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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Is there a way to get the layer collision matrix?

Discussion in 'Scripting' started by GarthSmith, Aug 5, 2014.

  1. GarthSmith

    GarthSmith

    Joined:
    Apr 26, 2012
    Posts:
    1,240
    So I'm writing custom character controller scripts which make heavy use of raycast. Right now, this means that I am passing layer masks into the Physics.Raycast() function. I want to generalize my code so that if no layermask is provided, then my controller will raycast layers the provided object can already collide with.

    Is there some way I can get the layer collision matrix? Should I just loop through every combination of layers and run Physics.GetIgnoreLayerCollision() a few dozen times?
     

    Attached Files:

    bruh0 likes this.
  2. naked_chicken

    naked_chicken

    Joined:
    Sep 10, 2012
    Posts:
    186
    My guess is that you'll have to write a custom PropertyDrawer or just a custom editor if you only want to do it on one script.
     
  3. GarthSmith

    GarthSmith

    Joined:
    Apr 26, 2012
    Posts:
    1,240
    I should clarify, I want to do this at runtime. Here's an example script.
    Code (csharp):
    1. public static bool HitGround(IController controller, float distance, int bitLayerMask) {
    2.   return Physics.RayCast(controller.position, -controller.transform.up, distance + 0.5f * controller.height, bitLayerMask);
    3. }
    I want to come up with a version of this function that does not take a bitLayerMask, but instead gets the layer from controller.gameObject.layer and then figures out which layers the Raycast should hit.
     
    bruh0 likes this.
  4. bellicapax

    bellicapax

    Joined:
    Oct 5, 2016
    Posts:
    14
    Sorry to necro this, but for anyone else out there, here's a useful script I wrote to access these values:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections.Generic;
    3.  
    4. public static class PhysicsCollisionMatrixLayerMasks
    5. {
    6.     private static Dictionary<int, int> _masksByLayer;
    7.  
    8.     public static void Init()
    9.     {
    10.         _masksByLayer = new Dictionary<int, int>();
    11.         for (int i = 0; i < 32; i++)
    12.         {
    13.             int mask = 0;
    14.             for (int j = 0; j < 32; j++)
    15.             {
    16.                 if(!Physics.GetIgnoreLayerCollision(i, j))
    17.                 {
    18.                     mask |= 1 << j;
    19.                 }
    20.             }
    21.             _masksByLayer.Add(i, mask);
    22.         }
    23.     }
    24.  
    25.     public static int MaskForLayer(int layer)
    26.     {
    27.         return _masksByLayer[layer];
    28.     }
    29. }
    30.  
     
  5. JustMoser

    JustMoser

    Joined:
    Feb 2, 2014
    Posts:
    2
    This is great, just what I needed. Thank you
     
  6. HM2D

    HM2D

    Joined:
    Mar 14, 2016
    Posts:
    1
    This is my version of handeling the save and load of the physics matrix. You can also save it to the file for a better view.
    Hope this helps anyone who needs it.
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections.Generic;
    3. using System.IO;
    4. using System.Text;
    5. using UnityEditor;
    6.  
    7.     public static class PhysicsCollisionMatrixLayerMasks
    8.     {
    9.  
    10.         private static bool[,] m_CollisionMatrix = new bool[32, 32];
    11.  
    12.         public static bool[,] CollisionMatrix => m_CollisionMatrix;
    13.         public static void SaveCollisionMatrix(bool saveToFile)
    14.         {
    15.             string strName = "";
    16.             string strID = "";
    17.             for (int i = 0; i < m_CollisionMatrix.GetLength(0); ++i)
    18.             {
    19.                 for (int j = 0; j < m_CollisionMatrix.GetLength(1) - i; ++j)
    20.                 {
    21.                     m_CollisionMatrix[i, j] = !Physics.GetIgnoreLayerCollision(i, j);
    22.                     strName += "[" + LayerMask.LayerToName(i) + "/" + LayerMask.LayerToName(j) + "(" + m_CollisionMatrix[i, j] + ")] ";
    23.                     strID += "[" + i + "/" + j + "(" + m_CollisionMatrix[i, j] + ")] ";
    24.                 }
    25.                 strName += "\n";
    26.                 strID += "\n";
    27.             }
    28.  
    29.             if (!saveToFile)
    30.                 return;
    31.  
    32.             FileStream fWrite = new FileStream(Application.dataPath + "/PhysicsMatrix(WithName).txt",
    33.                        FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);
    34.             byte[] writeArr = Encoding.UTF8.GetBytes(strName);
    35.  
    36.             fWrite.Write(writeArr, 0, strName.Length);
    37.             fWrite.Close();
    38.  
    39.             fWrite = new FileStream(Application.dataPath + "/PhysicsMatrix(ID).txt",
    40.                        FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);
    41.             writeArr = Encoding.UTF8.GetBytes(strID);
    42.  
    43.             fWrite.Write(writeArr, 0, strID.Length);
    44.             fWrite.Close();
    45.         }
    46.  
    47.         public static void LoadCollisionMatrix()
    48.         {
    49.             for (int i = 0; i < m_CollisionMatrix.GetLength(0); ++i)
    50.             {
    51.                 for (int j = 0; j < m_CollisionMatrix.GetLength(1) - i; ++j)
    52.                 {
    53.                     Physics.IgnoreLayerCollision(i, j, !m_CollisionMatrix[i, j]);
    54.                 }
    55.             }
    56.         }
    57.     }
    58.  
     
    CasualT_Bossfight likes this.
  7. MinhocaNice

    MinhocaNice

    Joined:
    May 3, 2020
    Posts:
    249
    Let me see if I understood correctly, the dictionary contains all the layers in the Layer Collision Matrix, when you call the
    int MaskForLayer(int layer)
    function, it returns all the layers that the input layer does not collide with... Is that correct?