- Home /
Why gameObject copy can not do the script commands?
Hi, I'm making 2D laser system and when the player collides with the ray it gets the damage.
So it's works fine, but in the first laser, every other copy is just showing the error about tag of the player.
Here is the error line:
if (hit.collider.tag == "Player" || spottedLeft == true)
Here is full script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class OneLaserScript : MonoBehaviour {
private LineRenderer lineRenderer;
public Transform laserHit;
public GameObject player;
public Transform leftCheck, rightCheck;
public Transform leftHit, rightHit;
public bool spottedLeft, spottedRight;
public LayerMask detectionLayers;
void Start () {
lineRenderer = GetComponent<LineRenderer> ();
}
void Update () {
RaycastHit2D hit = Physics2D.Raycast (transform.position, transform.up);
laserHit.position = hit.point;
lineRenderer.SetPosition (0, transform.position);
lineRenderer.SetPosition (1, laserHit.position);
Debug.DrawLine (leftCheck.position, leftHit.position, Color.green);
spottedLeft = Physics2D.Linecast (leftCheck.position, leftHit.position, detectionLayers);
Debug.DrawLine (rightCheck.position, rightHit.position, Color.green);
spottedRight = Physics2D.Linecast (rightCheck.position, rightHit.position, detectionLayers);
if (hit.collider.tag == "Player" || spottedLeft == true) {
player.GetComponent<PlayerControllerScript> ().knockFromRight = true;
player.GetComponent<PlayerControllerScript> ().knockbackCount += 1;
player.GetComponent<PlayerControllerScript> ().timer = 5f;
} else {
player.GetComponent<PlayerControllerScript> ().knockFromRight = false;
player.GetComponent<PlayerControllerScript> ().knockbackCount = 0;
}
if (hit.collider.tag == "Player" || spottedRight == true) {
player.GetComponent<PlayerControllerScript> ().knockbackCount += 1;
player.GetComponent<PlayerControllerScript> ().timer = 5f;
} else {
player.GetComponent<PlayerControllerScript> ().knockbackCount = 0;
}
}
}
What I have done wrong? Please try to help.
Answer by Harinezumi · Mar 22, 2018 at 08:04 AM
UPDATE: indeed the error is that the raycast didn't hit anything, so hit.collider
is null, so trying to access hit.collider.tag
throws a NullReferenceException. Always check the result of raycasts, either by using if (hit.collider != null)
or using the version that returns a bool
and puts the result in an out
parameter.
Original post: What is the exact error it says?
One possible issue is that you don't check if the raycast hit something, you just use hit.point
. However, if nothing was hit, hit.collider
will be null
(see documentation here) and you will get an error when you try to access the tag
member of it.
Did this solve the problem?
Indeed you need to check after the Raycast:
if(hit.collider != null) { // Hit detected }
I need to change hit.collider.tag == "Player" || spottedLeft == true
to this?
hit.collider != null || spottedLeft == true
or it is another line?
The error says "NullReferenceException: Object reference not set to an instance of an object" On the line which is highlighted on the picture.
So what should I exactly need to change or add? Something about hit.collider or function where it is said if it is null?
No, just as fafase said, right after RaycastHit2D hit = ...
add if (hit.collider != null)
, so that you only do anything if you actually hit an object.
The error you are receiving means that something is null, that is, it doesn't exist. As hit
cannot be null, nor spottedLeft
, and a comparison doesn't give you a NullReferenceException, it must be collider
that is null. If you read the reference for RaycastHit (the same as for RaycastHit2D), it says that if you don't hit anything, collider
is null.
Please check this tutorial for more info on how raycasting works and how to use it.
So I watched the tutorial and get it that I need to have if(collider != null) must be above everything on update right?
So I made a script like this, and the errors are not showing anymore, is that correct code? Because it is still not changing the values of "knockbackCount" like it did on the first laser which is not a copy where it is not working, this is very strange for my $$anonymous$$d
void Update () {
RaycastHit2D hit = Physics2D.Raycast (transform.position, transform.up);
if (hit.collider != null) {
laserHit.position = hit.point;
lineRenderer.SetPosition (0, transform.position);
lineRenderer.SetPosition (1, laserHit.position);
Debug.DrawLine (leftCheck.position, leftHit.position, Color.green);
spottedLeft = Physics2D.Linecast (leftCheck.position, leftHit.position, detectionLayers);
Debug.DrawLine (rightCheck.position, rightHit.position, Color.green);
spottedRight = Physics2D.Linecast (rightCheck.position, rightHit.position, detectionLayers);
if (hit.collider.tag == "Player" || spottedLeft == true) {
player.GetComponent<PlayerControllerScript> ().knockFromRight = true;
player.GetComponent<PlayerControllerScript> ().knockbackCount += 1;
player.GetComponent<PlayerControllerScript> ().timer = 5f;
} else {
player.GetComponent<PlayerControllerScript> ().knockFromRight = false;
player.GetComponent<PlayerControllerScript> ().knockbackCount = 0;
}
if (hit.collider.tag == "Player" || spottedRight == true) {
player.GetComponent<PlayerControllerScript> ().knockbackCount += 1;
player.GetComponent<PlayerControllerScript> ().timer = 5f;
} else {
player.GetComponent<PlayerControllerScript> ().knockbackCount = 0;
}
}
}
timer and knobackFromRight are working fine, but knockBackCount isnt