- Home /
Check if Layer is in Layermask?
How can you tell if a LayerMask contains a given layer.
Answer by Eric5h5 · Mar 03, 2011 at 02:54 AM
var layermask : LayerMask;
var layer : int;
function Start () {
if (layermask.value; 1<<layer) {
Debug.Log ("Layer is in layer mask");
}
}
I'm not sure how to get this working. Is the & supposed to be &&? I'm also writing in C# (Forgot to mention that). What return values am I checking for on either side of the &?
Figured it out. Thanks!
if ((layersCheckedForTargets.value & <
Er sorry for my application I needed to see if it was NOT in layer mask. Above would be != if you wanted to check if it WAS in layer mask.
Yeah, C# doesn't seem to cast to bool automatically like that.
Answer by Ideka · Feb 05, 2016 at 02:47 AM
A C# solution that elegantly results in a bool is:
layermask == (layermask | (1 << layer))
It works! Elegant indeed.
And I think I can explain why.
Short version
I believe a layermask is a series of bools (true, false, false, true) but thirty-two of them.
Those "<<" are telling us to take 1, and move it left x times
Then the "|" symbol actually ADDS that 1 at the spot. So if x = 3, we get (true, TRUE, false true)
And then we compare "==". As you can see in italics, they won't be the same though. So in my example you would get NO, the layer was not included.
Long story
I want to first note that this other question's answers contain some amazing tips for working with Layermasks and making them easier. Especially declaring a public variable so you can go clicking in the inspector!
Anyway. I was wondering why EXACTLY Ideka's code works. I THIN$$anonymous$$ I get it.
Say for example we have a layermask that says we can collide with layers 1 and 3. In other words the layermask is 0101. Well, not digits, because I think Unity stores them as a bunch of booleans. Anyway (This video blogger explains bit shifting and how the layer is expressed as 1s and 0s.)
So let us say our object is layer 2. This may be expressed as 1 << 2 or even just 0010.
Well, then we're hoping the code returns FALSE, right? Because object 2 is not in layers 1 or 3. So let's look at this code to see if we get FALS$$anonymous$$..
Now in our example, we would want to ask ask:
layermask == (layermask | (1 << layer))
or 0101 == ( 0101 | (1 << 2 ) )
There's a lot happening on the right side of the '==' operator.
After bit shifting, really we are asking this:
0101 == ( 0101 | 0010 )
So we have to solve the right before we can compare. And so we have to know what the HELL the "|" symbol actually does. You can read the documentation here. Don't be fooled: This is not the same as "||".
It's called an inclusive OR. But basically that "|" symbol is going to go through every digit place and keep all the "1s" that it can. And so on the right: 0101 | 0010 becomes 0111. See what I mean by keeping the ones? Ok. We've solved the right side and the comparison becomes
0101 == 0111.
This returns FALSE!
So I learned that bit shifting is a weird way of saying where to put the '1' digits. And then you can use special operators on those digits, like how '|' will give you a layermask number with as many preserved '1s' as possible. In the end, layer 2 was not included in a mask for layers 1 and 3.
Consider a different case. If our object was 0100 (that is layer 3). Then our comparison from just now becomes
0101 == ( 0101 | (1 << 3 ) )
which becomes 0101 == ( 0101 | 0100 ) which becomes 0101 == ( 0101 ) or 0101 == 0101
We would get TRU$$anonymous$$
BONUS. There are other bitwise symbols. "&" and "^". The & symbol prefers zeroes, and the ^ symbol highlights contrasts — like it puts zeroes unless, it sees a one over here but a zero over there... But I won't explore that right now.
This is beautiful.
I added this as a static method on a utility class and it works like a charm
public static bool IsInLayer$$anonymous$$ask(int layer, Layer$$anonymous$$ask layermask)
{
return layermask == (layermask | (1 << layer));
}
Answer by Mikael-H · Mar 28, 2017 at 05:01 PM
Create a static class with extension methods as you go along. You'll find lots of functionality you wish was included in the frameworks. Might as well add it yourself!
using UnityEngine;
using UnityEngine.Events;
public static class UnityExtensions{
/// <summary>
/// Extension method to check if a layer is in a layermask
/// </summary>
/// <param name="mask"></param>
/// <param name="layer"></param>
/// <returns></returns>
public static bool Contains(this LayerMask mask, int layer)
{
return mask == (mask | (1 << layer));
}
}
Then just use it like:
if(_layerMask.Contains(otherLayer))
{
//Do stuff
}
Answer by DoubleLee · Jan 30, 2019 at 04:36 PM
if ((layerMask.layer & (1<<layerToCheck)) != 0)
Simpler and more straight forward if a single bit is true on both the mask and the layer to check, it contains the layer and returns non 0.
I think this is a better answer. However, the code contains a $$anonymous$$or mistake. This a correctly working code:
if ((layer$$anonymous$$ask & (1<<layerToCheck)) != 0)
Layer$$anonymous$$ask implicitly converts itself to an int, so no need to use "layer$$anonymous$$ask.value".
Answer by Tom-Mensink · Mar 27, 2020 at 11:34 PM
There are two solutions provided above, one with "|" and one with "&". The difference would be what you want the result to be when layer == 0 (Default layer), in which case the "|" routine returns true and the "&" routine returns false.
I my case I want to detect collision with a specific layer and in that case layer 0 should return false, so the "&" routine is the correct one for me. Put in a static method:
public static bool Contains(this LayerMask mask, int layer)
{
return ((mask & (1 << layer)) != 0)
}