C# 检查光线投射是否命中,是否命中LayerMask中的某个层?
书名上写的是艾尔 最初我使用的是:C# 检查光线投射是否命中,是否命中LayerMask中的某个层?,c#,unity3d,C#,Unity3d,书名上写的是艾尔 最初我使用的是: hit.transform.gameObject.layer == LayerMask.NameToLayer("Floor") 但最终我发现不同的楼层需要不同的层,我想我应该使用一个LayerMask,如果我错了,请纠正我,但不能让它工作 在文件的顶部,我有: public LayerMask floorLayers; 在void更新中,我有: int floorMask = ~floorLayers.value; 在if声明中,我有: if (pla
hit.transform.gameObject.layer == LayerMask.NameToLayer("Floor")
但最终我发现不同的楼层需要不同的层,我想我应该使用一个LayerMask,如果我错了,请纠正我,但不能让它工作
在文件的顶部,我有:
public LayerMask floorLayers;
在void更新中,我有:
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");
}
由于您希望光线投射忽略任何非地板的内容,因此可以在光线投射中使用遮罩,使其仅命中地板。要执行此操作,您需要使用LayerMask floorLayers,以便只检查楼层,然后在光线投射中: Physics.Raycasttransform.position,dirDown,out hit,10f,~floorLayers.value 如果你这样做了,任何一击都将是落地一击,你不需要在下面做任何数学运算 如果您后来决定不能对光线投射使用相同的遮罩,那么您可能真的需要光线投射能够与许多可能的目标碰撞,然后查看命中的对象是否恰好是地板,然后阅读下面的内容 首先,您要比较一个掩码值,该值的位仅针对楼层设置为true,它似乎是floorLayers.value 如果要将GameObject.layer与LayerMask.value进行比较,首先需要按GameObject.layer移动一点 另外,如果您想检查gameObject.layer和floorMask之间是否至少有一个匹配项,您需要使用binary and&并查看它是否不是0!=0是不必要的,但它有助于提高可读性:
... && 1由于您希望光线投射忽略任何非地板的内容,因此可以在光线投射中使用遮罩,使其仅命中地板。要执行此操作,您需要使用LayerMask floorLayers,以便只检查楼层,然后在光线投射中: Physics.Raycasttransform.position,dirDown,out hit,10f,~floorLayers.value 如果你这样做了,任何一击都将是落地一击,你不需要在下面做任何数学运算 如果您后来决定不能对光线投射使用相同的遮罩,那么您可能真的需要光线投射能够与许多可能的目标碰撞,然后查看命中的对象是否恰好是地板,然后阅读下面的内容 首先,您要比较一个掩码值,该值的位仅针对楼层设置为true,它似乎是floorLayers.value 如果要将GameObject.layer与LayerMask.value进行比较,首先需要按GameObject.layer移动一点 另外,如果您想检查gameObject.layer和floorMask之间是否至少有一个匹配项,您需要使用binary and&并查看它是否不是0!=0是不必要的,但它有助于提高可读性: ... && 1有了这个:
if(hit.transform.gameObject.layer == floorMask)
您只是比较RaycastHit结果中的层命中率。如果这真的是您想要的,并且您只想检查层对光线投射的影响,那么不要在层上执行任何位掩码操作
删除此项:
获取图层索引:
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))
{
}
}
您可以在post上找到许多其他示例。与此相关:
if(hit.transform.gameObject.layer == floorMask)
您只是比较RaycastHit结果中的层命中率。如果这真的是您想要的,并且您只想检查层对光线投射的影响,那么不要在层上执行任何位掩码操作
删除此项:
获取图层索引:
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))
{
}
}
您可以在帖子中找到许多其他示例。感谢您的快速回复,但不幸的是,它仍然不起作用。我想要实现的是,如果它击中层掩码中的任何层,它应该做些什么,在我的情况下,我
n安装一个预制板。@QuincyNorbert我不知道在一个地板上有多个层。如果是这样的话,你把floorLayers.value放进了Physics.Raycast,那么任何命中率都不符合这个条件吗?无论如何,我编辑了我的答案,以解决一个包含多个层的~LayerMask.value。由于某些原因,我仍然无法让它工作,我将用更多的代码更新帖子,以了解它现在是如何设置的。感谢您的快速回复,不幸的是,它仍然无法工作。我想实现的是,如果它击中层掩码中的任何层,它应该做些什么,在我的例子中,实例化一个预置。@QuincyNorbert我没有意识到在一个地板掩码中有多个层。如果是这样的话,你把floorLayers.value放进了Physics.Raycast,那么任何命中率都不符合这个条件吗?无论如何,我编辑了我的答案,以解决一个包含多个层的~LayerMask.value。由于某些原因,我仍然无法让它工作,我将用更多的代码更新帖子,以了解它现在是如何设置的。floorLayers是否设置为选择每个楼层,从而使floorMask选择所有非楼层的内容?在这种情况下,如果只删除if语句的最后一部分,会发生什么呢?经过一些测试,我让它工作了,但它是反向的。我已经选择了我希望光线投射命中的2个层,但结果证明我必须选择除我想要的2个层以外的所有层。有什么方法可以反转它吗?反转Raycast调用中的最后一个参数,或者删除~如果它已经存在。就这样,非常感谢!floorLayers是否设置为选择每个楼板层,从而使floorMask选择所有非楼板的对象?在这种情况下,如果只删除if语句的最后一部分,会发生什么呢?经过一些测试,我让它工作了,但它是反向的。我已经选择了我希望光线投射命中的2个层,但结果证明我必须选择除我想要的2个层以外的所有层。有什么方法可以反转它吗?反转Raycast调用中的最后一个参数,或者删除~如果它已经存在。就这样,非常感谢!