为什么我的Unity会被看似最终条件成立的while语句卡住?
问题原因分析
核心问题是代码存在同步死循环+浮点数精度判断错误,导致Unity主线程被永久阻塞:
- 生命周期执行逻辑错误:Unity的
Start方法属于单帧执行的生命周期函数,所有逻辑都会在当前帧完成,不会切换到下一帧。你在Start里写了死循环逻辑,会一直占用主线程资源,导致渲染、物理更新、输入响应等后续逻辑完全无法执行,表现就是程序直接卡死。 - 浮点数等值判断逻辑错误:
Vector2的坐标是float浮点类型,你每次移动的步长是moveSpeed * Time.deltaTime,受浮点精度限制,location几乎不可能和目标点t的数值完全相等,location != t的判断会永远返回true,循环永远不会退出。
修复建议
- 替换同步循环为协程/帧更新逻辑:不要在同步生命周期里写阻塞逻辑,把路径移动逻辑放到
FixedUpdate里逐帧执行,或者用协程逐帧处理。 - 替换等值判断为阈值判断:不要用
==/!=判断浮点坐标是否相等,换成判断两点距离小于可接受的极小阈值即可,示例判断逻辑:if (Vector2.Distance(location, target) < 0.05f) 即可认为到达目标点。
参考修改后的协程实现:
// 原来Start里调用MovePath的代码替换为 StartCoroutine(MovePath(路径数组)); private IEnumerator MovePath(Vector2[] path) { foreach (var t in path) { while (Vector2.Distance(location, t) > 0.05f) { Move(t); // 等待下一帧再继续执行,不会阻塞主线程 yield return null; } // 到达目标点后强制对齐坐标,消除精度误差 location = t; rb.MovePosition(t); } } private void Move(Vector2 target) { var position = (Vector2) transform.position; var direction= target - position; direction.Normalize(); transform.right = (target - position) * -1; var endPosition = position + (direction * moveSpeed * Time.fixedDeltaTime); rb.MovePosition(endPosition); location = endPosition; }
内容的提问来源于stack exchange,提问作者OJS05
相关产品推荐
相关产品推荐

