Collider2d.bounds.Intersects not detecting intersection - c#

I'm making a top-down game where you drive a car and shoot targets at the same time. I have a script that makes a sprite of a crosshair follows the mouse cursor and I want to have it set up so that when the player presses the mouse button (the mouse button isn't in the code now) and the crosshair sprite is overlapping an enemy sprite, the enemy dies. I was following this documentation on Bounds.Intersects. Here's my code:
public class shootingScript : MonoBehaviour
{
public GameObject target, enemy;
CircleCollider2D targetCollider;
CapsuleCollider2D enemyCollider;
// Start is called before the first frame update
void Start()
{
//Check that the first GameObject exists in the Inspector and fetch the Collider
if (target != null)
{
print("targ not null");
targetCollider = target.GetComponent<CircleCollider2D>();
}
//Check that the second GameObject exists in the Inspector and fetch the Collider
if (enemy != null)
{
print("enemy not null");
enemyCollider = enemy.GetComponent<CapsuleCollider2D>();
}
}
// Update is called once per frame
void Update()
{
if (targetCollider.bounds.Intersects(enemyCollider.bounds))
{
print("hit");
Destroy(enemy);
}
}
}
In-game "targ not null" and "enemy not null" prints but when I move my cursor and the crosshair goes over the enemy "hit" is not printed and the enemy is not destroyed. I have a CircleCollider2D on the crosshair and a CapsuleCollider2D on the enemy. The script is on an empty game object. I also tried sprite.bounds but that resulted in the enemy getting killed as soon as I run the game.
EDIT:
Here's the code that keeps the crosshair sprite on the cursor. I copied it from somewhere. I set moveSpeed to 99999 since I want the crosshair sprite to be exactly where the mouse is.
public class mouseReticle : MonoBehaviour
{
private Vector3 mousePosition;
public float moveSpeed = 0.1f;
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
mousePosition = Input.mousePosition;
mousePosition = Camera.main.ScreenToWorldPoint(mousePosition);
transform.position = Vector2.Lerp(transform.position, mousePosition, moveSpeed);
}
}

The target sprite and enemy sprite were at different depths (z).

Related

How to reference camera in prefab script in Unity 2D?

I have created a player prefab (called Tim in my project) and am trying to make all the references to gameObjects and transforms directly from the one of the players scripts which is actually attached to a gun object which is a child of the player prefab.
The issue is I cant manage to reference the camera in the script although I've looked and tried many different methods, none of them seemed to work. Unity prints this error in the console though : "NullReferenceException: Object reference not set to an instance of an object". And here is the script :
public class Gun_Control : MonoBehaviour
{
// References for GameObjects
[SerializeField] private Rigidbody2D rb;
private GameObject Player;
[SerializeField] private Transform PlayerTransform;
private GameObject Gun;
[SerializeField] private Transform GunTransform;
private Camera MainCamera;
private GameObject firePoint;
[SerializeField] private Transform firePointTransform;
[SerializeField] private GameObject bulletPrefab;
// Variables for Shooting
private Vector2 mousePos;
private float bulletForce = 20f;
// Start is called at the beginning
void Start()
{
Debug.Log("Starting");
Player = GameObject.FindWithTag("Player");
PlayerTransform = Player.transform;
Gun = GameObject.FindWithTag("PlayerGun");
GunTransform = Gun.transform;
MainCamera = GameObject.FindWithTag("Camera").GetComponent<Camera>();
firePoint = GameObject.FindWithTag("PlayerFirePoint");
firePointTransform = firePoint.transform;
}
// Update is called once per frame
void Update()
{
// Get mouse position
mousePos = MainCamera.ScreenToWorldPoint(Input.mousePosition);
// Run shoot function on left click
if(Input.GetButtonDown("Fire1"))
{
Shoot();
}
}
// Update is called on every physics frame
void FixedUpdate()
{
// Set gun position to player position
GunTransform.position = PlayerTransform.position;
// Set gun rotation to mouse position
Vector2 lookDir = mousePos - rb.position;
float angle = Mathf.Atan2(lookDir.y ,lookDir.x) * Mathf.Rad2Deg - 180f;
rb.rotation = angle;
}
void Shoot()
{
// Instantiate a bullet at the firepoint and give it force
GameObject bullet = Instantiate(bulletPrefab, firePointTransform.position, firePointTransform.rotation);
Rigidbody2D rb = bullet.GetComponent<Rigidbody2D>();
rb.AddForce(firePointTransform.up * bulletForce, ForceMode2D.Impulse);
}
}
Right now I have a variable, MainCamera, and when the script starts I look for a camera which has "Camera" as its tag which is set correctly.
I can add on if anyone needs more details and thank you to everyone for taking the time to help.
Edit 1 :
I tried what thunderkill suggested but it doesnt seem to work.
Here is a picture of the new code.
And when I try to use Debug.Log(Camera.main); it prints null.
here is a good example to access your main camera :
Camera m_MainCamera;
void Start()
{
//This gets the Main Camera from the Scene
if(Camera.main != null){
m_MainCamera = Camera.main;
//This enables Main Camera
m_MainCamera.enabled = true;
}
}
Camera c = Camera.main;//get the camera Tagged "MainCamera"
So you have to Check if your Camera tag is "MainCamera".
or you try :
GameObject.FindObjectOfType<Camera>();
(I don't recommend the second solution)
So I ended up finding the answer.I just deleted the camera in my scene and created a new one and then ended up using : MainCamera = GameObject.FindWithTag("Camera").GetComponent<Camera>(); which worked this time. The issue could have also been caused by errors present before in my code.

Unity 2D character keeps playing walking animation when colliding and raycasts don't work as expected

I have been working on a 2d top down rpg game and I have added walking animations etc, I want to stop the player from doing a walking animation when they hit a wall and currently I have a box collider with a ray cast, the ray cast originally hit the player box collider when walking down but after using a layermask this has stopped, however while walking left and right work perfectly two issues occur that I cannot seem to fix. First, when walking up or down into a tilemap that is on the collision layer (this tilemap has tilemap collider which will stop the player from walking through them) the animation still plays, and second the player will only collide once instead of repeatedly when hitting the tilemap when two tiles are placed back to back, here is my code for collision, the tiles that are for collision are on layer 6.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerScript : MonoBehaviour
{
public float moveSpeed;
private Animator ani;
private bool isMoving;
private Vector2 lastMove;
private Rigidbody2D body;
private Vector2 movement;
private LayerMask wallLayer = 1 << 6;
// Start is called before the first frame update
void Start()
{
body = GetComponent<Rigidbody2D>();
ani = GetComponent<Animator>();
movement = Vector2.zero;
isMoving = false;
}
// Update is called once per frame
void Update() {
isMoving = false;
movement = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
RaycastHit2D ray = Physics2D.Raycast(body.position, movement, 0.6f, wallLayer);
if((movement.x != 0f || movement.y != 0f) && !(ray && ray.collider.tag == "wall")) {
isMoving = true;
lastMove = movement;
}
ani.SetFloat("MoveX", movement.x);
ani.SetFloat("MoveY", movement.y);
ani.SetFloat("LastX", lastMove.x);
ani.SetFloat("LastY", lastMove.y);
ani.SetBool("IsMoving", isMoving);
}
void FixedUpdate() {
body.MovePosition(body.position + movement * moveSpeed * Time.deltaTime);
}
}
The code looks fine. Most likely, the issue is with your configuration of the AnimatorController.
Do you have transitions in place for (for example) coming from the walk animation back to idle?

Instantiating a prefab at the mouse position for my sandbox game

I can't manage to instantiate a prefab at my mouse position.
I've tried to instantiate the prefab at the current mouse position, but on click, the block shows in the hierarchy and not the scene. It also creates 4-5 prefabs.
using UnityEngine;
public class Building : MonoBehaviour
{
public GameObject block;
void Update()
{
if (Input.GetMouseButton(0))
{
Instantiate(block, new Vector3(Input.mousePosition.x, Input.mousePosition.y, 0f), Quaternion.identity);
}
}
}
I want to create 1 prefab of the block, and I want it to show up in the scene view.
Input.mousePosition is the coordinates of the mouse on the screen. Use Camera.ScreenToViewportPoint to get the world position.
The block will not show in the scene, because its position is likely something like (500, 300, 0), which is very far. Select the block in the Hierarchy and press "F" to see it.
Input.GetMouseButton() keeps firing as long as the mouse is held. Change this to Imput.GetMouseButtonDown()
using UnityEngine;
public class Building : MonoBehaviour {
public GameObject block;
void Update()
{
if (Input.GetMouseButtonDown(0))
{
Vector3 pos = Camera.main.ScreenToViewportPoint(Input.mousePosition);
Instantiate(block, pos, Quaternion.identity);
}
}
}
You need to convert from screen space to world space.
One way to do this is to use Camera.ScreenToWorldPoint:
private Camera mainCam;
void Start()
{
mainCam = Camera.main;
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
Vector3 blockPos = mainCam.ScreenToWorldPoint(Input.mousePosition);
Instantiate(block, blockPos, 0f), Quaternion.identity);
}
}
If you want to spawn further away from the camera, look into Camera.ScreenPointToRay.

Despite Force Applied, No Movement

This code is for an elevator-type platform, where once the player stands on it, it 'takes' the player up by adding force onto it.
The thing is, while the force is created, the rigidbody (the player) does not move when the elevator moves. The code was written in C#, using Unity 5. In the code, the player is assigned the public 'rb', and contains a rigidbody.
The animation is a simple animation clip that moves the elevator up. Any ideas? Thank you for your time and answers in advance.
The elevator is Kinematic, the Player is not.
using UnityEngine;
using System.Collections;
/*This script activates when the player steps on the elevator, as it takes them up a floor.*/
public class ElevatorMovementScript : MonoBehaviour
{
private bool elevatorUp = false;
public Animation anim;
public int elevatorDelay = 5;
public int force = 800;
public Rigidbody rb;
// Use this for initialization
void Start ()
{
anim = GetComponent<Animation>();
}
// Update is called once per frame
void Update ()
{
}
/*Checks if the player has stepped onto the elevator. If the player has, it waits five seconds, and then pushes the player up.*/
void OnTriggerStay(Collider other)
{
if (other.gameObject.tag == "Player" && !elevatorUp)
{
Invoke("AnimationPlay",elevatorDelay);
elevatorUp = true;
}
}
/*Plays the animation of the player going up. Used for the 'Invoke' method.*/
void AnimationPlay()
{
rb.AddForce(transform.up * force);
Debug.Log (transform.up * force);
anim.Play ("Up");
}
}
It looks like this script is on your elevator's game object, in which case this line:
rb.AddForce(transform.up * force);
Will try to apply a force to the elevator, not the player. You've got to keep track of the player's rigidbody or somehow get it on demand in AnimationPlay.
You said that
the player is assigned the public 'rb'
But rb = GetComponent<Rigidbody>(); will ignore this and use the rigidbody attached to the gameobject that ElevatorMovementScript is attached to.

Constant animation hapenning when moving

I have the following code, but i'm having some problems. Every time update is called, the character move to the point i give him to. But i just give him a point when i click with the mouse on the ground, the problem starts when i try to make it animate the character.
If i pass the value of the animation on the clickToMove() method it'll always play that animation even if we aren't moving. And if i place clickToMove inside the "if clicked" the character will teleport and not move towards. I can't think in a way to do the animation properly, only when the object is moving, and goes back to idle when it's stopped, even if the clickToMove() is playing all the time.
using UnityEngine;
using System.Collections;
public class ClickScript : MonoBehaviour
{
public float moveSpeed;
public float minDistance;
Vector3 mouseClick; //Creates a variable to save the constant of the hit from raycast
private Animator anim;
private Rigidbody rigidB;
// Use this for initialization
void Start()
{
anim = GetComponent<Animator>();
rigidB = GetComponent<Rigidbody>();
}
// Update is called once per frame
void FixedUpdate()
{
if (Input.GetMouseButtonDown(1))//If clicked
{
clickPosition(); //Gets the click position
}
if (Vector3.Distance(transform.position, mouseClick) > minDistance) //If the click distance is bigger than the minimal
{
//It is allways moving, but since there's no click position it doesn't move when not clicked
clickToMove();
}
}
void clickPosition()//This function throw a raycast on the ground and save the position on mouseClick to make the char move to there
{
RaycastHit clickHit; //creates a constant with the infos from the raycast
Ray mouseClickPosition = Camera.main.ScreenPointToRay(Input.mousePosition); //creates a constant to save the mouse position
if (Physics.Raycast(mouseClickPosition, out clickHit, 100.00f))//throw a raycast returning the mouse position and more infos
{
Debug.Log("Click at " + clickHit.point); //Show where were clicked
mouseClick = clickHit.point;//mouseClick receive the position of the click
}
}
void clickToMove() //this function make the player look at the click and move to mouseClick
{
mouseClick.y = transform.position.y; //get rid of the y to fix rotation bugs
transform.LookAt(mouseClick);//look at the poit you clicked
transform.position = Vector3.MoveTowards(transform.position, mouseClick, moveSpeed * Time.deltaTime);//move to the clickpoint
}
}
How about this way?
bool _isAnimating = false;
// Update is called once per frame
void FixedUpdate()
{
if (Input.GetMouseButtonDown(1))//If clicked
{
clickPosition(); //Gets the click position
//start animation here!!!
//animator.SetBool("bWalk", false);
//and set animation state to true
_isAnimating = true;
}
if (Vector3.Distance(transform.position, mouseClick) > minDistance)
{
clickToMove();
}
else if(_isAnimating)
{
//turn off the animation here!!!
//animator.SetBool("bStop", false);
//and set to false
_isAnimating = false;
}
}

Categories

Resources