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\$
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\$
  • 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 '17 at 22:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.