Version: 2021.1
解压缩预制件实例
基于层的碰撞检测

Layers in Unity define which GameObjects can interact with different features and one another. They are most commonly used by Cameras to render only a part of the scene, and by Lights to illuminate only parts of the scene. But they can also be used by raycasting to selectively ignore colliders or to create collisions.

创建层

第一步是创建一个新层,随后我们可以将这个层分配给__游戏对象__。要创建新层,请打开 Tags and Layers 窗口(主菜单:Edit > Project Settings,然后选择 Tags and Layers 类别)。

我们可以在某个空用户层中创建一个新层。我们选择第 8 层。

分配层

Now that you have created a new layer, you can assign the layer to one or more GameObjects.

Each GameObject can only be assigned one layer.

Tags and Layers 窗口中,Player 层分配给第 8 层。

通过摄像机的剔除遮罩功能仅绘制场景的某一部分

利用摄像机的剔除遮罩,您可以选择性地渲染位于某一特定层中的对象。 为此,请选择需要部分渲染对象的摄像机。

通过在剔除遮罩属性中选中或取消选中某些层来修改剔除遮罩。

请注意,不会剔除 UI 元素。屏幕空间画布子项会不受摄像机的剔除遮罩影响。

选择性投射光线

通过使用层,您可以投射光线并忽略特定层中的碰撞体。 例如,您可能希望仅对玩家层投射光线并忽略所有其他碰撞体。

Physics.Raycast 函数获取位掩码,在位掩码中,每个位确定该层是否将被忽略。 如果 layerMask 中的所有位都启用,那么将可以对所有碰撞体进行碰撞。 如果 layerMask = 0,则投射光线不会发生任何碰撞。

int layerMask = 1 << 8;

// Does the ray intersect any objects which are in the player layer.
if (Physics.Raycast(transform.position, Vector3.forward, Mathf.Infinity, layerMask))
{
    Debug.Log("The ray hit the player");
}

然而,在现实世界中,您希望相反的效果。我们想要对玩家层中碰撞体之外的所有碰撞体投射光线。

void Update ()
{
    // Bit shift the index of the layer (8) to get a bit mask
    int layerMask = 1 << 8;

    // This would cast rays only against colliders in layer 8.
    // But instead we want to collide against everything except layer 8. The ~ operator does this, it inverts a bitmask.
    layerMask = ~layerMask;

    RaycastHit hit;
    // Does the ray intersect any objects excluding the player layer
    if (Physics.Raycast(transform.position, transform.TransformDirection (Vector3.forward), out hit, Mathf.Infinity, layerMask))
    {
        Debug.DrawRay(transform.position, transform.TransformDirection (Vector3.forward) * hit.distance, Color.yellow);
        Debug.Log("Did Hit");
    }
    else
    {
        Debug.DrawRay(transform.position, transform.TransformDirection (Vector3.forward) *1000, Color.white);
        Debug.Log("Did not Hit");
    }
}

如果您不将 layerMask 传递到 Raycast 函数,则仅忽略使用 IgnoreRaycast 层的碰撞体。 这是在投射光线时忽略某些碰撞体最简单的方法。


  • 2017–05–08 页面已修订

  • 在 Unity 2017.1 版中更新了剔除遮罩信息

解压缩预制件实例
基于层的碰撞检测