Unity Layers与LayerMask理解

层(Layer)

  在 Unity 中,***层***定义哪些游戏对象可以与不同的功能以及彼此交互。

  它们主要有两种用途:由摄像机用来仅渲染场景的某一部分;由光源用来仅照亮场景的某些部分。

  当然还有一个重要用途,也可以供射线投射用于选择性地忽略碰撞体或创建碰撞。

Layers

LayerMask

  指定要在 Physics.Raycast 中使用的层。

  GameObject 最多可以使用 Editor 支持的 32 个 LayerMask。这些 Layers 中的前 8 个由 Unity 指定;以下 24 个可由用户控制。

Unity官方文档中这样描述:

  位掩码表示 32 层,并将它们定义为 true 或 false。每个位掩码描述是否使用 Layer。

  我觉得稍微有些晦涩难懂,简单点说,LayerMask实际上是用Int32的32个位与Inspector窗口中的32个Layer一一对应,当这个位为1时表示使用这个层,为0时表示不用这个层。

  举个例子:我们想要检测射线是否射向位于“Water”层的GameObject,通过LayerMask.NameToLayer("Water")获取曾索引或者从上图中也可以得到Layer的序号,即16。

  那么对应的LayerMask即为:

 LayerMask mask = 1 << 16
 (等价于LayerMask.GetMask("Water"))

  因此有以下写法:

LayerMask mask = 1 << 2; 表示开启索引为2的层。

LayerMask mask = 0 << 5表示关闭索引为5的层。

LayerMask mask = ~(1 << 16) 打开除了索引为16的层之外的层。

LayerMask mask = ~(1 << 0) 打开所有的层。

(1 << 16) | (1 << 8) 打开索引为10和索引为8的层。等价于LayerMask.GetMask(("Game", "Processing");

简单谈谈LayerMask类中的函数

GetMask

public static int GetMask (params string[] layerNames);

  给定在***一组***层名称,返回所有这些层名称的等效层遮罩。

LayerMask.GetMask("UserLayerA", "UserLayerB")

LayerToName

public static string LayerToName (int layer);

  给定层编号,返回层的名称。

NameToLayer

public static int NameToLayer (string layerName);

  给定层名称,返回层索引。

  如果未找到,则返回 -1。


本文参考的文章
Unity Layers与LayerMask理解(CSDN)
UnityEngine.LayerMask - Unity 脚本 API