Unity 的 Pyshics.RaycastAll 图层参数的问题



如果我使用layer参数,此光线投射始终返回一个空数组,但如果我不使用它,则一切正常。我想为我的敌人(触发对撞机(制作一个分离层,以优化过程。

private RaycastHit[] GetRaycastHits(int layer = 0)
{
return Physics.RaycastAll(partToRotate.position, partToRotate.forward, ShootRangeDistance, layer);
}

非常奇怪的是,即使传递LayerMask.NameToLayer("Default"(也不起作用。我确保我的敌人现在在默认层上,我已经尝试传递允许施法触发的参数。

您使用的层掩码错误!

参见分层

Physics.Raycast函数采用一个位掩码,其中每个位决定是否忽略一个层。如果layerMask中的所有位都处于启用状态,我们将与所有对撞机发生碰撞如果layerMask=0,我们将永远找不到与光线的任何碰撞

为了进一步了解比特掩码

位掩码的工作原理基本如下:

每个(在这种情况下(层由一个启用(1(或禁用(0("表示;位";。

请记住,二进制后端中的一个int基本上只有4个字节=>32位=>Unity中有32个可用层。

举个例子来说,目前只有8层。

所以比特掩码看起来像

0000 0001

现在我将在上面添加索引,这样你就可以理解我所说的了

//indices 7654 3210
0000 0001

这意味着索引0处的层被启用,其他任何层都被禁用。这将具有int1(=2^0(

的第二个例子

// indices 7654 3210
0000 1010

这将意味着索引13处的层被启用,int的值将是10**为什么?因为它等于

0*2^7 + 0*2^6 + 0*2^5 + 0*2^4 + 1*2^3 + 0*2^2 + 1*2^1 + 0*2^0
= 0 + 0 + 0 + 0 + 8 + 0 + 2 + 0
= 10

为了写得更容易,你通常会使用位移操作,比如

var layers = 1<<3 | 1<<1;
// In bits   1000   10

这将导致最后的掩模示例。


所以Default层实际上是

int defaultLayer = 1<<0;

不等于0,而是等于1


为了不必进行层计算或通过字符串进行硬编码,您应该使用类似的LayerMask字段

public LayerMask raycastLayers;

在您的组件中,通过Inspector配置它,然后像一样传入

// This is possible because LayerMask has an implicit conversion from int to LayerMask
//                                                       |
//                                                       v
private RaycastHit[] GetRaycastHits(LayerMask hitLayers = 1<<0)
{
return Physics.RaycastAll(partToRotate.position, partToRotate.forward, ShootRangeDistance, hitLayers.value);
}

var hits = GetRaycastHits(raycastLayers);

我相信layerMask适用于您希望忽略的层。

尝试反转("逐位"反转(:

return Physics.RaycastAll(partToRotate.position, partToRotate.forward, ShootRangeDistance, ~layer);

最新更新