在Unity中将图层和位掩码与Raycast一起使用 [英] Using Layers and Bitmask with Raycast in Unity
问题描述
Unity的Raycast函数具有一个参数,您可以使用该参数对特定的GameObject进行光线广播.您还可以使用该参数忽略特定的GameObject.
Unity's Raycast functions has a parameter you could use to raycast to a particular GameObject. You can also use that parameter to ignore particular GameObject.
例如,Raycast功能:
For exmple the Raycast function:
public static bool Raycast(Vector3 origin, Vector3 direction, float maxDistance = Mathf.Infinity, int layerMask = DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal);
layerMask
参数用于指定哪些对象应该/不应该接收射线广播.
The layerMask
parameter is used to specified which Objects should/should not receive the raycast.
1 .如何将光线投射到特定游戏对象中,该对象位于称为多维数据集"的图层中?
1.How do you raycast to a particular GameObject which is in a layer called "cube"?
2 .如果场景中有 10 个游戏对象,但您只想通过光线播放仅 2 个游戏对象怎么办?你怎么做到的?
2.What if you have 10 GameObjects in the scene but you only want to raycast to just 2 GameObjects and ignore the rest? How do you do that?
让我们说这些对象的层是立方体"和球体".
Let's say that those Object's layers are "cube" and "sphere".
3 .如果您想对所有游戏对象进行光线广播,而忽略1.,该怎么办?
3.What if you want to raycast to all GameObjects but ignore 1.
比方说,要忽略的GameObject位于多维数据集"层中.
Let's say that the GameObject to ignore is in the "cube" layer.
4 .如果您想广播到所有游戏对象,而忽略2个(多个)游戏对象,该怎么办.
4.What if you want to raycast to all GameObjects but ignore 2(multiple) GameObjects.
同样,要忽略的层是多维数据集"和球形"层.
Again, the layers to ignore are the "cube" and "sphere" layers.
推荐答案
我看到的大多数Raycast
问题都错误地使用了Layermask
.尽管它运气不错,但是当他们实际上想从Raycast
中排除GameObject时,它们通常会遇到问题.
Most Raycast
questions I see use the Layermask
incorrectly. Although it works for them by luck but they usually run into issues when they actually want to exclude a GameObject from Raycast
.
此答案适用于人们在进行光线投射时想要使用图层来过滤游戏对象的所有情况.
This answer is made to cover all those scenarios that a person would want to use the Layer to filter GameObjects when performing raycast.
1 .如何将光线投射到特定游戏对象,该对象位于称为多维数据集"的图层中?
1.How do you raycast to a particular GameObject which is in a layer called "cube"?
首先,您使用LayerMask.NameToLayer("cube")
将图层名称转换为图层编号.如果该图层不存在,则 LayerMask.NameToLayer
函数将返回-1
.您必须先进行检查,然后再进行任何按位操作.
First you use LayerMask.NameToLayer("cube")
to convert the layer name to layer number. The LayerMask.NameToLayer
function returns -1
if the layer does not exist. You must check this before doing any layer bitwise operation.
射线播放到特定图层(仅适用于多维数据集"):
//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);
.
The most important part of the example above is int layerMask = (1 << cubeLayerIndex);
.
为简短起见,我将不检查其余答案的错误.
2 .如果场景中有 10 个游戏对象,但您只想通过光线播放仅 2 个游戏对象怎么办?你好吗 那?
2.What if you have 10 GameObjects in the scene but you only want to raycast to just 2 GameObjects and ignore the rest? How do you do that?
让我们说这些对象的层是立方体"和球体".
Let's say that those Object's layers are "cube" and "sphere".
向多维数据集"和球形"层发出光线,并忽略其余的内容:
//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 .如果您想对所有游戏对象进行光线播放而忽略1,该怎么办?
3.What if you want to raycast to all GameObjects but ignore 1.
比方说,要忽略的GameObject位于多维数据集"层中.
Let's say that the GameObject to ignore is in the "cube" layer.
向所有人广播,但忽略多维数据集"层:
//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 .如果您想广播到所有游戏对象,而忽略2个(多个)游戏对象,该怎么办.
4.What if you want to raycast to all GameObjects but ignore 2(multiple) GameObjects.
同样,要忽略的层是多维数据集"和球形"层.
Again, the layers to ignore are the "cube" and "sphere" layers.
向所有人广播,但忽略多维数据集"和球形"层:
//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));
OR
//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);
.
Finally, if you know the layer index/number, there is no need to use the LayerMask.NameToLayer
function. Just insert that layer index there. For example, let's raycast to the "cube" layer which is in index #9. You could just do int layerMask = (1 << 9);
.
请参阅 Layers 手册,以了解有关此主题的更多信息.
See the Layers manual to read more about this subjct.
这篇关于在Unity中将图层和位掩码与Raycast一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!