使用AnimatorOverrideController对原本的动画片段进行覆盖
1,AnimatorOverrideController结构:
其中左侧是旧动画片段(Clip)的名称而不是动画状态(State)的名称
AnimatorOverrideController类中通过索引器获取或设置对应片段override以后的片段
2,使用代码修改
/// <summary>
/// 修改动画片段
/// </summary>
void ChangeAnimationClip()
{
AnimatorOverrideController overrideController = new AnimatorOverrideController();
if (anim.runtimeAnimatorController is AnimatorOverrideController)
{
//如果原本就是AnimatorOverrideController,引用原本的AnimatorOverrideController防止覆盖之前的修改
overrideController = (anim.runtimeAnimatorController as AnimatorOverrideController);
//记录旧动画
if (oldClip == null)
oldClip = overrideController[changeClipName];
}
else
{
//如果原本不是AnimatorOverrideController,使用新建的AnimatorOverrideController,同时runtimeAnimatorController指向原本的AnimatorController
overrideController.runtimeAnimatorController = anim.runtimeAnimatorController;
if (oldClip == null)
oldClip = overrideController[changeClipName];
}
//填的是动画的名称而不是动画机中状态的名称
overrideController[changeClipName] = clip;
anim.runtimeAnimatorController = overrideController;
}
void ChangeBackAnimClip()
{
if (anim == null) return;
if (oldClip == null) return;
AnimatorOverrideController overrideController = new AnimatorOverrideController();
if (anim.runtimeAnimatorController is AnimatorOverrideController)
overrideController = (anim.runtimeAnimatorController as AnimatorOverrideController);
else
overrideController.runtimeAnimatorController = anim.runtimeAnimatorController;
//填初始的名字,不是新动画的名字
overrideController[changeClipName] = oldClip;
anim.runtimeAnimatorController = overrideController;
}
经过一次代码替换后,anim.runtimeAnimatorController 不论原本是AnimatorController还是AnimatorOverrideController,都会变成 AnimatorOverrideController
注意:如果未运行前,动画状态机使用的就是AnimatorOverrideController,这种替换会导致实际的AnimatorOverrideController文件中的参数替换,例如,运行时将Attack替换成Attack2片段,退出运行,仍然时Attack2片段,不会变成原本的Attack片段。
解决方法:在destroy时替换回去;或者在awake时浅拷贝原本的AnimatorOverrideController
public static class AnimOverrideCtrlExtention
{
/// <summary>
/// 浅拷贝一个AnimatorOverrideController
/// </summary>
/// <param name="original"></param>
/// <returns></returns>
public static AnimatorOverrideController ShallowCopy(this AnimatorOverrideController original)
{
// 创建一个新的AnimatorOverrideController实例
AnimatorOverrideController copy = new AnimatorOverrideController();
copy.runtimeAnimatorController = original.runtimeAnimatorController;
List<KeyValuePair<AnimationClip, AnimationClip>> overrides = new List<KeyValuePair<AnimationClip, AnimationClip>>();
original.GetOverrides(overrides);
// 遍历原始AnimatorOverrideController的所有动画片段
foreach (var state in overrides)
{
// 将每个状态的动画片段添加到新的AnimatorOverrideController中
copy[state.Key.name] = state.Value;
}
return copy;
}
}