onTriggerEnter Layers vs Tags

ontriggerenter doesnt detect layers only tags. oops.

Is this a realisation or a statement?

lmao. good one.

its a bug report.

Tags have nothing to do with physics.

Not sure what you mean by this. Afaik, OnTriggerEnter just lets you know if something entered the trigger. If you want to filter out stuff based on layers or tags, you do that yourself. Something like:

private void OnTriggerEnter(Collider other) 
{
   if ((myLayerMask.value & (1 << other.gameObject.layer)) > 0 ||
        other.gameObject.tag == "MyTag") 
   {
   // do something.
   }
}

im trying to add only specific triggers to my health script list when they are hurting me:

THIS, did not work:

void OnTriggerEnter(Collider other)
    {
        if(other.gameObject.layer == hazardLayerMask)
        {
            colliders.Add(other);
        }
    }

nothing added to the list.

so I had to do THIS:

void OnTriggerEnter(Collider other)
    {
        if(other.CompareTag("Hazard/Fire") || other.CompareTag("Hazard/Electricity") || other.CompareTag("Hazard/Lightning"))
        {
            colliders.Add(other);
        }
    }

a bit more work and all, but seems the only way to get it them in the list.

so in conclusion, ontriggerenter does not seem to work with layers. im sure it makes sense to someone other than me.

I once found almost 400 bugs in one week in a program once. the only question is: are you impressed yet?

You’re using layer masks incorrectly. Do some cursory googling and you’ll find it’s not as simple as a == b in this specific context.

In any case I wouldn’t use either layers nor tags for this.

I would define the required functionality in an Interface and TryGetComponent for the interface. This is a well established practice for flexible interactions. Please do some learning: https://gamedevbeginner.com/interfaces-in-unity/

I think you don’t know what a bug is. You seem to be confusing “it doesn’t work” with a bug, but it’s just your lack of knowledge.

1 Like

Thanks. I’m trying to learn as much as i can as quickly as possible. i was looking for something like this. im not sure yet if this will help this specific problem but im sure i can learn something useful here. excellent.

bugs, yeah. im just kidding and partially trolling. im ultra intelligent and know the difference. i swear. also, i was trying to make you laugh. i do that.

thanks for the link, again.

Not much. I found more in a single day.

Plot twist: I wrote the program.

Layers in Unity are implemented using something called “bit masks”, which is a concept that exists in all programming languages. Basically, individual ones and zeroes in the binary representation of a number are used as on/off toggles, in this case, to represent which layer(s) we are interested in.

So for instance if we are interested in layers 2, 4, and 5, our layer mask would look like: 0…000011010. From right to left, digits in positions 2, 4 and 5 are “1” (on) while the rest are zero. The total amount of bits in the mask depends on the size of the type used to store the bit mask. Unity uses integers, and those are 4 bytes in size so we have 32 bits (or, 32 on/off toggles).

To check if an object is in a specific layer, you use the & operator, called “bitwise and”. This will go over all bits of both operands and perform a logic “and” operation: the result is 1 if the bit is 1 in both operands, and zero otherwise.

0011010 & 0010001 = 0010000

So to test if two bit masks intersect (that is, at least one digit is “on” in both of them) you “and” them together and check if the result is anything other than all zeroes.

Long story short, your code should be:

if (((1 << other.gameObject.layer) & hazardLayerMask.value) != 0)

Which roughly translates to: “if the layer the gameObject we collided against is contained in the hazardLayerMask, then do something”. In other words “if the hazardLayerMask contains a 1 at the position specified by the layer the other gameObject is in, then do something”.

This is also why you’ll sometimes see people write stuff like

int layer = 1 << 5;

The << operator (“left shift”) in this context is used to shift an 1 to the left a number of positions. This is used to build a bit mask, in this case 0…00010000.

Another commonly used bitwise operator is | (“or”). This can be used to fuse together multiple masks:

// this is the mask I used as the first example, layers 2, 4 and 5
int layers = (1 << 2) | (1 << 4) | (1 << 5);

Needless to say, using bit masks and bitwise operators is much more efficient than using arrays of booleans, string comparisons, or a bunch of if conditionals: they’re extremely fast to work with and make excellent use of memory since they pack a lot of information in a single number. You’ll find them pretty much everywhere in programming.

For more info, look up bit masks in google. Some food for though:
https://en.wikipedia.org/wiki/Mask_(computing)
https://www.learn-c.org/en/Bitmasks
https://yetanotherchris.dev/csharp/csharp-bit-manipulation-by-example-part-2/

1 Like