GetMouseButtonDown on specific object error. [Solved]

Hello,

I would like to have a script so that if I click a specific object, my player goes a specific direction. I’m making a mobile game so the objects are the arrows. If you click on, as example, the left arrow, you should go left.
I have this script with an error (only ‘‘left arrow’’ in this script’’ later more). Maybe there are other ways to do this easier. Please let me know.

    public float speed = 5.0f;
    public Terrain terrain;

    private Vector3 dir;


    void Start ()
    {
        transform.position = new Vector3(232f,22.5f,248f);
        dir = Vector3.left;
    }


    void FixedUpdate ()
    {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;

        if (Input.GetMouseButtonDown(0))
        {
            if (Physics.Raycast(ray, out hit, Mathf.Infinity))
            {
            if(hit.gameObject.name == "MoveLeft");                
            }
                {
                    dir = Vector3.forward;
                }
    }

        float amountToMove = speed * Time.deltaTime;

        transform.Translate(dir * amountToMove);

    }

Error:

See this answer:

Thanks for the reply, but I think that method doesn´t work for me. You can´t put RaycastHit.Vector3.gameObject I think.

Indeed, you can’t, but you can use hit.transform.position to calculate the direction vector to the hit object.

I wasn’t paying attention but actually the problem is this line. if(hit.gameObject.name == “MoveLeft”);
That is where the error is coming from, so I think it has nothing to do with transform

It does.
There’s no property on the RaycastHit to access the gameobject directly.

So, instead of

if(hit.gameObject.name == "MoveLeft");

use

// either this
if(hit.transform.gameObject.name == "MoveLeft")
// or this
if(hit.collider.gameObject.name == "MoveLeft")
1 Like

I said that it was working but it actually isn’t…

if I use

        if (Input.GetMouseButtonDown(0))
        {
            if (Physics.Raycast(ray, out hit, Mathf.Infinity))
                {
                if(hit.collider.gameObject.name == "MoveLeft");
                }
                    {
                        dir = Vector3.forward;
                    }
        }

( or: if(hit.transform.gameObject.name==“MoveLeft”); )

With this code, if I click anywhere on the screen, it wil go left. I thought that it was only going left if I clicked the LeftArrow object, but I found out that it is going left if you click anywhere the screen.

if I use:

        if (Input.GetMouseButtonDown(0))
        {
            if (Physics.Raycast(ray, out hit, Mathf.Infinity) && hit.transform.gameObject.name == "MoveLeft")
                {
                    dir = Vector3.forward;
                }

        }

with this code, none of them works. The player doesn’t go left if I click the LeftArrow object or anywhere the screen.

Also with the first code, I get this:
with the second code, I don’t.

Remove the semicolon first.
I just saw that I even copied it from your code and didn’t remove it in the adjusted versions that I recommended (fixed that now). Sorry for that, I only focused on the actual expression because that mistake is rather rare :smile:

You also have some parantheses placed at the wrong positions in some parts of the code.

my code is now looking like this:

    void FixedUpdate ()
    {
        float amountToMove = speed * Time.deltaTime;

        transform.Translate(dir * amountToMove);   

        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;

        if (Input.GetMouseButtonDown(0))
        {
            if (Physics.Raycast(ray, out hit, Mathf.Infinity))
            {
                if(hit.collider.gameObject.name == "MoveLeft")
   
                {   
                    dir = Vector3.forward;
                }
            }
        }
    }

still nothing happends if I click.

Try to check the input in Update rather than in FixedUpdate. There’s no guarantee that FixedUpdate will catch the input.
If you need the code to be run in FixedUpdate, you’ll have to have another boolean that will be set to true in Update when the Input occured and which will be set to false when the Input was consumed by the FixedUpdate.
Also, add Debug.Logs to ensure the conditions are true etc.

(UnfortunateIy I don’t have much time today, but you can always use debugging to track the issue down).

I am not actually sure if I have to use FixedUpdate, I changed it to update, no effect

I’ve tested this version, attached to the MainCamera in a new scene:

public class ClickTest : MonoBehaviour {

    void Update()
    {
       
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;

        if (Input.GetMouseButtonDown(0))
        {
            if (Physics.Raycast(ray, out hit, Mathf.Infinity))
            {
                if(hit.collider.gameObject.name == "Cube")

                { 
                    Debug.Log(hit.collider.gameObject.name + " clicked.");
                }
            }
        }

    }
}

It works correctly, debug.log fires only when I click on the cube and nothing else…

Long shot - could you check how the object is named during Play (pause it and check hierarchy and inspector). SInce you’re checking by gameObject.name, if you’re instantiating from a prefab it will have " (clone)" added.

If it’s not working still, could you attach a screenshot of the hierarchy and inspector of the MoveLeft object? The code seems to work fine, so maybe there’s something there - collider inactive, different layerMask, there has to be something.

2 Likes

It works thnx :smile:

I replaced the LeftArrow as a sprite and I forgot to add a collider to it… I know, it’s really stupid that I didn’t see that. Sorry for wasting your time :3