LayerMasks for non-Raycast Purposes

I’m using a box collider with OnTriggerEnter events. I would like objects only of certain layers to be affected by the trigger. My idea was to use a LayerMask to easily select a list of layers I would like the trigger to check against for the objects that enter it. However, once I have my LayerMask set, I have no idea how to search against this mask to see if the triggering objects layer is a part of that mask.

So far I’ve only seen LayerMasks used as a property of Raycasts. Is it even possible to use them for other purposes? The documentation doesn’t seem to show me anything useful in this regard, so I’m not so hopeful.

By any chance, are you talking about this ?

I am, but I suppose that page says it all…

I know lights use layers too, but perhaps layers are limited to about those 3 purposes? I can’t use layers and masks for my own uses?

I did figure out a solution to my issue by using a small script on all the objects to work with the triggers.

There may be a way.

var layerMaskList : LayerMask;

function Start ()
{
	Debug.Log (layerMaskList.value);
}

Put this on an empty scene, set only one layer each time you launch the scene, in the layerMaskList, and observe the displayed value in the console.

It displays an int which is a sum.

A sum of what ?

In fact, each layer seems to have a value, which you add to the sum. If you have no layer, the sum is 0. If every layer is selected, you get -1 (probably a shortcut).

When you look carefully at the layer list, you have BuiltIn Layer 0, 1, 2, etc. If you set only Bulltin Layer 0 (Default), the sum is 1. If you set Bulltin Layer 1 (TransparentFX), the sum is 2.

If you have BuiltIn Layers 0, 1, 2 selected, the sum is 7.

What must we deduce ? For each BuiltIn Layer X, 2^X is added to the sum.

If you take the User Layer 8, you would get 256 (launching the scene with a custom layer at position 8 give us 256…).

The fact that the sum is only made of multiples of 2 (1, 2, 4, 8, 16…) ensures that each sum is made of a only precise layer mask list, because you could not reach this sum by an other list.

So, how is it related to triggers ? Well, when you trigger something, you can check for his gameObject.layer value and then check for whether it is included in the sum (if the sum is 254, you can’t possibly have the User Layer 8, which would have added 256 in the sum).

Do you understand ?

I do understand. Thanks for the research, AkilaeTribe!

So the mask’s value could only be a unique sum based on which layers are selected and would not be duplicated by any other combination of layers. I suppose I could then calculate a formula for determining those layers, perhaps storing an array of the layers into another array at index[ mask.value ] for quick reference of mask values and their layers.

Thanks again! I’m sure this information will be handy to myself and others.

To determine whether a mask is in the sum or not, you must start by the last layer (31).

currentSum = sum
If (0 <= currentSum - 2^31) then currentSum -= 2^31 (plus we know the layer 31 is here)
If (0 <= currentSum - 2^30) then currentSum -= 2^30 (plus we know the layer 30 is here)

etc

so 263 = 256 + 4 + 2 + 1.

(Layers 8, 2, 1, 0).

(they were using this technique when I was working in my last company…very interesting).

You can also use bitwise masks (if scripting supports them). For example, to check if a specific layer is set, use this code:

Note:
is bitwise AND (not sure what Unity actually uses)
^ is ‘to the power of’ (not sure what Unity actually uses)

// layerToCheck is int layer between 1 and 8

if (layers  (2^(layerToCheck-1)){
  // The layer is set if the conditional results in a number greater than 0

}

Hi,

I was just looking for something like that…
and I found another way to check whether an object is part of a mask:

if((collidingMask.value  (1 << col.collider.gameObject.layer)) > 0){
    ...
}

where collidingMask is a LayerMask, col is a Collision object (get from a OnCollisionEnter function) from which I get the layer number.

this way is probably less expensive than use an exponent function.

Hope that helps :slight_smile:

Cheers