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

如何根据射线命中数量使用LineRenderer绘制多条线段?

解决Unity中根据射线命中数量绘制多条线段的问题

看起来你已经搭好了射线检测的基础框架,现在要实现的就是根据射线命中的数量,用LineRenderer画出对应条数的线段对吧?我来帮你把这个功能整合到现有代码里:

第一步:调整变量,改用更灵活的LineRenderer集合

原来的myLines数组不太适合动态增减的场景,我们换成List<LineRenderer>来管理所有绘制的线段:

// 替换掉原来的GameObject[] myLines;
List<LineRenderer> lineRenderers = new List<LineRenderer>();

第二步:写一个创建LineRenderer的辅助方法

这个方法可以帮我们快速生成配置好基础属性的线段,不用每次重复写设置代码:

private LineRenderer CreateLineRenderer()
{
    GameObject lineObj = new GameObject($"HitLine_{lineRenderers.Count}");
    LineRenderer lr = lineObj.AddComponent<LineRenderer>();
    
    // 自定义线段的外观,你可以根据需求调整
    lr.startWidth = 0.02f;
    lr.endWidth = 0.02f;
    lr.material = new Material(Shader.Find("Sprites/Default"));
    lr.startColor = Color.cyan;
    lr.endColor = Color.red;
    lr.positionCount = 2; // 线段只需要两个端点
    
    return lr;
}

第三步:整合射线检测与线段绘制逻辑

在Update方法里,先清除上一帧的旧线段,再执行射线检测,最后根据命中结果生成对应数量的线段:

void Update()
{
    // 保留你原来的旋转逻辑,这里不改动
    if (nonstopSpin)
    {
        foreach (GameObject obj in objectsToRotate)
        {
            if (useQuaternion)
            {
                obj.transform.rotation = Quaternion.Euler(obj.transform.rotation.eulerAngles + spinDirection * speed);
            }
            else
            {
                obj.transform.Rotate(spinDirection * speed);
            }
        }
    }

    // 清除上一帧的旧线段
    ClearOldLines();
    // 执行射线检测并绘制新线段
    DrawLinesFromRaycast();
}

private void ClearOldLines()
{
    foreach (var lr in lineRenderers)
    {
        Destroy(lr.gameObject);
    }
    lineRenderers.Clear();
}

private void DrawLinesFromRaycast()
{
    // 生成射线,根据useMouse参数选择不同的射线来源
    if (useMouse)
    {
        ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    }
    else
    {
        ray = new Ray(transform.position, to.position - transform.position);
    }
    
    // 获取所有命中结果
    hits = Physics.RaycastAll(ray);

    // 遍历每个命中点,绘制从射线起点到命中点的线段
    foreach (RaycastHit hitResult in hits)
    {
        LineRenderer newLine = CreateLineRenderer();
        newLine.SetPosition(0, ray.origin);
        newLine.SetPosition(1, hitResult.point);
        lineRenderers.Add(newLine);
    }
}

完整整合后的代码

把上面的内容合并到你的RotateObjects类里,最终代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RotateObjects : MonoBehaviour
{
    public GameObject[] objectsToRotate;
    public Transform to;
    public float speed = 0.1f;
    public Vector3 spinDirection;
    public bool useMouse = false;
    public bool useQuaternion = false;
    public bool nonstopSpin = false;

    Ray ray;
    RaycastHit hit;
    RaycastHit[] hits;
    List<LineRenderer> lineRenderers = new List<LineRenderer>();

    void Start()
    {
        // 保留你原来的初始化逻辑
    }

    void Update()
    {
        // 原有旋转逻辑
        if (nonstopSpin)
        {
            foreach (GameObject obj in objectsToRotate)
            {
                if (useQuaternion)
                {
                    obj.transform.rotation = Quaternion.Euler(obj.transform.rotation.eulerAngles + spinDirection * speed);
                }
                else
                {
                    obj.transform.Rotate(spinDirection * speed);
                }
            }
        }

        // 线段绘制逻辑
        ClearOldLines();
        DrawLinesFromRaycast();
    }

    private void ClearOldLines()
    {
        foreach (var lr in lineRenderers)
        {
            Destroy(lr.gameObject);
        }
        lineRenderers.Clear();
    }

    private void DrawLinesFromRaycast()
    {
        if (useMouse)
        {
            ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        }
        else
        {
            ray = new Ray(transform.position, to.position - transform.position);
        }
        
        hits = Physics.RaycastAll(ray);

        foreach (RaycastHit hitResult in hits)
        {
            LineRenderer newLine = CreateLineRenderer();
            newLine.SetPosition(0, ray.origin);
            newLine.SetPosition(1, hitResult.point);
            lineRenderers.Add(newLine);
        }
    }

    private LineRenderer CreateLineRenderer()
    {
        GameObject lineObj = new GameObject($"HitLine_{lineRenderers.Count}");
        LineRenderer lr = lineObj.AddComponent<LineRenderer>();
        
        lr.startWidth = 0.02f;
        lr.endWidth = 0.02f;
        lr.material = new Material(Shader.Find("Sprites/Default"));
        lr.startColor = Color.cyan;
        lr.endColor = Color.red;
        lr.positionCount = 2;
        
        return lr;
    }
}

几个实用小提示

  • 如果你的场景需要频繁刷新线段,建议用对象池复用LineRenderer,避免频繁创建销毁带来的性能损耗。
  • 确保被射线检测的物体都添加了Collider组件,否则射线会直接穿过,不会产生命中结果。
  • 可以根据需求调整LineRenderer的Shader,比如用URP的Lit Shader来获得更好的光照效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:10:37