【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(射线检测)个人理解分享这篇博客演示了碰撞检测的应用。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

九九345

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值