如何才能一一播放动画师控制器中的所有动画剪辑?

时间:2018-12-31 05:49:52

标签: c# unity3d

主要目标是逐一播放列表中的所有动画,以播放第一个动画,等待其完成播放,然后开始下一个动画。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayAnimations : MonoBehaviour
{
    public Animator animator;

    private List<AnimationClip> clips = new List<AnimationClip>();

    // Start is called before the first frame update
    void Start()
    {
        foreach (AnimationClip ac in animator.runtimeAnimatorController.animationClips)
        {
            StartCoroutine(PlayAll(ac.name, ac.length));
        }
    }

    public IEnumerator PlayAll(string stateName, float length)
    {
        animator.Play(stateName);
        yield return new WaitForSeconds(length);
    }

    // Update is called once per frame
    void Update()
    {

    }
}

但是它只播放一个动画剪辑,而动画控制器中有两个。为什么呢

它只播放第二个,而第一个不播放StateMachine默认状态的播放。

1 个答案:

答案 0 :(得分:1)

您要在“相同”时间(至少在同一帧中)针对不同状态/动画启动所有协程,因此它们都“同时”运行animator.Play

因此在第一帧中,两个协程都设置了相应的状态,首先是第一个动画,然后是第二个动画,等等。

=>您只有列表中的最后一个实际运行,因为它是唯一不会因随后的animator.Play调用而被“推翻”的计算机。

相反,请将您的for循环移至协同程序:

void Start()
{
    StartCoroutine(PlayAll());
}

public IEnumerator PlayAll()
{
    foreach (AnimationClip ac in animator.runtimeAnimatorController.animationClips)
    {
        animator.Play(ac.name);
        yield return new WaitForSeconds(ac.length);
    }
}

但是实际上StateMachine的整个想法都在进行过渡..因此,您可以将两个状态/动画与具有过渡的过渡简单地联系起来

  • UseExitTime已启用
  • ExitTime = 1
  • Duration(如果需要,可以过渡或淡入)0

然后它会自动转到第一个动画后的下一个动画。 (您现在甚至可以通过简单地过渡到第一个状态来循环播放它们。)

因此,您实际上根本不需要任何脚本。


否则,您也可以使用Animation组件,而不使用状态,过渡,层和控制器。

代码只会稍有不同:

// Assuming here this script is attached to the same object as the Animation component
// Ofcourse you can also keep it public and reference the component yourself
private Animation animation;

public List<AnimationClip> clips = new List<AnimationClip>();

private void Awake()
{
    animation = GetComponent<Animation>();
}

private void Start()
{
    StartCoroutine(PlayAll());
}

private IEnumerator PlayAll()
{
    foreach(var clip in clips)
    {
        animation.Play(clip.name);
        yield return new WaitForSeconds(clip.length);
    }
}

Animation组件被标记为旧版,但是由于其简单易用,例如您的用例。