什么是范围检测
游戏中瞬时的攻击范围判断一般会使用范围检测。
例如:
-
玩家在前方5m处释放一个魔法,在此范围内的对象将收到伤害;
-
玩家攻击,在前方1m圆形范围内对象都会受到伤害,等等。
类似这种并没有实体物体,只想在检测的一瞬间在某一指定范围内是否让敌人受到伤害时,便可以使用范围判断。简而言之,在指定的位置进行范围判断,我们可以得到处于指定范围内的对象,目的是对对象进行处理,比如受伤,减血等。
如何进行范围检测
必备条件:想要范围检测到的对象,必须具备碰撞器!
注意:
- 范围检测相关API只有当执行该代码时进行一次范围检测,他是瞬时的
- 范围检测相关API并不会真的产生一个碰撞器,只是碰撞判断计算而已
范围检测API
盒状范围检测
- 参数1:立方体中心的
- 参数2:立方体三边大小
- 参数3:立方体角度
- 参数4:检测指定层级(不填检测所有层)
- 参数5:是否忽略触发器。UseGlobal- 使用全局设置 Collide-检测触发器 Ignore-忽略触发器 不填默认UseGlobal
- 返回值:在该范围内的触发器(得到了对象触发器就可以得到对象的所有信息)
//只检测Default层
Collider[] colliders = Physics.OverlapBox(Vector3.zero, Vector3.one, Quaternion.AngleAxis(45, Vector3.up),
1 << LayerMask.GetMask("Default"), QueryTriggerInteraction.UseGlobal);
foreach (var collider in colliders)
{
print(collider.gameObject.name);
}
关于层级的运算:
如果不填指定层级,那么默认是所有层;如果想只检测对应某几个层级,可以使用或运算;如果不想检测某几层可以先或后非。
Unity内部逻辑是 1<<(0-31) 然后与传入的值做与运算,如果不为0则表示这个层级需要检测。
另外可以通过名字得到层级编号:LayerMask.NameToLayer("Default"); 我们需要通过左移构建二进制,这样每个编号的层级都对应位为1的2进制数,我们通过位运算可以选中想要检测的层级。好处是一个int就可以表示所有想要检测的层级信息。
例如:(层级编号是0-31,刚好32位)
每个编号都是int数,都代表的二进制的一位
- //0 --------- 1<<0 ======== 0000 0000 0000 0000 0000 0000 0000 00001 =1
- //1 --------- 1<<1 ======== 0000 0000 0000 0000 0000 0000 0000 00010 =2
- //2 --------- 1<<2 ======== 0000 0000 0000 0000 0000 0000 0000 00100 =4
- …….
另一个盒状范围检测API
- 返回值:碰撞到的碰撞器数量
- 参数:传入一个数组进行存储
Collider[] colliders1 = new Collider[] { };
if (Physics.OverlapBoxNonAlloc(Vector3.zero, Vector3.one, colliders1) != 0)
{
}
球形范围检测
- 参数1:中心点
- 参数2:球半径
- 参数3:检测指定层级(不填检测所有层)
- 参数4:是否忽略触发器。 UseGlobal- 使用全局设置 Collide-检测触发器 Ignore-忽略触发器 不填默认UseGlobal
- 返回值:在该范围内的触发器
Collider[] colliders2 = Physics.OverlapSphere(Vector3.zero, 5, 1 << LayerMask.GetMask("Default"));
另一个球形范围检测
- 返回值:碰撞到的碰撞器数量
- 参数:传入一个数组进行存储
Collider[] colliders3 = new Collider[] { };
if (Physics.OverlapSphereNonAlloc(Vector3.zero, 5, colliders3) != 0)
{
}
胶囊范围检测
- 参数1:半圆一中心点
- 参数2:半圆二中心点
- 参数3:半圆半径
- 参数4:检测指定层级(不填检测所有层)
- 参数5:是否忽略触发器。 UseGlobal- 使用全局设置 Collide-检测触发器 Ignore-忽略触发器 不填默认UseGlobal
- 返回值:在该范围内的触发器
//胶囊是两个半圆加上中间的圆柱体构成。通过参数1和2,可以确定胶囊圆柱体的高以及胶囊的角度
Collider[] colliders4 = Physics.OverlapCapsule(Vector3.zero, Vector3.up, 1);
另一个胶囊范围检测
- 返回值:碰撞到的碰撞器数量
- 参数:传入一个数组进行存储
if(Physics.OverlapCapsuleNonAlloc(Vector3.zero, Vector3.up, 1, colliders5) != 0)
{
}