unity中animator动态设置AnimationClip

需求:
只有一个AnimatorController,这是在unity中制作好的一个状态机。
我们需要在运行的时候,将其添加到每个人物身上,而每个人物的animationclip是不同的,这就需要将不同的clip的设置到AnimatorController上。

解决方法:
1、准备AnimatorController资源:
unity中animator动态设置AnimationClip_第1张图片
unity中animator动态设置AnimationClip_第2张图片
2、准备三个状态:
unity中animator动态设置AnimationClip_第3张图片
3、为每个状态,添加一个空的AnimactionClip
unity中animator动态设置AnimationClip_第4张图片
unity中animator动态设置AnimationClip_第5张图片
unity中animator动态设置AnimationClip_第6张图片
unity中animator动态设置AnimationClip_第7张图片
unity中animator动态设置AnimationClip_第8张图片

4、编写代码,动态设置AnimationClip

[Serializable]
public class PrefabInfo
{
    public GameObject prefab;
    public Vector3 position;
    public List<AnimationClip> clips;
}

public class Benchmark : MonoBehaviour
{
    public List<PrefabInfo> m_gos;
    private List<Animator> m_animators;

    private float m_duration = 2.0f;
    private float m_countDown = 0;
    private int m_hideIndex = -1;
    private int m_visibleNum = 0;
    public Text num;

    private void Start()
    {
        m_animators = new List<Animator>();
        RuntimeAnimatorController animatorController = Resources.Load("Controller") as RuntimeAnimatorController; //加载状态机资源
        for (int i = 0; i < m_gos.Count; ++i) //实例化多个不同的人物
        {
            GameObject go = GameObject.Instantiate(m_gos[i].prefab);
            go.transform.localScale = Vector3.one;
            go.transform.position = m_gos[i].position;
            Animator animator = go.GetComponent<Animator>(); //获取不到,就添加
            if (animator == null) animator = go.AddComponent<Animator>();
            animator.runtimeAnimatorController = animatorController; //将状态机资源,赋值给animator的runtimeAnimatorController

            AnimationClip[] clips = animatorController.animationClips; //拿到空的动画片段,其实只用到了其名字
            AnimatorOverrideController overrideController = new AnimatorOverrideController(); //新建一个重写的controller
            overrideController.runtimeAnimatorController = animatorController; //重写的controller的runtimeAnimatorController指向那个空的
            for (int j = 0; j < m_gos[i].clips.Count && j < clips.Length; ++j)
            {
                overrideController[clips[j].name] = m_gos[i].clips[j]; //设置不同的clip
            }
            animator.runtimeAnimatorController = overrideController; //重新赋值给物体
            m_animators.Add(animator);
        }
        m_hideIndex = -1;
        m_visibleNum = m_animators.Count;
        UpdateVisibleNum();
    }
}

注意点:
1、 overrideController[clips[j].name] 这里是指如下图,其值为a1,是个字符串,而不是状态的名字。
unity中animator动态设置AnimationClip_第9张图片
2、要使用AnimatorOverrideController,进行动画片段重写,然后赋值给runtimeAnimatorController,不能直接改RuntimeAnimatorController改。这个unity设计比较诡异。

3、AnimatorController也能打包:
https://blog.csdn.net/tonnychu/article/details/49903657
但是注意实例化的没有试过,参考上面的博客。
这里只要一个AnimatorController即可。

4、上面有一个Any State
unity中animator动态设置AnimationClip_第10张图片
他是任意状态都能切换到其他的状态。

5、播放动画,可以用trigger,也可以直接用名字:
如:
m_animators[i].SetTrigger(“To” + (index + 1));
unity中animator动态设置AnimationClip_第11张图片
unity中animator动态设置AnimationClip_第12张图片
也可以直接播放状态的名字:
m_animators[i].Play(“Monster_MarineMusketeer_damage_fly”);
unity中animator动态设置AnimationClip_第13张图片
至此结束。

你可能感兴趣的:(Unity)