Unity C#如何用Async实现等待NavMeshAgent到达目标点的功能
Unity多角色任务移动功能问题修复方案
核心错误原因
- 同步死循环卡主线程:
GoTo方法中的while (agent.hasPath) ;是空同步循环,Unity所有逻辑都运行在主线程,你占着主线程不放,NavMeshAgent永远没机会更新路径状态、计算位置,agent.hasPath永远不会变成false,直接卡死导致Unity崩溃。 - Task实现完全错误:
GoTo虽然返回了Task类型,但整个逻辑都是同步执行,最后返回的Task.CompletedTask是已完成状态,await完全没有起到异步等待的作用,逻辑和同步调用没有区别。 async void存在隐患:ExecuteTask用async void声明,运行中抛出的异常无法被正常捕获,容易出现隐形逻辑错误或崩溃。
修复方案
核心思路是用非阻塞的方式等待角色到达目标点,将协程和TaskCompletionSource结合,把到达状态转换为Task的完成状态,让await可以正常工作:
1. 重写GoTo方法
private Task GoTo(GameObject building) { TaskCompletionSource<bool> arriveTcs = new TaskCompletionSource<bool>(); CurrentLocation = "World"; Debug.Log($"Pawn.cs > {FullName}: Going to {building.name}"); Vector3 target = building.GetComponent<Building>().EntryNode.transform.position; NavMeshAgent agent = GetComponent<NavMeshAgent>(); agent.destination = target; // 用协程非阻塞等待到达,不占主线程 StartCoroutine(WaitForArriveCoroutine(agent, building.name, arriveTcs)); return arriveTcs.Task; } private IEnumerator WaitForArriveCoroutine(NavMeshAgent agent, string buildingName, TaskCompletionSource<bool> tcs) { // 等待路径计算完成 yield return new WaitUntil(() => agent.hasPath); // 等待到达目标点(判断剩余距离小于停止距离且没有待计算路径) yield return new WaitUntil(() => agent.remainingDistance <= agent.stoppingDistance && !agent.pathPending); Debug.Log($"Pawn.cs > {FullName} has arrived at {buildingName}"); CurrentLocation = buildingName; // 标记Task完成,await会继续执行后续逻辑 tcs.SetResult(true); }
2. 修改ExecuteTask声明
把async void改为async Task,方便后续异常处理和状态追踪:
public async Task ExecuteTask(string task) { Debug.Log($"{this.FullName} is doing {task}"); switch (task) { case "Sleep": case "Home": if (this.CurrentLocation != this.Home.name) await GoTo(Home); break; case "Work": if (this.CurrentLocation != this.Work.name) await GoTo(Work); break; default: Debug.LogWarning($"Pawn.cs > {this.FullName} caught out of bound task: {task}"); break; } }
补充说明
- 如果你的项目引入了UniTask插件,可以不用写协程,直接用
await UniTask.WaitUntil(() => 条件)的写法,代码会更简洁。 - 可以在等待到达的逻辑里加超时判断,避免角色被永久阻挡导致任务一直卡住。
内容的提问来源于stack exchange,提问作者Riptide00
相关产品推荐
相关产品推荐

