I have seen a TON of threads and tutorial videos and Discord discussions describing the differences between a LayerMask (a 32bit packed list of boolean values) and a layer index (the 0-to-31 index in the list of layer names).
If you know bitwise operators, it’s pretty easy to do the conversion once you understand these two data types. For example, the layer index 4 corresponds to the fifth binary bit in the LayerMask value (0b00000000000000000000000000010000) and you can compute it with (1 << 4). There’s all sorts of bitwise operators to combine or intersect these masks to make it easy and very highly performant to check if a renderer or collider is applicable or not.
For some reason I have never seen C# extension methods to deal with these in a more readable or “code literate” way. Surely, people have made such extensions, after having written this sort of code in long form more than once, but again, I haven’t seen any.
So here I offer mine to whomever might find them convenient.
public static void Add(ref this LayerMask mask, int layer)
{
mask |= (1 << layer);
}
public static void Remove(ref this LayerMask mask, int layer)
{
mask &= ~(1 << layer);
}
public static bool Contains(this LayerMask mask, int layer)
{
return (0 != (mask & (1 << layer)));
}
public static bool Contains(this LayerMask mask, GameObject gob)
{
if (gob == null)
return false;
return (0 != (mask & (1 << gob.layer)));
}
public static bool Contains(this LayerMask mask, Component component)
{
if (component == null)
return false;
return (0 != (mask & (1 << component.gameObject.layer)));
}
Now you can make more readable code like cullingMask.Add(ghostLayer); (*) or if (!interestingMask.Contains(collider)) return; instead of trying to mentally parse the bit math involved every time.
(*) I almost wrote Camera.main.cullingMask.Add(ghostLayer) but that’s a property so you still have to get, modify, set such properties separately.