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