Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 检查光线投射是否命中,是否命中LayerMask中的某个层?_C#_Unity3d - Fatal编程技术网

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调用中的最后一个参数,或者删除~如果它已经存在。就这样,非常感谢!