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; } }
当前效果

解决方案
核心问题分析
- 硬编码了目标位置,导致路径不是指向生成的收集物
- 给所有路径点加了过大的固定高度偏移(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
相关产品推荐
相关产品推荐

