如果我使用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
处的层被启用,其他任何层都被禁用。这将具有int
值1
(=2^0
(
的第二个例子
// indices 7654 3210
0000 1010
这将意味着索引1
和3
处的层被启用,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);