动态修改动画状态机中的动画片段

使用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;
    }
}
   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值