3
\$\begingroup\$

I have been troubleshooting a problem I have encountered with some of my raycasts, and have arrived at a perplexing brick wall. I fire a Physics2D.Raycast in order to determine if my character is grounded; however, it would not always return a reference to the ground object in situations where it should.


Breaking down the method call, I have fired a raycast without a layer mask. This returns the correct reference; I then send the layer mask associated with the reference transform to the debug log.

public void FireTestRay()
{
    RaycastHit2D hit = Physics2D.Raycast(startPosition, Vector2.down, 0.1f);
    Debug.Log(hit.transform.gameObject.layer);
}

8

I want to be checking against my platform objects, which I have proven to contain the layer index of 8. However, when I use layer masks, the raycast fails.

public void FireTestRay()
{
    RaycastHit2D hit = Physics2D.Raycast(startPosition, Vector2.down, 0.1f, 8);
    Debug.Log(hit.transform.name);
}

NullReferenceException: Object reference not set to an instance of an object

I am not moving my game object; in fact, the only thing that changes at all is the above mentioned lines of code.


I seem to be able to successfully hit the intended object if I do not use a layer mask, and in turn, can successfully retrieve the value of the intended objects layer mask. As soon as I filter my raycast to only hit that layer mask, it fails.

Why does Physics2D.Raycast automatically fail if applying a layer mask?

\$\endgroup\$

1 Answer 1

11
\$\begingroup\$

A Layer Mask is an integer, so that's right.

But if you want to test against Layer 8, you don't pass in 8 as the value. What if you want to check against 8 and 7? Well, 15 is the wrong answer there (as are both 8 and 7).

The value you need to pass to check against layer 8 is 1<<8

This is why there are exactly 32 layers numbered from 0 to 31, as the layer number corresponds to a single bit in an integer-sized bitmask. So why's it called a layer mask? Why a bitmask for a given physics layer.

\$\endgroup\$
1
  • 3
    \$\begingroup\$ While this is an excellent answer that explains the behavior, bit shifting may be a little inconvenient / hard to read, and newbies would probably write a convenience function duplicating the existing functionality - so It may be appropriate to mention LayerMask.GetMask(String...) here. \$\endgroup\$
    – Knetic
    May 10, 2017 at 22:51

You must log in to answer this question.

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