How to Do Mouse Picking

Here’s my code:

void CastRay()
        {
            Vector3 mousePos = Input.mousePosition;
            Vector3 enemyDepth = new Vector3(0, 0, -10);
            //RaycastHit hit = Physics.Raycast(, Vector3.back, 100, 0);
            RaycastHit hit;
            Physics.Raycast(Camera.main.ScreenToWorldPoint(mousePos), Vector3.back, out hit, 100);
            if (collider2d != null && collider2d.tag == "Enemy")
            {
                //Debug.Log("enemy_over");
                enemy_over = true;
            }
            else enemy_over = false;
        }

I had this working in 2D, but to get this to work right I have to do it in 3d. The idea is just to see if the mouse is over the enemy but it’s not working. The editor says hit.collider etc. is deprecated so I declared a public Collider2D object collider2d instead. But it doesn’t work.

If youre making a 3D game you use use 3D physics so use Collider instead of Collider2D, also your physics.raycast is not in an if statement? Is this even running? Sorry never seen it done like this before

1 Like

i’m making a 2d game but using a 3d raycast to see what’s under the mouse (i.e. is the enemy under the mouse?). you’re right that i just replaced hit witch collider without connecting collider to physics.raycast. not sure what i should do.

There’s a couple of ways to do it. The simple way is with OnMouseEnter.

Another way is just raycasting from where the mouse cursor is into the world.

    // Layer that enemy is on - remember to set this in inspector.
    public LayerMask _layerMask;

    // Distance to cast ray
    public float _raycastDistance = 10000f;

    void Update()
    {
        LogHoveredEnemyName();
    }

    void LogHoveredEnemyName()
    {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); // Create ray from camera into the world through the mouse cursor position.

        RaycastHit hitInfo; // Empty var to store info about the thing we hit

        if (Physics.Raycast(ray.origin, ray.direction, out hitInfo, _raycastDistance, _layerMask)) // If raycast hit a collider...
        {
            if (hitInfo.collider.tag == "Enemy") // Tag is enemy?
            {
                Debug.Log(hitInfo.collider.name); // Print name of enemy it hit.
            }
        }
        else
        {
            // Not hitting anything
        }
    }
1 Like

so if i wanted to use OnMouseEnter, i would put that in the enemy’s attached script and then use an event to signal the hero’s enemy_over script? i just learned about events (i guess i knew about them in java, but that was a long time ago).

you do not need to use a 3D raycast if doing this. you can use something like;

void CastRay()
{
      RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);

        if (hit.collider != null)
        {
            if (hit.collider.tag == "Enemy")
            {
                Debug.Log(hit.collider.gameObject.name);

            }

        }
}

then run CastRay in a FixedUpdate or Update Loop

1 Like

edit: could this be the reason -
“Property collider has been deprecated. Use GetComponent() instead”

what should i do instead then?

still not working:

void CastRay()
        {
            //Vector3 mousePos = Input.mousePosition;
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); // Create ray from camera into the world through the mouse cursor position.

            RaycastHit hitInfo; // Empty var to store info about the thing we hit

            if (Physics.Raycast(ray.origin, ray.direction, out hitInfo, 100)) // If raycast hit a collider...
            {
                if (hitInfo.collider.tag == "Enemy") // Tag is enemy?
                {
                    Debug.Log(hitInfo.collider.name); // Print name of enemy it hit.
                    enemy_over = true;
                }
            }
            else
            {
                // Not hitting anything
                enemy_over = false;
            }
        }

enemy_over is not being triggered even when i click on the enemy. odd.

Do the Enemys have a Collider2D on them?

yes, a polygon collider. your code seems to work, though i’m still having an issue with the range being off and i can’t figure out why.

Can you supply a screenshot of your scene ? Also, is the polygon collider centered for your enemy?

i fixed it by putting != null in with the nested if statement. the range is still off though, and i can’t figure out why. it’s always something.

thanks guys!

This is because if the hit.collider !=/not equal to null then it wont run the code, you can place it here instead;

    void CastRay()
    {
        RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);

        if (hit.collider != null)
        {
            if (hit.collider.tag == "Enemy")
            {
                Debug.Log(hit.collider.gameObject.name);
                enemy_over = true;
            }
        }
        else
        {
            enemy_over = false;
            Debug.Log("enemyovernot");
        }
    }
1 Like

My code was for 3D. I didn’t see you needed 2D.

Yes. You’d need to have a script on every enemy with OnMouseEnter inside it, then send a static event. The script that is interested in that data would subscribe to it in OnEnable and unsubscribe in OnDisable.

1 Like