标题称之为
最初我使用的是:
hit.transform.gameObject.layer == LayerMask.NameToLayer("Floor")
但最终我发现不同的地板需要不同的层,我想我应该使用LayerMask,如果我错了,但不能让它发挥作用,请纠正我。
在文件的顶部,我有:
public LayerMask floorLayers;
在空白更新我有:
int floorMask = ~floorLayers.value;
在if语句中,我有:
if (playerHasWetFeet == true && wetSteps < maxWetSteps && controller.isGrounded && hit.transform.gameObject.layer == floorMask)
然而,这不起作用。
有人能指出我做错了什么吗?
编辑:
这在我的更新功能范围内:
int floorMask = ~floorLayers.value;
currentFrameFootstepLeft = anim.GetFloat("FootstepLeft");
if (currentFrameFootstepLeft > 0 && lastFrameFootstepLeft < 0)
{
if (Physics.Raycast(transform.position, dirDown, out hit, 10f, floorMask))
{
if (playerHasWetFeet == true && wetSteps < maxWetSteps && controller.isGrounded && (1 << hit.transform.gameObject.layer & floorMask) != 0)
{
LeftWetStepSpawner();
Debug.Log("Hit");
}
使用此:
if(hit.transform.gameObject.layer == floorMask)
您只是在比较RaycastHit
结果中的层命中率。如果这确实是您想要的,并且您只想检查光线投射按层命中的内容,则不要对层执行任何位掩码操作。
删除此:
int floorMask = ~floorLayers.value;
获取层索引:
int floor1 = LayerMask.NameToLayer("Floor1");
int floor2 = LayerMask.NameToLayer("Floor2");
int floor3 = LayerMask.NameToLayer("Floor2");
然后直接比较图层索引:
if (hit.transform.gameObject.layer == floor1)
{
}
if (hit.transform.gameObject.layer == floor2)
{
}
if (hit.transform.gameObject.layer == floor3)
{
}
虽然这应该可以解决您的问题,但使用图层掩码的主要原因是过滤光线投射。当使用layermask时,您可以使用它来决定光线投射应该命中或忽略哪些对象,如果这是您真正想要做的,请不要像在代码中那样比较层。只需找到遮罩,然后将遮罩传递给光线投射函数。我不确定这是否是您想要做的,但这两个例子都应该让您了解图层遮罩的用途。
例如,您希望只对"地板"层上的对象进行光线投射,而不希望光线投射击中另一层上的任何其他对象:
int floorLayerIndex = LayerMask.NameToLayer("Floor");
//Check if layer is valid
if (floorLayerIndex == -1)
{
Debug.LogError("Layer Does not exist");
}
else
{
//Calculate layermask to Raycast to. (Raycast to "Floor" layer only)
int layerMask = (1 << floorLayerIndex);
Vector3 fwd = transform.TransformDirection(Vector3.forward);
RaycastHit hit;
//Raycast with that layer mask
if (Physics.Raycast(transform.position, fwd, out hit, 10, layerMask))
{
}
}
你可以在这篇文章中找到许多其他的例子。
由于您希望光线投射忽略任何不是地板的东西,因此可以在光线投射中使用遮罩,使其只触及地板。要做到这一点,您需要有您的LayerMask floorLayers
,以便只检查楼层,然后在Raycast
:中
Physics.Raycast(transform.position, dirDown, out hit, 10f, ~floorLayers.value)
如果你这样做,任何命中都将是地板命中,你不需要做下面的任何数学运算。
如果您后来决定不能使用相同的遮罩进行光线投射(也许您真的需要光线投射能够与许多可能的目标碰撞,然后如果击中的对象恰好是地板,请参见(,请阅读以下内容。
首先,您想要比较一个掩码值,该值的位仅针对楼层设置为true,它似乎是floorLayers.value
。
如果要将GameObject.layer
与LayerMask.value
进行比较,首先需要按GameObject.layer
移位一位。
此外,如果您想检查gameObject.layer
和floorMask
之间是否至少有一个匹配,您需要使用二进制and(&
(并查看它是否不是0(!= 0
是不必要的,但它有助于提高可读性(:
... && (1 << hit.transform.gameObject.layer & floorLayers.value) != 0
这是因为GameObject.layer
是该单层的索引,但FloorMask.value
是基于各种位的真/假值的位掩码。直接比较它们是没有意义的,而不首先进行转换。