【问题标题】:How can I play all animations clips from animator controller one by one?如何从动画控制器一个一个地播放所有动画剪辑?
【发布时间】:2018-12-31 19:53:51
【问题描述】:

主要目标是将List中的所有动画一个一个播放完,播放第一个等待它播放完再开始下一个。

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 默认状态的第一个不播放。

【问题讨论】:

    标签: c# unity3d


    【解决方案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 组件被标记为旧版,但这可能会因为它的简单性而改变,例如你的用例。

    【讨论】:

    • 有没有办法通过脚本在动画(状态)之间添加过渡?例如,在这种情况下,在动画控制器的编辑器中,我有 12 个状态可能是 30 或更多,并且在每个状态之间添加转换可能需要很长时间。
    • 是的,你实际上可以(reference),但它有点复杂,只能在编辑器中使用,所以你必须确保它没有内置到最终的应用程序中
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 2019-09-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多