Unity : LayerMask
What is the LayerMask?
In this article we try to answer to this question.
Here’s the reference
https://docs.unity3d.com/ScriptReference/LayerMask.html
First of all, a LayerMask is a specifies Layers to use in a Physics.Raycast.
And in the example we can see a specific case like this
As always, the best way to understand things is implemented in our code.
So try to use directly in a simple scene.
Let’s try to think of this example: we have a shooter and we have to shoot the enemy but also save people and we don’t want to implement friendly fire.
We have this scene, two cubes are Enemies, one is Hostage.
What we want is shoot to enemy but not the hostage.
Let’s do it!
We simply select the Enemy, and we need to create a LayerMask “Enemy” and one for hostage, and assign to them
Little explanation : LayerMask is a sort of flag, so it returns 1 or 0 (or true or false if you prefer)
and it is a 32 int.
At bitwise level, what this means?
Below we have a representation of 32 int in bit, and every number represent one Layer ok?
So in total we have 32 Layer
0000 0000 0000 0000
We have in our example the EnemyLayer on the sixth Layer
and what happen “under the hood” is simply this
0000 0000 0010 0000
The sixth Layer is now change to 0 to 1, so from false to true, and this means that the Raycast can hit ONLY what there is on this Layer.
In code, we can do this type of check in this way
I have a Player script
First part is the same.
What we change is inside an If Statement :
and after this
We pass the origin and the out hit as always, but after we can pass directly the LayerMask.
It can be do it in two ways, in this first example I use the bitwise syntax
1 << 6
that it means SHIFT TO THE LEFT 1 to the sixth position.
And change the color
Important Note :
always WATCH OUT at what parameter the method ask to us.
This seems incredibly stupid, but is one of the most common error, like forgot to attach the script to the objects or to pass the objects in the editor.
I’m telling you this because normally Unity gives us an almost instant error and we can fix it.
But for example in this case we can literally go crazy finding the bug, because we don’t have any errors and things don’t work out.
At the moment, in fact, we have no errors and everything seems ok.
If we test it
We hit everything and we don’t have any errors.
But this is not what we expected.
Where is the problem?
Well, the problem is inside the Raycast, exactly here
The third parameter we pass is not for LayerMask, but for a DISTANCE.
And in this specific case, distance and LayerMask ARE BOTH INT, so technically we pass an int where the method asks us for an int.
That’s not what we want, but it’s not a mistake.
So again, I know it’s incredibly stupid, and maybe it never happens to you, but it’s a more common mistake than we think.
Going back to our test, the distance parameter is MathF.Infinity, and after we can write 1 << 6
Play it
And now it works.
The alternative method if you don’t like the bitwise operation, is simply create a [SerializeField], and pass directly the LayerMask in the Editor
Same result.
Personally I think the first approach is better for a simple reason : if we need more than one Layer, with bitwise we can simply use the Or Operator (|), in the second case we need to create everyMask we need and assign it in Inspector, because with one variable we can only detect one Layer at time.