【Unity API】射线相关:Ray Raycast

写在前面

【Unity API】系列!记录实现效果一路上遇到的Unity API,仅作个人学习记录。


在Unity里写工具时,总有场景需要用到两点发出射线求交的函数,Unity提供了一些API方便我们使用!例如最近在实现一个光晕效果的工具:

  • 需要根据光源位置和相机参数确定光源方向
  • 射线求交判断遮挡

脚本里就用到了

  • UnityEngine.Ray
  • Physics.Raycast

1 Ray

官方手册:UnityEngine.Ray - Unity 脚本 API

关于射线的是一整个struct,首先是通过发出点origin+射线方向确定一个Struct Ray:

    //
    // 摘要:
    //     Representation of rays.
    public struct Ray : IFormattable
    {
        //
        // 摘要:
        //     Creates a ray starting at origin along direction.
        //
        // 参数:
        //   origin:
        //
        //   direction:
        public Ray(Vector3 origin, Vector3 direction);

        //
        // 摘要:
        //     The origin point of the ray.
        public Vector3 origin { get; set; }
        //
        // 摘要:
        //     The direction of the ray.
        public Vector3 direction { get; set; }

        //
        // 摘要:
        //     Returns a point at distance units along the ray.
        //
        // 参数:
        //   distance:
        public Vector3 GetPoint(float distance);
        //
        // 摘要:
        //     Returns a formatted string for this ray.
        //
        // 参数:
        //   format:
        //     A numeric format string.
        //
        //   formatProvider:
        //     An object that specifies culture-specific formatting.
        public override string ToString();
        //
        // 摘要:
        //     Returns a formatted string for this ray.
        //
        // 参数:
        //   format:
        //     A numeric format string.
        //
        //   formatProvider:
        //     An object that specifies culture-specific formatting.
        public string ToString(string format);
        //
        // 摘要:
        //     Returns a formatted string for this ray.
        //
        // 参数:
        //   format:
        //     A numeric format string.
        //
        //   formatProvider:
        //     An object that specifies culture-specific formatting.
        public string ToString(string format, IFormatProvider formatProvider);
    }

 [Unity]教程------Ray(射线)的基本使用这个文章详细写了怎么通过射线检测碰撞物体。

再看看实现光晕,首先需要计算光晕方向

Ray ray = new Ray(m_GameCamera.transform.position, position);

然后Raycast(后面会提到)进行射线遮挡判断

if(Physics.Raycast(ray, out hit))
{
    ...
}

2 Raycast

官方手册:Physics-Raycast - Unity 脚本 API

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

文档中对这个API的描述为:向场景中的所有碰撞体投射一条射线,该射线起点为 /origin/,朝向 /direction/,长度为 /maxDistance/

返回的值:返回的是一个bool变量,如果射线检测道碰撞机就返回true,否则返回false

        RaycastHit hit;
        // Does the ray intersect any objects excluding the player layer
        if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out hit, Mathf.Infinity, layerMask))
        {
            Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.forward) * hit.distance, Color.yellow);
            Debug.Log("Did Hit");
        }
        else
        {
            Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.forward) * 1000, Color.white);
            Debug.Log("Did not Hit");
        }

 RaycastHit

    [NativeHeaderAttribute("Modules/Physics/RaycastHit.h")]
    [NativeHeaderAttribute("Runtime/Interfaces/IRaycast.h")]
    [NativeHeaderAttribute("PhysicsScriptingClasses.h")]
    [UsedByNativeCodeAttribute]
    public struct RaycastHit
    {
        //
        // 摘要:
        //     The Collider that was hit.
        public Collider collider { get; }
        //
        // 摘要:
        //     Instance ID of the Collider that was hit.
        public int colliderInstanceID { get; }
        //
        // 摘要:
        //     The impact point in world space where the ray hit the collider.
        public Vector3 point { get; set; }
        //
        // 摘要:
        //     The normal of the surface the ray hit.
        public Vector3 normal { get; set; }
        //
        // 摘要:
        //     The barycentric coordinate of the triangle we hit.
        public Vector3 barycentricCoordinate { get; set; }
        //
        // 摘要:
        //     The distance from the ray's origin to the impact point.
        public float distance { get; set; }
        //
        // 摘要:
        //     The index of the triangle that was hit.
        public int triangleIndex { get; }
        //
        // 摘要:
        //     The uv texture coordinate at the collision location.
        public Vector2 textureCoord { get; }
        //
        // 摘要:
        //     The secondary uv texture coordinate at the impact point.
        public Vector2 textureCoord2 { get; }
        //
        // 摘要:
        //     The Transform of the rigidbody or collider that was hit.
        public Transform transform { get; }
        //
        // 摘要:
        //     The Rigidbody of the collider that was hit. If the collider is not attached to
        //     a rigidbody then it is null.
        public Rigidbody rigidbody { get; }
        //
        // 摘要:
        //     The ArticulationBody of the collider that was hit. If the collider is not attached
        //     to an articulation body then it is null.
        public ArticulationBody articulationBody { get; }
        //
        // 摘要:
        //     The uv lightmap coordinate at the impact point.
        public Vector2 lightmapCoord { get; }
        [EditorBrowsable(EditorBrowsableState.Never)]
        [Obsolete("Use textureCoord2 instead. (UnityUpgradable) -> textureCoord2")]
        public Vector2 textureCoord1 { get; }
    }

其中,RaycastHit也是一个围绕Raycast定义的结构体,感觉每个定义了Raycast的脚本都会定义个RaycastHit再给他out出来(即使后面不用到),感觉应该是个固定的、不能更改的写法吧。

Unity学习之Physic.Raycast(射线检测)个人理解分享这篇博客演示了碰撞检测的应用。

猜你喜欢

转载自blog.csdn.net/qq_41835314/article/details/129925453