2

This is for 3D. My Raycast does not hit the Player object when I click over it. The raycast debug line is flying all over the screen, and it only draws once. Re clicking doesn't redraw. I purposely compensated and clicked on empty space to click and get the ray through my Player object. Even then, it doesn't count as a hit. The script is attached to an empty object which has no tag if that is relevant.

I have gone through similar answers down here and it looks to be correct. Please advice what I am doing wrong. Added couple of screenshots. Thank you.

This is error thrown:

NullReferenceException: Object reference not set to an instance of an object Player.isPlayerClicked () (at Assets/Player.cs:24) Player.Update () (at Assets/Player.cs:18)

public class Player : MonoBehaviour{

    private Ray ray;
    private RaycastHit hit;

    private void Start(){
        if (Camera.main != null) ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        else{
            Debug.Log("Camera is null"); // this doen't print meaning cam is valid
        }
    }

    private void Update (){
        isPlayerClicked();
    }

    private bool isPlayerClicked(){
        if (Input.GetMouseButton(0)){
            Debug.DrawRay(ray.origin, ray.direction * 100, Color.green, 100f); // only draws once. Re-clicking does nothing
            Debug.Log("mouse clicked " + hit.transform.name); // this is throwing error. hit seems to be invalid. 
            if (!Physics.Raycast(ray, out hit)) return false;
            if (!hit.transform.CompareTag("Player")) return false;
            Debug.Log ("Player clicked");
            return true;
        }
        return false;
    }
}

Player Camera

kar
  • 3,679
  • 8
  • 37
  • 53
  • You are trying to log something using `hit` before it has been created, hence the `NullReferenceException`. Move the `Debug.Log("mouse clicked " + hit.transform.name);` line after the `if (!Physics.Raycast(ray, out hit)) return false;` line. – Steve Oct 24 '18 at 00:05
  • 2
    Possible duplicate of [What is a NullReferenceException, and how do I fix it?](https://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – Steve Oct 24 '18 at 00:05

1 Answers1

1

The only time you should ever use the RaycastHit variable returned by the Physics.Raycast function is when Physics.Raycast returns true. If Physics.Raycast returns false, don't bother using or checking the RaycastHit value because it will always be null. Again, hit.transform would be null if Physics.Raycast returns false so you must use the result only when the raycast actually hits something.

Your function can be simplified into something below (notice how result is used in the if statement and only if it returns true):

private bool isPlayerClicked()
{
    if (Input.GetMouseButton(0))
    {
        ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        Debug.DrawRay(ray.origin, ray.direction * 100, Color.green, 100f); // only draws once. Re-clicking does nothing
        Debug.Log("mouse clicked"); 
        if (Physics.Raycast(ray, out hit) && hit.transform.CompareTag("Player"))
        {
            Debug.Log("Player clicked " + hit.transform.name);
            return true;
        }
    }
    return false;
}

Since you just want to detect clocks on a 3D GameObject, use the EventSystem. The OnPointerClick function with the IPointerClickHandler interface should be fine for this. See #6 from this post for how to set this up. This will work on both mobile and desktop platforms.

Programmer
  • 104,912
  • 16
  • 182
  • 271
  • Thanks, this does resolve the error issue and it detects the Player object. But this only happens once, and also provided I hit the Player first. If I clicked elsewhere, the raycast doesn't move to the new click spot when I re click. I will have a look at PointerClick. – kar Oct 24 '18 at 00:19
  • That's because you only got your ray variable once in the Start function. This means that the mouse position is only retrieved once. The latest one is not. You just have to move `ray = Camera.main.ScreenPointToRay(Input.mousePosition);` to the Update function too so that the mouse position ray is updated when you click the mouse. See my Update. Anyways, you should use the `OnPointerClick` stuff I mentioned about. – Programmer Oct 24 '18 at 00:24
  • Spot on. Thanks. – kar Oct 24 '18 at 00:39