Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Bug onTriggerEnter Layers vs Tags

Discussion in 'Editor & General Support' started by zeropointblack, Dec 15, 2022.

  1. zeropointblack

    zeropointblack

    Joined:
    Jun 8, 2020
    Posts:
    190
    ontriggerenter doesnt detect layers only tags. oops.
     
  2. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,881
    Is this a realisation or a statement?
     
  3. zeropointblack

    zeropointblack

    Joined:
    Jun 8, 2020
    Posts:
    190
    lmao. good one.

    its a bug report.
     
  4. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,881
    Tags have nothing to do with physics.
     
  5. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    1,663
    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:

    Code (CSharp):
    1.  
    2. private void OnTriggerEnter(Collider other)
    3. {
    4.    if ((myLayerMask.value & (1 << other.gameObject.layer)) > 0 ||
    5.         other.gameObject.tag == "MyTag")
    6.    {
    7.    // do something.
    8.    }
    9. }
     
  6. zeropointblack

    zeropointblack

    Joined:
    Jun 8, 2020
    Posts:
    190


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

    THIS, did not work:

    Code (CSharp):
    1.  
    2. void OnTriggerEnter(Collider other)
    3.     {
    4.         if(other.gameObject.layer == hazardLayerMask)
    5.         {
    6.             colliders.Add(other);
    7.         }
    8.     }
    9.  
    nothing added to the list.

    so I had to do THIS:

    Code (CSharp):
    1.  
    2. void OnTriggerEnter(Collider other)
    3.     {
    4.         if(other.CompareTag("Hazard/Fire") || other.CompareTag("Hazard/Electricity") || other.CompareTag("Hazard/Lightning"))
    5.         {
    6.             colliders.Add(other);
    7.         }
    8.     }
    9.  

    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.
     
  7. zeropointblack

    zeropointblack

    Joined:
    Jun 8, 2020
    Posts:
    190
    I once found almost 400 bugs in one week in a program once. the only question is: are you impressed yet?
     
  8. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,881
    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.
     
    arkano22 likes this.
  9. zeropointblack

    zeropointblack

    Joined:
    Jun 8, 2020
    Posts:
    190

    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.
     
  10. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    1,663
    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:

    Code (CSharp):
    1. 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
    Code (CSharp):
    1. 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:

    Code (CSharp):
    1.  
    2. // this is the mask I used as the first example, layers 2, 4 and 5
    3. 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/
     
    Last edited: Dec 16, 2022
    spiney199 likes this.