Raycast won't hit object until object moves

I’m making a top-down 2D game. To select a character, I’m using a raycast to detect the “Player” tag. It works fine and I’m able to select the player just fine…BUT only after the characters transform changes once first. I’m not sure why it’s doing that, I’ve attached the raycast.

    private void PlayerInput()
    {
        if (Input.GetMouseButtonDown(0))
        {
            int rayLayerMask = LayerMask.GetMask("Player");

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

            if (hit)
            {
                if (hit.collider.gameObject.tag == "Player")
                {
                    Debug.Log("it's hitting player");

                    player = hit.collider.gameObject;
                    var hitplayerScript = player.GetComponent<playerScript>();

                    hitplayerScript.currentlySelected = true;
                    characterSelected = true;
                }

                if (hit.collider.gameObject.tag != "Player")
                {
                    characterSelected = false;
                    player = null;
                    Debug.Log("it's NOT hitting player");
                }
            }

            else
            {
                return;
            }
        }

@rapidcatch4464

Didn’t read the code properly - but are you expecting that raycast in 2D goes from screen towards depth axis?

As it doesn’t do that…

Raycast in 2D goes “sideways” along the flat plane of the screen.

If you need to do raycasting like in 3D, you can use one of the GetRayIntersection methods, or alternatively just test collision with some overlap test of Physics2D.

The raycast seems to be working fine, it hits the player when it’s the only thing on the screen. I actually just discovered that the raycast is hitting the tile behind the player (which is where he starts on the screen), however, I would have imagined the layer mask would ignore the tiles since they all have a tile layer.

If anyone sees a bug in my code, please let me know. Otherwise, I’ll just start focusing on why it’s choosing tiles…

@rapidcatch4464

“The raycast seems to be working fine”

“If anyone sees a bug in my code, please let me know.”

Yet your question is “Raycast won’t hit object until object moves”.

Yes - feel free to ignore help, but like I said raycast 2D works in 2D plane - You have:

Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero, rayLayerMask);

What do you expect happens with it?

I just ask, as you ignored to answer to this…

Your start for ray is mouse position converted to world point (which won’t be even on z-axis 0 if you use perspective camera).

Then your ray direction is Vector2.zero. What direction is that? Is it left, right or up or some other 2d vector defined direction?

If you use Vector2.right for example, ray will work just fine. It will start from mouse position, fire towards right, and when player is in front, it will hit.

But if you use Vector2.zero, your ray starts from your mouse position, then its direction is set as 0… and I don’t think there is overload that takes end point.

Then now that I look your code, your rayLayerMask also might not be correct as the parameters for raycast look like this:

public static RaycastHit2D Raycast(Vector2 origin, Vector2 direction, float distance = Mathf.Infinity, int layerMask = DefaultRaycastLayers, float minDepth = -Mathf.Infinity, float maxDepth = Mathf.Infinity);

First you should have origin, then direction, then distance and only then layer - so you placed the layermask on direction’s location? Unless there was overload that takes such parameters. So this might be the reason - your layer gets set to other than you think.

Try this:

private void Update()
{
    var sp = cam.ScreenToWorldPoint(Input.mousePosition);
    sp.z = 0;

    RaycastHit2D hit = Physics2D.Raycast(sp, Vector2.right, 1000f, playerMask);

    if (hit.collider != null)
        Debug.DrawLine(sp, hit.point, Color.red);
    else
        Debug.DrawRay(sp, Vector2.right, Color.green);
}
1 Like

You could bypass a raycast all together and simply use OnMouseDown()

Raycast works fine. Turns out I had the layer mask in the distance position of the ray. Works fine now.

1 Like