【问题标题】:How can I play random animations in animator using script?如何使用脚本在动画师中播放随机动画?
【发布时间】:2019-01-01 23:44:58
【问题描述】:

我有 12 个状态,它们都通过循环中的转换连接。 所以演奏的流程总是一样的。但我想随机播放。

但如果它们都通过转换连接,我想这是不可能的,因为转换构成了路径。

并且使用动画组件不适用于 mixamo 动画。由于在动画组件中动画必须是传统类型,但在动画器中它们必须是人形类型并且要正确播放动画,我需要将它们设置为人形类型,这就是我使用动画器而不是动画的原因。播放它们效果很好,但我想按随机顺序播放它们。

【问题讨论】:

    标签: c# unity3d


    【解决方案1】:
    private AnimationClip[] clips;
    private Animator animator;
    
    private void Awake()
    {
        // Get the animator component
        animator = GetComponent<Animator>();
    
        // Get all available clips
        clips = animator.runtimeAnimatorController.animationClips;
    }
    

    现在你有了所有的动画。

    现在有多种方法可以随机化它们...我向您展示最简单的一种,它只是随机选择一个索引并播放该动画。

    首先,您将使用一个协程,以便从头开始

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

    在协程中选择一个随机索引并在动画器中播放状态

    private IEnumerator PlayRandomly ()
    {
        while(true)
        {
            var randInd = Randome.Range(0, Clips.length);
    
            var randClip = clips[randInd];
    
            animator.Play(randClip.name);
    
            // Wait until animation finished than pick the next one
            yield return new WaitForSeconds(randClip.length);
        }
    }
    

    请注意,这是最简单的方法,不能保证“不要在另一个之后播放相同的动画两次”或“在重复之前先播放所有动画”之类的内容

    要实现这些,您可以改组剪辑列表,遍历它们并在最后一个剪辑之后再次随机播放等,例如喜欢

    private IEnumerator PlayRandomly ()
    {
        var clipList = clips.ToList();
    
        while(true)
        {
            clipList.Shuffle();
    
            foreach(var randClip in clipList)
            {
                animator.Play(randClip.name);
                yield return new WaitForSeconds(randClip.length);
            }
        }
    }
    
    public static class IListExtensions 
    {
        /// <summary>
        /// Shuffles the element order of the specified list.
        /// </summary>
        public static void Shuffle<T>(this IList<T> ts) {
            var count = ts.Count;
            var last = count - 1;
            for (var i = 0; i < last; ++i) {
                var r = UnityEngine.Random.Range(i, count);
                var tmp = ts[i];
                ts[i] = ts[r];
                ts[r] = tmp;
            }
        }
    }
    

    【讨论】:

    • 工作。但是现在在我的另一个项目中,子状态机中带有动画的状态。如何从子状态机中获取它们?子状态机名称为 Magic StateMachine。
    • 据我所知,您可以通过将子状态与 . 连接来获得子状态。但我很确定您不应该在 StateName 中有空格,然后 .. 看起来像 @ 987654327@
    • 不幸的是,runtimeAnimatorController 似乎无法知道一个状态是只有一个剪辑还是一个子状态机.. 不确定但 animationClips 可能也已经包含子状态机的剪辑,因此您可以通过 orser 中的州名称过滤列表以仅获取这些剪辑。
    • 抱歉搞砸了。您在这里的答案已经包括子状态。
    猜你喜欢
    • 2014-09-03
    • 2019-09-05
    • 2022-07-13
    • 1970-01-01
    • 1970-01-01
    • 2022-10-14
    • 1970-01-01
    • 2021-09-25
    • 2015-11-18
    相关资源
    最近更新 更多