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

Question Relation between SetLayerCollisionMask and IgnoreLayerCollision not documented

Discussion in '2D' started by Baste, Sep 26, 2023.

  1. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,179
    What's the relation between the layer collision mask and IgnoreLayerCollision?

    I noticed that the methods doesn't say anything in the documentation. I've always assumed that IgnoreLayerCollision has priority over the layer collision mask, but it might as well be that IgnoreLayerCollision just sets a single bit in the collision mask, so they're two different interfaces to the same data.
     
  2. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,329
    If two specific colliders are set to ignore each other then nothing can override that.

    The order of evaluation is:
    1. Kinematic/Kinematic and not using full-kinematic contacts? Yes so no Contact
    2. Ignore Collider/Collider? Yes so no Contact
    3. Either Collider using an Effector Collider Mask? Yes, so contact is defined by that.
    4. Combine the Layer Collision Matrix with +Include Layer(s) and -Exclude Layer(s) + Layer Priority and use that.
    5. If Layer masks are conflicting and they have the same layer priority then no Contact (sort of a soft user error)

    4 is what you'd use most of the time with 2 being the per-collider-pair override.
     
  3. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,179
    Thanks for the reply!

    I don't think that quite covers my question. I wasn't wondering about Physics2D.IgnoreCollision, I was wondering about Physics2D.IgnoreLayerCollision, and how it relates to the layer collision matrix. Is it updating the collision matrix, or overriding it?

    Or in code, if I do this:

    Code (csharp):
    1. Physics2D.IgnoreLayerCollision(0, 8, true);
    Is that the same as:

    Code (csharp):
    1. var matrix = Physics2D.GetLayerCollisionMask(0);
    2. Physics2D.SetLayerCollisionMask(0, matrix & ~(1 << 8));
    Or is it something else?
     
  4. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,329
    Oh sorry, think I had too much of your other question on my mind!

    So yes, it's a simple bit toggle which updates the Layer Collision Matrix. It's actually the call we use in the Editor itself so setting it outside of play-mode will persist the change. Obviously in play-mode it'll won't be persisted.

    Here's it being used in the Layer Collision Matrix Editor itself:

    https://github.com/Unity-Technologi...aged/Settings/Physics2DSettingsEditor.cs#L196

    Internally the Layer Collision Matrix is an array of 32 x UInt32 where each is a bit-mask of what that layer (array index) can interact with. This means that when you use "SetLayerCollisionMask" to set a whole mask, the whole set of masks are updated appropriately. You can find this stored in the "ProjectSettings/Physics2DSettings.asset" as "m_LayerCollisionMatrix".

    Yes! The "ignore" part inverses it.

    Or layer 0 can interact only with layers 3 and 6
    Code (CSharp):
    1. Physics2D.SetLayerCollisionMask(0, (1 << 3) | (1 << 6));
     
    Baste likes this.
  5. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,329
    Some of the source for ignoring a layer collision:
    Code (CSharp):
    1. void Physics2DSettings::IgnoreLayerCollision(int layer1, int layer2, bool ignore)
    2. {
    3.     <snip>
    4.  
    5.     // m_LayerCollisionMatrix is an array of UInt32 x 32.
    6.  
    7.     if (ignore)
    8.     {
    9.         m_LayerCollisionMatrix[layer1] &= ~(1 << layer2);
    10.         m_LayerCollisionMatrix[layer2] &= ~(1 << layer1);
    11.     }
    12.     else
    13.     {
    14.         m_LayerCollisionMatrix[layer1] |= 1 << layer2;
    15.         m_LayerCollisionMatrix[layer2] |= 1 << layer1;
    16.     }
    17.  
    18.     <snip>
    19. }
     
    Baste likes this.