范围检测
碰撞产生必要条件
至少一个物体有刚体
两个物体都必须有碰撞器
碰撞与触发
碰撞会产生实际的物理效果
触发看起来不会产生碰撞但是可以通过函数监听触发
碰撞检测主要用于实体物体间产生物理效果时使用
什么是范围检测
游戏中瞬时的攻击范围判断一般会使用范围检测
如何进行范围检测
条件:必须具备碰撞体
注意:只有当执行该句代码时进行一次范围检测,不会产生碰撞器,只是碰撞判断计算
范围检测API
盒状范围检测
Physics.OverLapBox(Vector.zero,Vector.one,Quaternion.AngleAxis(45,Vector3.up),1<< LayerMask.NameToLayer(层级名称)),QueryTriggerInteraction.UseGlobal)
参数一:立方体中心点
参数二:立方体三边大小
参数三:立方体角度
参数四:检测指定层级(不填检测所有层)
参数五:是否忽略触发器(UseGlobal:使用全局设置,Collide:检测触发器,Ignore:忽略触发器,不填默认UseGlobal)
返回值:在该范围内的触发器(得到了对象触发器就可以得到对象的所有信息)
球形范围检测
Physics.OverlapSphere(Vector3.zero,5,1<<LayerMask.NameToLayer(层级名称),QueryTriggerInteraction.UseGlobal)
参数一:中心点
参数二:球半径
参数三:检测指定层级(不填检测所有层)
参数四:是否忽略触发器
胶囊范围检测
Physics.OverlapCapsule((Vector3.zero,Vector3.up,1,1<<LayerMask.NameToLayer(层级名称),QueryTriggerInteraction.UseGlobal)
参数一:半圆一中心点(上半圆)
参数二:半圆二中心点(下半圆)
参数三:半圆半径
参数四:检测指定层级(不填检测所有层)
参数五:是否忽略触发器
返回值:在该范围内的触发器(得到对象触发器就可以得到对象所有信息)
Physics.OverlapBoxNonAlloc
可传入一个数组,将碰撞到的碰撞器数量传入该数组,返回值为数组长度
重点
关于层级
通过名字得到层级编号LayerMask.NameToLayer
需要通过编号左移构建二进制数
这样每个编号层级都是对应位为1的2进制数
通过位运算可以选择想要检测的层级
好处:一个int就可以表示所有想要检测的层级信息
层级编号是0~31刚好32位
是一个int数
每个编号代表的都是二进制的一位
0—1<<0—0000 0000 0000 0000 0000 0000 0000 0001 = 1
1—1<<0—0000 0000 0000 0000 0000 0000 0000 0010 = 2
2—1<<0—0000 0000 0000 0000 0000 0000 0000 0100 = 4
3—1<<0—0000 0000 0000 0000 0000 0000 0000 1000 = 8
4—1<<0—0000 0000 0000 0000 0000 0000 0001 0000 = 16
5—1<<0—0000 0000 0000 0000 0000 0000 0010 0000 = 32
例如:
待检测层:1 << LayerMask.NameToLayer("UI"),该层二进制为:Convert.ToString(1 << LayerMask.NameToLayer("UI"),2) = 100000
检测指定层:1 << LayerMask.NameToLayer("Water") | 1 << LayerMask.NameToLayer("Default") | 1 << LayerMask.NameToLayer("UI"),该所有层二进制为:Convert.ToString((1 << LayerMask.NameToLayer("Water") | 1 << LayerMask.NameToLayer("Default") | 1 << LayerMask.NameToLayer("UI")),2) = 110001
根据二进制位与(&)规则: 二进制位与运算符用来比较两个二进制数的每一位。如果两个数的同一位都是 1,那么结果就是 1,否则结果就是 0
110001
100000
从右往左比较,下标从0开始,第5位两个数都为1,结果为1,而“UI”层的层级编号是5,所以“UI”层在检测范围内
总结
范围检测主要用于瞬时碰撞范围检测