在Unity中使用Raycast图层和位掩码
Unity的Raycastfunction有一个参数可以用来对特定的GameObject进行光线投射。 您也可以使用该参数来忽略特定的GameObject。
例如Raycastfunction:
public static bool Raycast(Vector3 origin, Vector3 direction, float maxDistance = Mathf.Infinity, int layerMask = DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal);
layerMask
参数用于指定哪些对象应该/不应该接收光线投射。
1 ,你如何对一个名为“cube”的图层进行光线投射?
2,如果你在场景中有10个 GameObjects,但是你只想对2个 GameObjects进行光线投射而忽略其余部分? 你如何做到这一点?
假设这些对象的图层是“立方体”和“球体”。
3,如果你想对所有 GameObjects进行光线投射,但忽略1。
假设要忽略的GameObject位于“多维数据集”层中。
4,如果您想对所有 GameObjects进行光线投射,但忽略2(多个)GameObjects。
同样,要忽略的层是“立方体”和“球体”层。
我看到的大多数Raycast
问题Layermask
错误地使用了Layermask
。 虽然它运气好,但他们通常遇到的问题,当他们真的想从Raycast
排除游戏对象。
这个答案是为了涵盖一个人在执行光线投射时想使用图层来过滤GameObjects的所有场景。
1 ,你如何对一个名为“cube”的图层进行光线投射?
首先使用LayerMask.NameToLayer("cube")
将图层名称转换为图层编号。 如果图层不存在,则LayerMask.NameToLayer
函数返回-1
。 在进行任何图层按位操作之前,您必须先检查这一点。
Raycast到特定图层(仅“立方体”):
//Convert Layer Name to Layer Number int cubeLayerIndex = LayerMask.NameToLayer("cube"); //Check if layer is valid if (cubeLayerIndex == -1) { Debug.LogError("Layer Does not exist"); } else { //Calculate layermask to Raycast to. (Raycast to "cube" layer only) int layerMask = (1 << cubeLayerIndex); Vector3 fwd = transform.TransformDirection(Vector3.forward); //Raycast with that layer mask if (Physics.Raycast(transform.position, fwd, 10, layerMask)) { } }
上例中最重要的部分是int layerMask = (1 << cubeLayerIndex);
。
为了使这个答案简短,我不会检查答案的其余部分的错误。
2,如果你在场景中有10个 GameObjects,但是你只想对2个 GameObjects进行光线投射而忽略其余部分? 你如何做到这一点?
假设这些对象的图层是“立方体”和“球体”。
Raycast到“立方体”和“球体”层,忽略其余部分:
//Convert Layer Name to Layer Number int cubeLayerIndex = LayerMask.NameToLayer("cube"); int sphereLayerIndex = LayerMask.NameToLayer("sphere"); //Calculate layermask to Raycast to. (Raycast to "cube" && "sphere" layers only) int layerMask = (1 << cubeLayerIndex) | (1 << sphereLayerIndex);
3,如果你想对所有 GameObjects进行光线投射,但忽略1。
假设要忽略的GameObject位于“多维数据集”层中。
Raycast几乎都忽略了“多维数据集”层:
//Convert Layer Name to Layer Number int cubeLayerIndex = LayerMask.NameToLayer("cube"); //Calculate layermask to Raycast to. (Ignore "cube" layer) int layerMask = (1 << cubeLayerIndex); //Invert to ignore it layerMask = ~layerMask;
4,如果您想对所有 GameObjects进行光线投射,但忽略2(多个)GameObjects。
同样,要忽略的层是“立方体”和“球体”层。
Raycast除了忽略“立方体”和“球体”层:
//Convert Layer Name to Layer Number int cubeLayerIndex = LayerMask.NameToLayer("cube"); int sphereLayerIndex = LayerMask.NameToLayer("sphere"); //Calculate layermask to Raycast to. (Ignore "cube" && "sphere" layers) int layerMask = ~((1 << cubeLayerIndex) | (1 << sphereLayerIndex));
要么
//Convert Layer Name to Layer Number int cubeLayerIndex = LayerMask.NameToLayer("cube"); int sphereLayerIndex = LayerMask.NameToLayer("sphere"); //Calculate layermask to Raycast to. (Ignore "cube" && "sphere" layers) int layerMask = (1 << cubeLayerIndex); layerMask |= (1 << sphereLayerIndex); layerMask |= (1 << otherLayerToIgnore1); layerMask |= (1 << otherLayerToIgnore2); layerMask |= (1 << otherLayerToIgnore3); //Invert to ignore it layerMask = ~layerMask;
最后,如果您知道图层索引/编号,则不需要使用LayerMask.NameToLayer
函数。 只需在那里插入图层索引。 例如,让我们对索引#9中的“立方体”图层进行光线投射。 你可以做int layerMask = (1 << 9);
。
请参阅图层手册以了解有关此主题的更多信息。