⚠️:本文为上篇文章:http://t.csdn.cn/VQy63中对射线检测编程的补充
一、射线碰撞信息
射线检测有着丰富的碰撞信息,如可以获取到碰撞点坐标、被碰撞物体的所有信息,甚至可以获取到碰撞点的发现。这些信息都被保存在RaycastHit结构体中。
以下几个Raycast()函数的重载可以获取到碰撞信息
bool Raycast(Vector3 origin,Vector3 direction,out RaycastHit hitInfo,float maxDistance);
bool Raycast(Vector3 origin,Vector3 direction,out RaycastHit hitInfo,float maxDistance,int layerMask);
bool Raycast(Ray ray,out RaycastHit hitInfo,float maxDistance,int layerMask);
综合用法演示如下
//声明变量,用于保存信息 RaycastHit hitInfo; //发射射线,起点是当前物体的位置,方向时世界前方 if(Physiics.Raycast(transform.position,Vector3.forward,out hitInfo)) { //如果碰到物体,会运行到这里 //获取碰撞点的世界坐标 Vector3 point=itInfo.point; //获取对方的碰撞体组件 Collider coll=hitInfo.collider; //获取对方的Transform组件 Transform trans=hitInfo.transform; //获取对方的物体名称 string name=coll.gameObject.namel //获取碰撞点的法线向量 Vector3 normal=hitInfo.normal;
二、其他形状的射线
射线不仅可以有长度,还可以有粗细和形状。如球形、盒子、和胶囊体射线。
与发射射线类似,各种形状的射线也有很多种函数重载,以下是几种常用的重载形式
//球形射线
bool SphereCast(Ray ray,float radius);
bool SphereCast(Ray ray,float radius,out RaycastHit hitInfo);
//盒子射线
bool BoxCast(Vector3 center,Vector3 halfExtents,Vector3 direction);
bool BoxCast(Vector3 center,Vector3 halfExtents,Vector3 direction,out RaycastHit hitInfo,Quaternion orientation);
//胶囊体射线
bool CapsuleCast(Vector3 point1,Vector3 point2,float radius,Vector3 direction);
bool CapsuleCast(Vector3 point1,Vector3 point2,float radius,Vector3 direction,out RaycastHit hitInfo,float maxDistance);
可以看出,它们都与直线型射线差不多,只是多了半径、体对角线、朝向之类的。
三、穿过多个物体的射线
有时候需要射线在遇到第一个物体时不停止,继续前进,穿过多个物体。
Physics.RaycastAll()函数可以获取到射线沿途碰撞到的所有碰撞信息,返回值为RaycastHit数组。举例如下
RaycastHit[] RaycastAll(Ray ray,float maxDistance);
RaycastHit[] RaycastAll(Vector3 origin,Vector3 direction,float maxDirection);
RaycastHit[] RaycastAll(Ray ray,float maxDistance,int layerMask);
RaycastHit[] RaycastAll(Ray ray);
同样,也有SpherecastAll、BoxcastAll和CapsulecastAll。
四、区域覆盖型射线(Overlap)
有时需要检测一个空间范围,物理系统也提供了这类函数,均以Physics.Overlap开头,举例如下
Collider[] OverlapBox(Vector3 center,Vector3 halfExtents,Quaternion orientation,int layerMask);
Collider[] OverlapCapsule(Vector3 point0,Vector3 point1,float radius,int layerMask);
Collider[] OverlapSphere(Vector3 position,float radius,int layerMask);
以球形检测OverSphere为例,调用函数时,会返回原点为position、半径为radius的球体内满足一定条件的碰撞体集合(以数组表示),而这球体称为"3D相交球"。
五、射线调试技巧
看到这里我们会发现,射线检测函数类型多、参数多、重载多,很容易把自己绕懵。这里介绍一个提高编程效率的方法:使用Debug.DrawLine()函数和Debug.DrawRay()函数。将看不见的射线以可视化的形式表现出来,方便查看参数是否正确。
Debug.DrawLine(),Debug.DrawRay()函数的常用形式如下
void DrawLine(Vector3 start,Vector3 end,Color color);
void DrawLine(Vector3 start,Vector3 end,Color color,float duration);
void DrawRay(Vector3 start,Vector3 dir,Color color);
void DrawRay(Vector3 start,Vector3 dir,Color color,float duration);
Debug.DrawLine()函数通过制定线段的起点、终点和颜色(默认为红色),绘制一条线段
Debug.DrawRay则是通过制定起点和方向向量,绘制一条射线。
这里需要注意的是,DrawLine第二个参数是终点坐标,而不是一般的方向向量。
以上函数的最后一个参数,duration,可以省略。省略后这条参考线只出现一帧。如果在代码中每帧都会直线条,则可以省略。如果只出现一帧且看不清,则可以听写一个较大的持续时间(单位为秒),让射线停留在屏幕上以便查看。