You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中如何实现带偏移量与角度的Ray.GetPoint()方法?

自定义Unity Ray的带偏移和角度的GetPoint方法

嘿,作为Unity新手能想到扩展Ray的功能真的很棒!你想要的这种GetPoint(distance, padding, angle)方法完全可以自己实现,我来一步步给你拆解怎么做。

核心思路

首先明确需求:我们需要先获取射线上距离起点distance的基础点,然后在垂直于射线方向的平面上,以这个基础点为中心,偏移padding单位的距离,偏移方向由angle参数决定(0°对应某个基准方向,90°则旋转90度)。

实现的关键是找到两个垂直于射线方向的正交向量,用来定义这个偏移平面的坐标系,再通过角度计算出具体的偏移方向。

完整代码实现

我们可以给Ray写一个扩展方法,这样调用起来就和原生的GetPoint一样方便:

using UnityEngine;

public static class RayExtensions
{
    /// <summary>
    /// 获取射线上指定距离的点,并在垂直于射线的平面上偏移指定距离和角度
    /// </summary>
    /// <param name="ray">目标射线</param>
    /// <param name="distance">沿射线的距离</param>
    /// <param name="padding">偏离射线的距离(垂直方向)</param>
    /// <param name="angle">偏移的角度(0°为基准方向,顺时针/逆时针旋转)</param>
    /// <returns>偏移后的目标点</returns>
    public static Vector3 GetPointWithOffset(this Ray ray, float distance, float padding, float angle)
    {
        // 1. 获取射线上的基础点c
        Vector3 basePoint = ray.GetPoint(distance);

        // 2. 找到第一个垂直于射线方向的基准向量
        Vector3 perpendicular1;
        // 避免射线方向和Vector3.up平行的情况(比如射线向上/向下)
        if (Mathf.Abs(Vector3.Dot(ray.direction, Vector3.up)) > 0.99f)
        {
            perpendicular1 = Vector3.Cross(ray.direction, Vector3.right).normalized;
        }
        else
        {
            perpendicular1 = Vector3.Cross(ray.direction, Vector3.up).normalized;
        }

        // 3. 找到第二个垂直于射线和perpendicular1的向量(构成平面坐标系)
        Vector3 perpendicular2 = Vector3.Cross(ray.direction, perpendicular1).normalized;

        // 4. 根据角度计算偏移方向
        float radian = angle * Mathf.Deg2Rad;
        Vector3 offsetDirection = Mathf.Cos(radian) * perpendicular1 + Mathf.Sin(radian) * perpendicular2;

        // 5. 计算最终偏移后的点
        return basePoint + offsetDirection * padding;
    }
}

参数说明与示例

  • distance:和原生Ray.GetPoint(distance)一样,是沿射线起点到基础点的距离,比如你说的3就是距离起点3单位的点c。
  • padding:偏离射线的垂直距离,比如2就是从点c向垂直方向移动2单位。
  • angle:偏移方向的角度,0°对应我们计算的perpendicular1方向,90°则对应perpendicular2方向(也就是你说的“后方/上方”,具体方向取决于射线朝向)。

举个你提到的例子:

  • 调用ray.GetPointWithOffset(3, 2, 0):返回点c沿perpendicular1方向偏移2单位的点d。
  • 调用ray.GetPointWithOffset(3, 2, 90):返回点c沿perpendicular2方向偏移2单位的点d。

注意事项

  • 角度的正负:如果想要顺时针旋转,角度用负值即可,比如-90°就是逆时针转90度的反方向。
  • 当射线方向接近垂直(向上/向下)时,代码会自动切换基准向量,避免计算出零向量导致偏移失效。

内容的提问来源于stack exchange,提问作者Fredrik Johansson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:12:46