标题说出来了。
最初我使用的是
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");
}
答案 0 :(得分:3)
与此:
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的主要原因是过滤光线投射。使用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))
{
}
}
您可以在this帖子中找到许多其他示例。
答案 1 :(得分:1)
由于您希望光线投射忽略不属于地板的任何物体,因此可以在光线投射中使用遮罩,使其仅撞击地板。为此,您希望拥有LayerMask floorLayers
,以便只检查楼层,然后在Raycast
中:
Physics.Raycast(transform.position, dirDown, out hit, 10f, ~floorLayers.value)
如果您执行此操作,则任何命中都将是无效命中,并且您无需在下面进行任何数学运算。
如果您以后决定不能对光线投射使用相同的蒙版(也许您真的需要光线投射才能与众多可能的目标发生碰撞,然后查看是否命中的物体碰巧设为地板),然后阅读以下内容。
首先,您要比较一个掩码值,该掩码值的位仅对于楼层(设置为floorLayers.value
)设置为true。
如果要将GameObject.layer
与LayerMask.value
进行比较,则首先需要将GameObject.layer
移一点。
此外,如果要检查gameObject.layer
和floorMask
之间的至少一个匹配项,则要使用二进制AND(&
)并查看它是否不为0({{ 1}}是不必要的,但有助于提高可读性):
!= 0
这是因为... && (1 << hit.transform.gameObject.layer & floorLayers.value) != 0
是该单层的 index ,但是GameObject.layer
是基于各种位的真/假值的位掩码。直接比较它们而不先进行转换是没有意义的。