Unity协程中Lerp过渡动画切换物体后未完成的问题求助
Unity协程中Lerp过渡动画切换物体后未完成的问题求助
看起来你遇到的这个问题其实很典型,我先帮你梳理下最可能的核心原因,再给你对应的解决方案和优化建议:
最可能的问题根源:协程被意外终止
协程的运行是依附于它所在的MonoBehaviour组件的,而这个组件又挂在某个GameObject上。如果你的这段协程所在的脚本是挂在overworldObject上面的,那么当你执行overworldObject.SetActive(false)时,这个MonoBehaviour会被直接禁用,正在运行的协程也会立刻终止——这就完美解释了为什么切换物体激活状态后,动画卡在中间,最后的transition.position = endPos;也没执行:因为协程已经停了,根本走不到那一步。
而你注释掉if语句后,没有禁用overworldObject,协程所在的脚本一直活跃,所以动画能完整跑完,这也和你的测试结果完全吻合。
解决方案
把承载这个协程的脚本,移动到一个全程保持激活的GameObject上,比如专门的GameManager、UIManager这类全局管理对象,这些对象在游戏的整个流程中都不会被禁用。这样即使overworldObject被关闭,协程所在的脚本依然处于活跃状态,协程就能完整执行完整个过渡动画。
额外的优化建议
除了解决核心问题,你还可以优化协程的逻辑,让它更健壮:
- 用标志位避免重复判断:原来的if条件依赖
overworldObject.activeSelf,可以换成一个局部标志位,确保切换逻辑只执行一次,避免不必要的状态判断:public IEnumerator EnterRaftMenu() { Vector3 startPos = new Vector3(-32f, 0f, 0f); Vector3 endPos = new Vector3(32f, 0f, 0f); float duration = 0.5f; float elapsed = 0f; bool hasSwitchedToMenu = false; // 新增标志位,确保切换逻辑只执行一次 transition.position = startPos; while (elapsed < duration) { float progress = elapsed / duration; transition.position = Vector3.Lerp(startPos, endPos, progress); // 只在第一次达到进度0.5时执行界面切换 if (!hasSwitchedToMenu && progress >= 0.5f) { overworldObject.SetActive(false); raftMenuObject.SetActive(true); hasSwitchedToMenu = true; } elapsed += Time.deltaTime; yield return null; } transition.position = endPos; } - 解耦动画进度与视觉时机:如果你担心
elapsed/duration >=0.5f和实际“覆盖屏幕”的视觉时机不匹配,可以提前计算过渡的中间位置,直接判断物体是否到达该位置:
不过对于线性Lerp来说,进度0.5和中间位置是完全对应的,这个调整可以根据你的实际需求选择。Vector3 midPos = (startPos + endPos) / 2f; // 在循环中替换判断逻辑 if (!hasSwitchedToMenu && Vector3.Distance(transition.position, midPos) < 0.1f) { // 执行切换操作 }
其他排查点(如果上述方案不生效)
如果确认脚本不在overworldObject上,那可以额外检查:
- 有没有其他脚本在切换到raftMenu后,修改了
transition的position属性? raftMenuObject激活后,是否有层级遮挡或者其他逻辑影响了transition的显示状态?
不过根据你的测试结果,核心问题大概率就是协程被终止,先试试移动脚本的位置应该就能解决问题。
内容来源于stack exchange
相关产品推荐
相关产品推荐

