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

Unity沿线段放置射线问题:射线无法对齐端点

线段上均匀分布射线的实现修正

问题描述

需要在起点(绿色点(2, 0, 2))和终点(红色点(2, 0, -2),两点间距4)的线段上放置数量可调的射线,当前实现无法满足需求:

  • 2条射线时:无法让射线分别对齐起点和终点,新增射线需均匀分布在两点间;
  • 3条射线时:终点位置未被利用,缺少终点处的射线;
  • 5条射线时:首尾射线无法对齐起点和终点,中间射线分布不均。

当前代码问题分析

  1. 方向依赖固定的Vector3.back,若后续起点终点连线方向变化,会直接导致位置计算错误;
  2. 用dist / sideRaysAmount * i计算偏移时,最后一条射线的偏移量为dist*(sideRaysAmount-1)/sideRaysAmount,永远到不了终点,导致终点位置被浪费。

解决方案

使用向量插值的方式计算射线位置,直接基于起点和终点的连线实现均匀分布,代码更健壮且满足需求:

public class VehicleAroundCast : MonoBehaviour
{
    [SerializeField] private int sideRaysAmount;
    [SerializeField] private Vector3 offset;

    private void Update()
    {
        // 计算起点和终点的世界位置
        Vector3 startRayPos = transform.position + Vector3.left * offset.x + Vector3.forward * offset.z;
        Vector3 endRayPos = transform.position + Vector3.left * offset.x + Vector3.back * offset.z;

        // 绘制起点和终点的参考射线
        Debug.DrawRay(startRayPos, Vector3.down, Color.green);
        Debug.DrawRay(endRayPos, Vector3.down, Color.red);

        // 处理射线数量为0的边界情况
        if (sideRaysAmount <= 0) return;

        // 遍历生成每条射线
        for (int i = 0; i < sideRaysAmount; i++)
        {
            // 计算当前射线在起点-终点线段上的比例,处理单射线的特殊情况
            float t = sideRaysAmount == 1 ? 0f : (float)i / (sideRaysAmount - 1);
            // 插值计算射线位置
            Vector3 rayPos = Vector3.Lerp(startRayPos, endRayPos, t);
            
            Debug.DrawRay(rayPos, Vector3.down);
        }
    }
}

关键修正点

  1. 向量插值Vector3.Lerp:通过比例t(0对应起点,1对应终点)直接计算射线位置,确保首尾射线严格对齐起点和终点;
  2. 单射线特殊处理:当射线数量为1时,直接将射线放在起点位置;
  3. 移除硬编码方向:不再依赖固定的Vector3.back,即使后续修改起点终点的相对方向,依然能正确分布射线。

效果验证

  • 2条射线:分别对齐起点和终点;
  • 3条射线:起点、中点、终点各一条;
  • 5条射线:起点、1/4线段处、中点、3/4线段处、终点各一条,完全符合需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 08:59:13