碰撞和射线检测
Contents
范围检测
//Physics.OverlapBox(中心点位置,长宽高的一半,角度 四元数);
//参数4 检测指定层级 填入层级的id 1<<LayerMask.NameToLayer("UI")
//参数5 是否忽略触发器 UseGlobal-使用全局设置 Collide-检测触发器 Ignore-忽略触发器 不填使用UseGlobal
Cokkider[] colliders = Physics.OverlapBox(Vector3.zero,new Vector3(1,2,3));
//球形碰撞器
colliders = Physics.OverlapSphere(Vector3.zero, 5, 1 << LayerMask.NameToLayer("Default"));
//胶囊碰撞器
colliders = Physics.OverlapCapsule(Vector3.zero, Vector3.up, 1, 1 << LayerMask.NameToLayer("UI"), QueryTriggerInteraction.UseGlobal);
//另一个API
//返回值:碰撞到的碰撞器数量
//参数:传入一个数组进行存储
//Physics.OverlapBoxNonAlloc()
if(Physics.OverlapBoxNonAlloc(Vector3.zero, Vector3.one, colliders) != 0)
{
Debug.log(colliders.length);
}LayerMask位运算
Unity中的层级编号是0~31 刚好32位
每一个编号 代表的都是 二进制中的一位
- 1« 5 0000 0000 0000 0000 0000 0000 0001 0000 代表第五层
- 1« 1 0000 0000 0000 0000 0000 0000 0000 0010 代表第一层
如果想要同时检测第五层和第一层 则使用1« 5 | 1« 1 或运算有1则1
结果:0000 0000 0000 0000 0000 0000 0001 0010
射线检测
它可以再指定点发射一个指定方向的射线
判断该射线和那些碰撞器相交 获得对应的对象
//最原始的射线 new Ray(起点,方向);
Ray r1 = new Ray(Vector3.zero,Vector3.forward);
//摄像机发射出的射线
Ray r2 = Camera.main.ScreenPointToRay(Input.mousePosition);射线的检测
//参数1 射线
//参数2 检测的最大距离 超过这个距离不检测
//参数3 检测指定的层级
//参数4 是否忽略触发器
//返回值bool 是否碰撞到了对象
Physics.Raycast(r2,100,1<<LayerMask.NameToLayer("Monster"),QueryTriggerInteraction.UseGlobal);
//重载 把射线变成了 射线的起点和方向
Physics.Raycast(Vector3.zero,Vector3.forward,100,1<<LayerMask.NameToLayer("Monster"),QueryTriggerInteraction.UseGlobal);获取与射线相交的物体信息
RaycastHit是一个结构体 值类型的 Unity会通过out关键字 在函数内部处理后 得到碰撞数据返回到该参数中
RaycastHit hitInfo;
//Physics.Raycast(射线,out hitInfo,距离,层级,是否检测触发器)
bool isTrigger = Physics.Raycast(r2,out hitInfo,100,1<<LayerMask.NameToLayer("Monster"),QueryTriggerInteraction.UseGlobal);
if(isTrigger){
//得到碰撞器信息
print(hitInfo.collider.gameObject.name);
//碰撞到的店
print(hitInfo.point);
//法线信息
print(hitInfo.normal);
//得到碰撞到对象 距离自己的距离
print(hitInfo.distance);
}获取相交的多个物体
RaycastHit[] hitInfos = Physics.RaycastAll(r2,100,1<<LayerMask.NameToLayer("Monster"),QueryTriggerInteraction.UseGlobal);
//返回碰撞数量 然后通过out得到hits
RaycastHit[] hits;
int a = Physics.RaycastNonAlloc(r2,out hits ,100,1<<LayerMask.NameToLayer("Monster"),QueryTriggerInteraction.UseGlobal);