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);