using System; using System.Diagnostics; using UnityEngine; namespace Framework.Layers { /// Provides helper methods for working with layer masks public static class LayerMaskHelper { /// Index of the layer all game objects are on by default public static readonly int DefaultLayer = 0; //LayerMask.NameToLayer("Default"); /// Index of the layer used for transparent effects public static readonly int TransparentFxLayer = 1; //LayerMask.NameToLayer("TransparentFX"); /// Index of the layer which by default is ignored by all raycasts public static readonly int IgnoreRaycastLayer = 2; //LayerMask.NameToLayer("IgnoreRaycast"); /// Index of the layer intended to bodies of water public static readonly int WaterLayer = 4; //LayerMask.NameToLayer("Water"); /// Index of the layer on which world-space UI should be public static readonly int UiLayer = 5;//LayerMask.NameToLayer("UI"); /// Builds a layer mask for the specified layers /// Layers that should be part of the mask /// The layer mask for the specified layers public static int GetLayerMaskFor(params string[] layers) { int mask = 0; for(int index = 0; index < layers.Length; ++index) { int layerIndex = LayerMask.NameToLayer(layers[index]); mask |= 1 << layerIndex; } return mask; } /// Gets the layer mask for collision with the specified layer /// Name of the layer whose mask will be returned /// The layer collision mask for the specified layer /// /// Because calculating the layer mask is a bit costly, the masks will be cached. /// If you change layer collision masks at runtime via Physics.IgnoreLayerCollision(), /// the masks returned by this method will reflect that change until you also /// call . /// public static int GetLayerCollisionMaskFor(string layerName) { return GetLayerCollisionMaskFor(LayerMask.NameToLayer(layerName)); } /// Gets the layer mask for collision with the specified layer /// Index of the layer whose mask will be returned /// The layer collision mask for the specified layer /// /// Because calculating the layer mask is a bit costly, the masks will be cached. /// If you change layer collision masks at runtime via Physics.IgnoreLayerCollision(), /// the masks returned by this method will not reflect that change until you also /// call . /// public static int GetLayerCollisionMaskFor(int layerIndex) { enforceLayerIndexValid(layerIndex); // If we have already cached the result, provide it from the cache if(layerMaskQueried[layerIndex]) { return layerMask[layerIndex]; } // Result was not cached, query the layer mask and put it in the cache int mask = queryLayerCollisionMask(layerIndex); layerMaskQueried[layerIndex] = true; layerMask[layerIndex] = mask; return mask; } /// Invalidates the cached layer mask for the specified layer index /// /// Name of the layer whose cached layer mask will be invalidated /// public static void InvalidateCache(string layerName) { InvalidateCache(LayerMask.NameToLayer(layerName)); } /// Invalidates the cached layer mask for the specified layer index /// Layer index whose cached layer mask will be invalidated public static void InvalidateCache(int layerIndex) { enforceLayerIndexValid(layerIndex); layerMaskQueried[layerIndex] = false; } /// Queries the collision mask of the specified layer /// Layer whose collision mask will be queried /// The collision mask of the specified layer private static int queryLayerCollisionMask(int layerIndex) { int mask = 0; for(int index = 0; index < 32; ++index) { if(!Physics.GetIgnoreLayerCollision(layerIndex, index)) { mask |= (1 << index); } } return mask; } /// Throws an exception if the layer index is not valid /// Layer index that will be checked [Conditional("DEBUG")] private static void enforceLayerIndexValid(int layerIndex) { if((layerIndex < 0) || (layerIndex >= 32)) { throw new ArgumentException("Layer index must be in the 0-31 range", "layerIndex"); } } /// Keeps track of which layer masks have already been queried private static bool[/*32*/] layerMaskQueried = new bool[32]; /// Stores the collision masks for each of the 32 possible layers private static int[/*32*/] layerMask = new int[32]; } } // namespace Framework.Layers