Unity中等待对象旋转结束再播动画及朝向异常求助
Unity 两个技术问题解决方案
问题1:如何实现等待对象旋转结束后再播放动画?
从你的代码来看,当前你是在启动旋转协程的同时直接触发了动画,这就导致旋转还在进行中动画就开始播放了。要实现等待旋转结束再播放动画,只需要在协程中等待Spin协程执行完毕后再开启动画即可:
修改你的PlayAudio协程,把anim.SetBool("Roll_Anim", true);放到等待旋转协程完成之后:
IEnumerator PlayAudio() { AudioSource audio = GetComponent<AudioSource>(); audio.clip = audioClip; audio.Play(); yield return new WaitForSeconds(audio.clip.length); var rotation = Quaternion.LookRotation(target.position - transform.position); // 等待Spin协程完全执行完毕 yield return StartCoroutine(Spin(3f, rotation)); // 旋转结束后再启动动画 anim.SetBool("Roll_Anim", true); }
这样就能确保旋转完成后才播放动画,完美解决“等待旋转结束再执行后续动作”的需求。
问题2:播放Roll_Anim时对象朝向变回子对象相机的异常排查与修复
异常原因分析
从你的代码和描述来看,主要有两个可能的原因:
- 动画的根运动(Root Motion)覆盖了旋转结果:如果你的
Roll_Anim动画开启了根运动,动画本身的旋转关键帧会直接覆盖你通过代码设置的对象旋转,导致朝向变回动画默认的方向(也就是你说的子对象相机方向)。 - Update方法中的移动逻辑干扰:当动画播放时,Update里的位置移动逻辑可能还在运行,间接影响对象的朝向。
修复方案
方案1:关闭动画的根运动(最直接)
打开你的Animator控制器,选中Roll_Anim动画片段,在Inspector面板中找到Root Motion选项,取消勾选,或者将动画的根运动模式设置为None。这样动画就不会修改对象的根节点旋转/位置,只会影响子对象的动画,保证你通过代码设置的旋转方向不会被覆盖。
方案2:锁定旋转并禁用干扰逻辑(补充防护)
如果需要保留根运动,可以在动画播放前做好防护:
IEnumerator PlayAudio() { AudioSource audio = GetComponent<AudioSource>(); audio.clip = audioClip; audio.Play(); yield return new WaitForSeconds(audio.clip.length); var rotation = Quaternion.LookRotation(target.position - transform.position); yield return StartCoroutine(Spin(3f, rotation)); // 确保旋转完全到位,避免Slerp精度问题 transform.rotation = rotation; // 禁用Update里的移动逻辑,避免干扰动画 hasStarted = false; // 启动动画 anim.SetBool("Roll_Anim", true); }
同时可以优化Spin协程,确保旋转最终完全达到目标值:
IEnumerator Spin(float lerpTime, Quaternion rotation) { float elapsedTime = 0f; while (elapsedTime <= lerpTime) { transform.rotation = Quaternion.Slerp(transform.rotation, rotation, elapsedTime / lerpTime); elapsedTime += Time.deltaTime; yield return null; } // 强制设置最终旋转,保证精度 transform.rotation = rotation; }
方案3:检查动画初始帧
打开你的Roll_Anim动画文件,检查动画的初始帧旋转是否和你期望的朝向一致。如果初始帧的朝向是子对象相机的方向,即使关闭根运动,动画播放时也会把对象拉回初始旋转,这时需要调整动画的初始关键帧旋转。
内容的提问来源于stack exchange,提问作者Daniel Lip
相关产品推荐
相关产品推荐

