当前位置:   article > 正文

Unity——在运行时修改Animator Controller状态机中的动画片段_unity animationcontroller运行时替换

unity animationcontroller运行时替换

在开发中,经常会有在运行时根据对象的不同状态来修改播放动画的需求。比如做一个射击游戏,那么持手枪时、攻击使用的动画片段明显是不能与持匕首时相同的。

原先用Legacy Animation时,是可以很方便地修改的。而Mecanim基于状态机,动画片段存在于状态机中的状态里。想要实现上述需求,相较于之前也是麻烦了不少。

最容易想到的解决方案是,在Animator Controller状态机中分别建“PistalAttack
”和“DaggerAttack”的状态,根据当前角色所持的武器来决定转移到哪一个状态。

但是如果需求有变,角色除了手枪和匕首,还能装备弓箭、冲锋枪、狙击枪……那么就得在状态机里为每一种武器增加一个状态。这种方法扩展性不好。

另一种解决方案是,针对角色持有的各种武器、每一种武器都创建一个Animator Controller,在运行时替换Animator组件中的runtimeAnimatorController。

显然这也不是一种好的方式。仔细分析,会发现如果按照这种方式,所有的Animator Controller都会是同一种结构,它们完全可以被统一起来。

任何程序开发问题都可以通过添加一层抽象来解决。分析需求,无论角色装备什么武器,事实上它们都具有一个攻击状态。那么,抛开具体的武器,动画控制器只需要一个“Attack”状态与之对应即可。在角色持有不同武器时,去修改“Attack”状态中具体播放的动画片段就能解决上述问题了。

这种方式就是标题所说的在运行时修改Animator Controller状态机中的动画片段。它通过AnimatorOverrideController来实现。贴上官方文档链接:AnimatorOverrideController官方API说明

基础的示例代码如下,代码很清晰,就不再作详细解析了。

using UnityEngine;

public class SwapWeapon : MonoBehaviour
{
    public AnimationClip[] weaponAnimationClip;

    protected Animator animator;
    protected AnimatorOverrideController animatorOverrideController;

    protected int weaponIndex;

    public void Start()
    {
        animator = GetComponent<Animator>();
        weaponIndex = 0;

        animatorOverrideController = new AnimatorOverrideController(animator.runtimeAnimatorController);
        animator.runtimeAnimatorController = animatorOverrideController;
    }

    public void Update()
    {
        if (Input.GetButtonDown("NextWeapon"))
        {
            weaponIndex = (weaponIndex + 1) % weaponAnimationClip.Length;
            animatorOverrideController["shot"] = weaponAnimationClip[weaponIndex];
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

需要注意的是:

  1. 所使用的AnimationClip,必须不是Legacy Animation,否则可能会报错,当然也不会正常播放动画。

  2. animatorOverrideController["shot"] = weaponAnimationClip[weaponIndex];代码中的字符串“shot”,不是Animator Controller中状态的名字,而是该状态下的动画片段的名字。

  3. 在修改片段时,每次修改都会触发一次动画片段绑定,因此比较耗性能,慎用。

  4. 当需要批量修改动画片段时,文档中给出了高级用法,可以用来减少性能消耗。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/138305
推荐阅读
相关标签
  

闽ICP备14008679号