0
\$\begingroup\$

I am having a problem where my ray is unable to detect the player, even if I did layermask and went to draw ray and all other stuff.

Unity editor screenshot

Here is my code

RaycastHit2D raycastHit2D = Physics2D.Raycast(enemyEyes.transform.position, new Vector2(directionOfRay, 0), LayerMask.GetMask("Player"));

if(raycastHit2D.collider != null )
{
    if (raycastHit2D.collider.gameObject.tag=="Player")
    {
        Debug.Log("Hit Hit");
    }
}

  
Debug.DrawRay(enemyEyes.transform.position,new Vector3(directionOfRay , 0,0)  , Color.red);

Problem is HIT HIT is not displaying in console .

Raycasting Problem where my ray is unable to detect my player.

\$\endgroup\$
1
  • \$\begingroup\$ Remember to use .CompareTag() instead of .tag == for better performance. \$\endgroup\$
    – DMGregory
    Commented Oct 29, 2022 at 18:38

1 Answer 1

0
\$\begingroup\$

You've made the same mistake as in this previous question: Why is Raycast hitting a masked layer?

Paraphrasing/quoting my answer there:

The problem is that raycast functions have so darned many optional parameters, and LayerMask isn't picky about what type it's treated as.

From the docs:

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

layerMask is the fourth parameter. So if you provide only three parameters, Unity wants to interpret them as origin, direction, and distance.

It might seem like providing an input of type LayerMask should make your intent unambiguous, or at least generate a compile-time error, but LayerMask can implicitly convert to int, and int can implicitly convert to float.

So when you put a LayerMask in the third argument, the compiler tries to convert it to a float, succeeds, and so silently re-interprets your mask as a distance.

If your mask evaluates to a small number, like say 1, then you get a very short ray that misses your player. If it evaluates to a large number, you might get a ray long enough to hit the player, but along the way it hits something on a non-player layer (since the function thinks you provided no layer mask), and returns that instead.

You can fix this by providing a dummy distance value (say, infinity, if you don't have any more conservative upper bound) so your layer mask selections end up in the fourth argument where Unity expects it:

RaycastHit2D raycastHit2D = Physics2D.Raycast(enemyEyes.transform.position, new Vector2(directionOfRay, 0), float.positiveInfinity, LayerMask.GetMask("Player"));
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .