您现在的位置是:首页 >其他 >Unity射线编程详解网站首页其他

Unity射线编程详解

七七喝椰奶 2024-06-14 17:18:59
简介Unity射线编程详解

⚠️:本文为上篇文章: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,可以省略。省略后这条参考线只出现一帧。如果在代码中每帧都会直线条,则可以省略。如果只出现一帧且看不清,则可以听写一个较大的持续时间(单位为秒),让射线停留在屏幕上以便查看。

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。