kar
kar

Reputation: 3651

Raycast is not hitting what I click

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

Upvotes: 1

Views: 2139

Answers (1)

Programmer
Programmer

Reputation: 125445

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.

Upvotes: 1

Related Questions