unity中的射线碰撞检测

在Unity中,射线碰撞检测是一种常用的技术,通常用于确定射线与场景中的物体是否相交,并获取相交点的信息。

一.射线碰撞检测的基本步骤

1.创建射线:

使用Ray类或RaycastHit结构体创建射线。Ray表示射线的起点和方向,而RaycastHit用于存储射线与物体相交的信息,如相交点、法线等。

Ray ray = new Ray(origin, direction);
RaycastHit hit;

2.发射射线:

使用Physics.Raycast函数发射射线,并检查是否与物体相交。该函数会返回一个布尔值,表示射线是否击中物体。

if (Physics.Raycast(ray, out hit, maxDistance))
{
    // 射线击中物体
    // hit.point 是相交点的坐标
    // hit.collider 是相交物体的碰撞器
    // 其他信息如 hit.normal 可以获取相交点的法线等
}

3.Layer过滤:

可以使用layerMask参数来限制射线只与特定层的物体进行碰撞检测。这对于只关心特定类型的物体很有用。

int layerMask = 1 << LayerMask.NameToLayer("YourLayerName");
if (Physics.Raycast(ray, out hit, maxDistance, layerMask))
{
    // 只与指定层的物体相交
}

二.Physics.Raycast函数有多个重载类型

1.基本的Ray和最大射线支持的距离maxDistance

public static bool Raycast(Ray ray, out RaycastHit hitInfo, float maxDistance = Mathf.Infinity);
//Mathf.Infinity表示无穷大

2.Layer过滤:

使用layerMask参数来限制射线只与特定层的物体进行碰撞检测。

public static bool Raycast(Ray ray, out RaycastHit hitInfo, float maxDistance = Mathf.Infinity, int layerMask = DefaultRaycastLayers);

3.指定最小和最大碰撞体积大小:

使用minSizemaxSize参数,可以指定物体的最小和最大碰撞体积大小。

public static bool Raycast(Ray ray, out RaycastHit hitInfo, float maxDistance = Mathf.Infinity, int layerMask = DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal, float minSize = 0.0f, float maxSize = Mathf.Infinity);

这里出现了QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal,下面是对他的解释 

在Unity中,物体可以有两种类型的碰撞器:实体碰撞器(Collider)和触发器(Trigger)。实体碰撞器用于物体之间的物理碰撞,而触发器则用于检测物体是否进入某个区域,但触发器本身不会引起物理碰撞反应。

在进行射线碰撞检测时,有一个参数叫做 QueryTriggerInteraction,它的作用是告诉Unity在检测碰撞时是否要考虑触发器。

  • 如果设置为 QueryTriggerInteraction.UseGlobal,则会根据全局设置(Physics.queriesHitTriggers)来决定是否考虑触发器。
  • 如果设置为 QueryTriggerInteraction.Ignore,则不考虑触发器,即使全局设置允许考虑触发器。
  • 如果设置为 QueryTriggerInteraction.Collide,则始终考虑触发器,即使全局设置不允许考虑触发器。

4.返回所有相交信息:

使用RaycastHit[]数组返回所有相交信息。

public static RaycastHit[] RaycastAll(Ray ray, float maxDistance = Mathf.Infinity, int layerMask = DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal);

5.指定射线起点和方向:

这种重载允许你直接提供射线的起点和方向而不是创建Ray对象。

public static bool Raycast(Vector3 origin, Vector3 direction, out RaycastHit hitInfo, float maxDistance = Mathf.Infinity, int layerMask = DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal);

三.FPS游戏个人用过的方法

 if (Physics.Raycast(muzzle.position, muzzle.forward, out hit, range)) // 判断是否击中物体
        {
            if (hit.rigidbody) // 如果击中的物体有刚体的话
            {
                hit.rigidbody.AddForce(-hit.normal * impactForce); // 对击中的物体沿法线的反方向施加一个力
            }

            Enemy enemy = hit.transform.GetComponent<Enemy>();
            if (enemy)
            {
                enemy.TakeDemage(impactForce / 10);//这里是检测如果是敌人,就造成伤害
                return;
            }
        }

1首先在枪口前方定义一个空对象,用作发射点也就是代码中的muzzle.position.

2调整发生点的正方向,用作射线的方向。

3.hit是定义的RaycastHit,储存相交的物体信息。

4.range是定义的射程。

有帮助,有建议,请评论,还在学习中。

猜你喜欢

转载自blog.csdn.net/zzexcellent27/article/details/134772449