前言
最近刷到b站up主山长操作库的内容,感觉很有意思,于是就简单整理了一下。注意本文的实现思路完全是按这位up整理的,这里就先放记录在这里,后续如果实际项目有用的到再深入研究。
设置好LineRenderer线组件配置,用于绘制寻路轨迹
代码
新增代码控制寻路轨迹显示
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AI; public class NavPathLineRenderer : MonoBehaviour { [SerializeField] private Transform player; // 玩家的Transform [SerializeField] private Transform target; // 目标的Transform [SerializeField] private LineRenderer line; // 用于绘制路径的LineRenderer组件 [SerializeField] private float pathHeightOffset = 0.3f; // 绘制路径时的垂直偏移量(在地面上方) [SerializeField] private int quality = 10; // 每个路径段的分段数 [SerializeField] private float maxHeight = 10; // 射线最大高度 [SerializeField] private float drawUpdateSpeed = 0.2f; // 路径绘制更新速度 private Coroutine drawCoroutine; // 用于管理路径绘制的协程引用 private void Start() { // 在开始之前停止任何现有的协程 if (drawCoroutine != null) { StopCoroutine(drawCoroutine); } drawCoroutine = StartCoroutine(DrawNavMeshLine()); } // 协程:持续绘制NavMesh路径 private IEnumerator DrawNavMeshLine() { WaitForSeconds wait = new WaitForSeconds(drawUpdateSpeed); // 等待时间间隔 NavMeshPath path = new NavMeshPath(); // 存储计算路径的NavMeshPath对象 // 只要目标不为空,就持续绘制路径 while (target != null) { // 从玩家位置到目标位置计算路径 if (NavMesh.CalculatePath(player.position, target.position, NavMesh.AllAreas, path)) { // 平滑并绘制路径线条 List<Vector3> newPath = new List<Vector3>(); // 存储平滑后的路径点 for (int i = 0; i < path.corners.Length - 1; i++) { Vector3 currentPoint = path.corners[i] + Vector3.up * maxHeight; // 当前路径段起始点 Vector3 nextPoint = path.corners[i + 1] + Vector3.up * maxHeight; // 下一个路径段起始点 // 细分路径段并向下射线,寻找有效的地面点 for (int j = 0; j < quality; j++) { Vector3 calPoint = Vector3.Lerp(currentPoint, nextPoint, (1f / quality) * j); // 计算插值点 RaycastHit hit; // 射线向下,寻找地面点 if (Physics.Raycast(calPoint, Vector3.down, out hit, Mathf.Infinity, 1 << LayerMask.NameToLayer("Ground"))) { newPath.Add(hit.point); // 将有效的地面点添加到平滑路径中 } } } newPath.Add(target.position); // 将最终目标位置添加到路径中 // 设置LineRenderer的位置数量和位置 line.positionCount = newPath.Count; for (int i = 0; i < newPath.Count; i++) { // 每个位置设置在地面上方的偏移量处 line.SetPosition(i, newPath[newPath.Count - 1 - i] + Vector3.up * pathHeightOffset); } // 设置玩家的NavMeshAgent路径为计算出的路径 player.GetComponent<NavMeshAgent>().SetPath(path); } yield return wait; // 等待下一次更新 } } }
挂载代码,配置参数
烘培导航网格
设置地面图层
设置不同地面的优先级,区分不同表面
烘培寻路网格
运行效果