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

Unity 3D中如何让Line Renderer贴合地面呈现平面效果

3D导航引导线贴合地面解决方案

问题背景

我做了一个3D地图模拟项目,用AI Navigation实现导航到选中对象的功能,并用LineRenderer绘制目标引导线。当前引导线未贴合地面,呈现浮空状态,需要调整使其贴合地面平面。

问题代码

[SerializeField]
private Collectable Prefab;
[SerializeField]
private Transform Player;
[SerializeField]
private LineRenderer Path;
[SerializeField]
private float PathHeightOffset = 1f;
[SerializeField]
private float SpawnHeightOffset = 1f;
[SerializeField]
private float PathUpdateSpeed = 0.25f;

private Collectable ActiveInstance;
private UnityEngine.AI.NavMeshTriangulation Triangulation;
private Coroutine DrawPathCoroutine;

private void Awake()
{
    Triangulation = UnityEngine.AI.NavMesh.CalculateTriangulation();
}

private void Start()
{
    SpawnNewObject();
}

public void SpawnNewObject()
{
    ActiveInstance = Instantiate(Prefab,
        Triangulation.vertices[Random.Range(0, Triangulation.vertices.Length)] + Vector3.up * SpawnHeightOffset,
        Quaternion.Euler(90, 0, 0)
    );
    ActiveInstance.Spawner = this;

    if (DrawPathCoroutine != null)
    {
        StopCoroutine(DrawPathCoroutine);
    }

    DrawPathCoroutine = StartCoroutine(DrawPathToCollectable());
}

private IEnumerator DrawPathToCollectable()
{
    WaitForSeconds Wait = new WaitForSeconds(PathUpdateSpeed);
    UnityEngine.AI.NavMeshPath path = new UnityEngine.AI.NavMeshPath();

    while (ActiveInstance != null)
    {
        if (UnityEngine.AI.NavMesh.CalculatePath(Player.position, new Vector3(55.6f, 32.04f, 17.37f), UnityEngine.AI.NavMesh.AllAreas, path))
        {
            Path.positionCount = path.corners.Length;

            for (int i = 0; i < path.corners.Length; i++)
            {
                Path.SetPosition(i, path.corners[i] + Vector3.up * PathHeightOffset);
            }
        }
        else
        {
            Debug.LogError($"无法在NavMesh上计算从{Player.position}到{ActiveInstance.transform.position}的路径!");
        }

        yield return Wait;
    }
}

当前效果

引导线未贴合地面的效果

解决方案

核心问题分析

  1. 硬编码了目标位置,导致路径不是指向生成的收集物
  2. 给所有路径点加了过大的固定高度偏移(1f),导致引导线浮空

修改后的代码

重点调整DrawPathToCollectable方法:

private IEnumerator DrawPathToCollectable()
{
    WaitForSeconds Wait = new WaitForSeconds(PathUpdateSpeed);
    UnityEngine.AI.NavMeshPath path = new UnityEngine.AI.NavMeshPath();

    while (ActiveInstance != null)
    {
        // 替换硬编码坐标为当前收集物的位置
        if (UnityEngine.AI.NavMesh.CalculatePath(Player.position, ActiveInstance.transform.position, UnityEngine.AI.NavMesh.AllAreas, path))
        {
            Path.positionCount = path.corners.Length;

            for (int i = 0; i < path.corners.Length; i++)
            {
                // 使用NavMesh路径点的原生Y值,仅加微小偏移避免穿模
                Vector3 groundPosition = path.corners[i];
                groundPosition.y += Mathf.Clamp(PathHeightOffset, 0.1f, 0.5f);
                Path.SetPosition(i, groundPosition);
            }
        }
        else
        {
            Debug.LogError($"无法在NavMesh上计算从{Player.position}到{ActiveInstance.transform.position}的路径!");
        }

        yield return Wait;
    }
}

额外调整建议

  • 将PathHeightOffset的默认值改为0.2f左右,避免引导线过高
  • 若地面有复杂起伏,可添加射线检测进一步验证地面高度:
// 在循环内添加射线检测获取精准地面高度
if (Physics.Raycast(groundPosition + Vector3.up * 2f, Vector3.down, out RaycastHit hit, 5f, LayerMask.GetMask("Ground")))
{
    groundPosition.y = hit.point.y + 0.1f;
}

内容的提问来源于stack exchange,提问作者Cyrille Con Morales

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 05:55:15