Unity中带旋转的动画为何会破坏游戏对象的旋转状态?
解决Unity植物动画播放后旋转异常的问题
看起来你遇到的核心问题是动画系统和代码设置的旋转之间的冲突,尤其是取消Root Motion后出现的旋转被强制重置为0的情况。我来帮你一步步排查和解决:
1. 先检查动画剪辑的「Write Defaults」设置
这是新手最容易踩的坑:当你关闭Root Motion后,Animator的「Write Defaults」选项如果是开启状态,动画播放结束后会把所有动画涉及的属性(比如旋转)重置为默认值(0),这会直接覆盖你在代码里设置的localEulerAngles = (0,0,-90),哪怕你在Update里强制设置也没用——因为动画帧的更新优先级比Update高。
解决办法:
- 打开Animator窗口,选中你的植物触发动画状态
- 在Inspector面板里找到「Write Defaults」选项,把它关闭
- 关闭后,动画播放结束会保留最后一帧的属性值,而不是重置为默认
2. 修正动画剪辑的旋转关键帧
你的动画逻辑是「旋转到特定角度再转回0度」,但这里的「0度」是相对于局部空间还是世界空间?如果动画里的关键帧直接把Transform.localEulerAngles设为(0,0,0),那会覆盖你初始设置的-90度。
正确的做法是:
- 打开动画剪辑,把初始关键帧的旋转值设为(0,0,-90)(和你代码里的初始旋转一致)
- 动画的旋转动作应该是从-90度转到目标角度,再转回-90度,而不是转到0度
- 确保动画修改的是
Transform.localEulerAngles(局部旋转),而不是世界空间的Transform.rotation,这样不会影响父物体的行星旋转
3. 优化植物生成的旋转逻辑
你当前的生成代码里,父物体先绕行星旋转,然后实例化植物时用Quaternion.identity,再手动设置父物体和局部旋转。这里可以简化逻辑,避免旋转叠加混乱:
修改Tree脚本的Start方法:
void Start() { // 父物体绕行星的自定义支点旋转 transform.RotateAround(customPivot.position, Vector3.forward, angle); // 实例化植物时直接继承父物体的位置和旋转,避免手动调整 GameObject myPlant = Instantiate(plant, transform.position, transform.rotation); myPlant.transform.SetParent(transform); // 设置局部旋转,让植物朝向正确的方向(相对于父物体) myPlant.transform.localEulerAngles = new Vector3(0, 0, -90); }
这样父物体负责行星层面的旋转,植物物体只负责自身的局部朝向,动画修改的也是局部旋转,不会互相干扰。
4. 用动画事件强制重置旋转(兜底方案)
如果上面的方法还没解决,可以给动画添加一个结束事件,强制把旋转改回正确值:
- 在
TreeBehaviour脚本里添加一个重置方法:
public void ResetPlantRotation() { // 确保重置为初始的局部旋转 transform.localEulerAngles = new Vector3(0, 0, -90); }
- 打开动画剪辑,在最后一帧的位置添加一个动画事件(右键时间轴→Add Event)
- 在事件的Inspector里,选择植物物体的
TreeBehaviour组件,然后选择ResetPlantRotation方法
这样动画播放结束时,会自动调用这个方法把旋转恢复到正确状态。
内容的提问来源于stack exchange,提问作者Kon




