As you can see in the screenshoot I can't see prefabs in the game tab but only in the editor. I have made a simple function for shooting(not finished yet), it works fine, it spawns the prefabs but i can't see them in the game tab, I have already tried changing the Sorting Layer, move the camera, change Z position but nothing appen.
This is my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerAttack : MonoBehaviour
{
[SerializeField]
float delayBetweenShots = 0.4f;
float timePassedSinceLast = 0f;
// Start is called before the first frame update
void Start()
{
timePassedSinceLast = delayBetweenShots;
}
// Update is called once per frame
void Update()
{
Aiming();
Shooting();
}
void Aiming()
{
var objectPos = Camera.main.WorldToScreenPoint(transform.position);
var dir = Input.mousePosition - objectPos;
transform.rotation = Quaternion.Euler(new Vector3(0,0,Mathf.Atan2(-dir.x, dir.y) * Mathf.Rad2Deg));
}
void Shooting()
{
if(Input.GetMouseButton(0) && timePassedSinceLast >= delayBetweenShots)
{
GameObject bullet = (GameObject)Instantiate(Resources.Load("bullet"), transform.position, transform.rotation);
timePassedSinceLast = 0f;
}
else
{
timePassedSinceLast += Time.deltaTime;
}
}
}
The prefabs get instantiated correctly. As others suggested as well, the best way to find "lost" objects in your game is to shoot some stuff, pause the game, go into scene view, turn on 3D mode and double click one of the prefabs in the hierarchy. The camera will take you straight to your object.
Related
I am a beginner at unity and try to make a game by watching some tutorial. After finishing my game I wanted to add some more functionality which is dropping objects continuously from up to the plane. But after it dropped on the plane it rising up to a certain level and again dropped on the plane. I don't understand what to do.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class droper : MonoBehaviour
{
// Start is called before the first frame update
MeshRenderer renderer;
Rigidbody rigidbody;
Vector3 pos1;
Vector3 pos2;
Vector3 pos3;
[SerializeField]float timeToWait =2f;
[SerializeField]float speed =0.005f;
void Start()
{
renderer = GetComponent<MeshRenderer>();
rigidbody = GetComponent<Rigidbody>();
renderer.enabled= false;
rigidbody.useGravity= false;
pos1 = transform.position;
}
// Update is called once per frame
void Update()
{
if (Time.time > timeToWait)
{
renderer.enabled= true;
rigidbody.useGravity= true;
pos2 = transform.position;
Debug.Log(pos1);
pos3=new Vector3(transform.position.x,pos1.y,transform.position.z);
if (pos2.y < pos1.y)
{
transform.position=Vector3.MoveTowards(pos2,pos3,speed);
}
}
}
}
enter image description here
You can do this in 2 ways
You can use rigidbody.velocity along the axis you want to move, you may want to disable gravity depending on what you are trying to achieve
Transform.translate is also an option but it has buggy physics so you shouldn't really use it
this should be a very simple answer. I'm following a Unity with C# tutorial for making a simple Space Invaders game, and at one point it is shown that when our enemyHolder object has no child objects left (when all enemies are destroyed) the attached text under the winText function should be displayed.
So we have
if (enemyHolder.childCount == 0)
{
winText.enabled = true;
}
When I run the code the text isn't displayed after the enemies are destroyed and no child object is left. It's like the code stops getting read at that point, although the character is still movable and you can generate new shots.
If I create two "Enemy" child objects and tell it to display the winText rather when the childCount reaches 1, it does work.
So why is it not working when the function calls for == 0?
EDIT: Complete class code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class EnemyController : MonoBehaviour
{
private Transform enemyHolder;
public float speed;
public GameObject shot;
public Text winText;
public float fireRate = 0.997f;
// Start is called before the first frame update
void Start()
{
winText.enabled = false;
InvokeRepeating("MoveEnemy", 0.1f, 0.3f);
enemyHolder = GetComponent<Transform>();
}
void MoveEnemy()
{
enemyHolder.position += Vector3.right * speed;
foreach (Transform enemy in enemyHolder)
{
if (enemy.position.x < -10.5 || enemy.position.x > 10.5)
{
speed = -speed;
enemyHolder.position += Vector3.down * 0.5f;
return;
}
if (enemy.position.y <= -4)
{
GameOver.isPlayerDead = true;
Time.timeScale = 0;
}
if (enemyHolder.childCount == 1)
{
CancelInvoke();
InvokeRepeating("MoveEnemy", 0.1f, 0.25f);
}
if (enemyHolder.childCount == 0)
{
winText.enabled = true;
}
}
}
}
Your code is inside the void MoveEnemy() function.
I'm assuming your script is attached to in-game enemies. Your code doesn't run because the MoveEnemy function no longer runs if there are no enemies.
So, you need to handle enemy movement and scene handling in different scripts.
The code that checks the enemy holder's number of children should be placed inside a void Update() function. This Update() function should be placed on an object that never gets deleted. Its advantage is that it runs every frame.
As a convention, devs generally use separate empty objects or even the camera to attach scripts which contain Update functions that handle the scene. Good luck!
Read more on Update
I have a problem that main camera position doesn't change after CharacterController.SimpleMove() called. The task is to create scene where camera moves.
I have Main Camera game object with Character Controller and Script attached.
The issue is that nothing in vrCamera position changed after SimpleMove() called.
My question is what is wrong in this code. I suggest something wrong with binding between MainCamera object and CharacterController component, but I have spend a lot of time investigating and nothing working found.
using UnityEngine;
[RequireComponent(typeof(CharacterController))]
public class VRLookWalk : MonoBehaviour {
public Transform vrCamera;
public float toggleAngle = 30.0f;
public float speed = 3.0f;
public bool moveForwad;
private CharacterController cc;
// Use this for initialization
void Start () {
cc = vrCamera.GetComponent<CharacterController>();
}
// Update is called once per frame
void Update () {
if (vrCamera.eulerAngles.x >= toggleAngle && vrCamera.eulerAngles.x < 90.0f)
{
Vector3 forward = vrCamera.TransformDirection(Vector3.forward);
cc.SimpleMove(forward * speed);
}
}
}
You can't move the VR Camera, it's the SDK that determine the mainCamera position.
In order to move your camera you can just make a new GameObject as a parent of your mainCamera then move the parent GameObject
Try this. Your TransformDirection probably returns wrong vector.
Vector3 forward = vrCamera.transform.forward;
cc.SimpleMove(forward * speed);
I'm writing a script in C# in Unity that essentially functions as a switch to turn gravity on or off for a 2D Rigidbody. When the game starts, gravity should be 0 for the Rigidbody. Then when the user taps the space bar, gravity is supposed to increase to 3 (which is does). Then, however, when the player collides with a gameObject labeled 'InvisGoal', the player should teleport to another location and then gravity should be 0 again. However, the player always falls after coming in contact with InvisGoal and teleporting and I can't figure out why. This is my first project in C# so sorry for any obvious errors.. The script is here:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BallLaunch : MonoBehaviour {
private Rigidbody2D myRigidBody;
public GameObject Ball;
// Use this for initialization
void Start ()
{
myRigidBody = GetComponent<Rigidbody2D> ();
GetComponent<Rigidbody2D>().gravityScale = 0f;
}
// Update is called once per frame
void Update ()
{
if (Input.GetButtonDown ("Jump"))
{
GetComponent<Rigidbody2D> ().gravityScale = 3f;
}
}
void OnTriggerEnter2D(Collider2D other){
if (other.tag == "InvisGoal")
{
Ball.gameObject.GetComponent<Rigidbody2D>().gravityScale = 0f;
transform.position = new Vector3 (0.61f, 1.18f, 0f);
return;
}
}
}
Ball.gameObject.GetComponent<Rigidbody2D>().gravityScale = 0f;
This is likely what is causing the problem.
It sounds like the RigidBody2D you are referencing to in this line is not the same as the one you retrieved beforehand with GetComponent().
GetComponent returns the component of the GameObject you call it from. Therefore in the code I mentioned above,
Ball.gameObject.GetComponent<RigidBody2D>()
and
GetComponent<RigidBody2D>()
would give you an two different RigidBody2D component if the field Ball does not refer to the same GameObject your BallLaunch script is attached to.
[
Supposing BallLaunch script is attached to the Ball you want to set the gravity of (As picture above)
Simply change:
Ball.gameObject.GetComponent<Rigidbody2D>().gravityScale = 0f;
To
GetComponent<Rigidbody2D>().gravityScale = 0f;
Also, since you already referenced your RigidBody2D in your Start method to the field myRigidBody, you can replace all subsequent GetComponent with myRigidBody.
GetComponent<Rigidbody2D>().gravityScale = 0f;
To
myRigidBody.gravityScale = 0f;
I'm currently trying to make a Unity3d (Or 2D in this case) Platformer tech demo.
While working on the demo I ran into a bit of a snag because I want my Player object to be able to go up slopes, but if I apply gravity while the Player object is on the ground it will not be able to go up slopes, even if it can go down them. My solution was to turn off gravity while the PLayer object was touching the ground, and turn it back on when it wasn't. I did this by using the functions void OnCollisionEnter2D(Collision2D collision) to turn the gravity off, and void OnCollisionExit2D(Collision2D collision) to turn it back on.
This did not work, so I played with it a bit and thought of the idea to give the ground, and Player object "Trigger Boxes" which are unseen child Cube objects that have a Collider marked as a Trigger. So now I am using the function void OnTriggerEnter2D(Collider2D collision) to turn the gravity off, and void OnTriggerExit2D(Collider2D collision) to turn it back on. But this also does not work. Below is my code, first is the Player object's main script, and after that is the Player object's "TriggerBox" and after that will be images to show how my objects are setup in Unity.
The result: The Player class currently does not collide with the ground, and falls through it to infinity.
What I want: The player to collide with the ground, and the player's TriggerBox to collide with the ground's "TriggerBox" and turn off the Player's gravity.
Notes: I've tried giving the players, and ground RigidBody2Ds. The player collides with the ground and gets jittery, and does not trigger the gravity turn-off, and the ground falls on contact with the player when the ground has the RigidBody2D. It is unknown what triggers, as the ground falls right under the player.
using UnityEngine;
using System.Collections;
public class PlayerControls : MonoBehaviour {
CharacterController controller;
private float speed = 0.004f;
private float fallSpeed = 0.01f;
private Vector3 tempPos;
bool onGround = false;
public void setOnGround(bool b){ onGround = b; }
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
tempPos = Vector3.zero;
if(Input.GetKey(KeyCode.W)) tempPos.y -= speed;
if(Input.GetKey(KeyCode.S)) tempPos.y += speed;
if(Input.GetKey(KeyCode.A)) tempPos.x -= speed;
if(Input.GetKey(KeyCode.D)) tempPos.x += speed;
RaycastHit2D[] hits = Physics2D.RaycastAll(new Vector2(transform.position.x,transform.position.y), new Vector2(0, -1), 0.2f);
float fallDist = -fallSpeed;
if(hits.Length > 1){
Vector3 temp3Norm = new Vector3(hits[1].normal.x, hits[1].normal.y, 0);
Vector3 temp3Pos = new Vector3(tempPos.x, tempPos.y, 0);
temp3Pos = Quaternion.FromToRotation(transform.up, temp3Norm) * temp3Pos;
tempPos = new Vector2(temp3Pos.x, temp3Pos.y);
}
if(!onGround) tempPos.y = fallDist;
transform.Translate(tempPos);
}
}
Next the TriggerBox:
using UnityEngine;
using System.Collections;
public class PlayerTriggerBox : MonoBehaviour {
public PlayerControls playerControls;
// Use this for initialization
void Start () {
//playerControls = gameOGetComponent<PlayerControls>();
if(playerControls == null) Debug.Log("playerControls IS NULL IN PlayerTriggerBox!");
}
// Update is called once per frame
void Update () {
}
void OnTriggerEnter2D(Collider2D other) {
playerControls.setOnGround(true);
}
void OnTriggerExit2D(Collision2D collision){
playerControls.setOnGround(false);
}
}
-As for the images for my setup-
The player's setup:
The player's TriggerBox setup:
The ground's setup:
The ground's TriggerBox setup:
Thank you for your time reading this, and hopefully for your help.