简体   繁体   English

unity计算总动画师以完成然后更改场景

[英]Unity calculate total animator to complete then change scene

Im trying to show an exit animation from a scene and, at the same time, load a new scene using LoadSceneAsync, keep the scene on memory until the animation ends, then change to the new scene like this question already solved 我试图显示场景中的退出动画,同时使用LoadSceneAsync加载新场景,将场景保留在内存中直到动画结束,然后更改为新场景,就像已经解决了这个问题一样

The catch is i have several animations running on layers all fired by the same trigger, right now all my animations are 1 seg on length, but some starts at 0 and some at 0.5 seg 问题是我在同一触发器触发的层上运行了多个动画,现在我所有的动画长度为1段,但有些从0开始,有些从0.5段开始

How can i calculate the total time that will take the animation to complete, asynchronously load the new scene, then, either wait for the animation time to complete or, the loading of the new scene to finish (the one that takes longer), and finally change scene? 如何计算动画完成所需的总时间,异步加载新场景,然后等待动画时间完成或新场景的加载完成(需要更长的时间),以及终于改变了场面?

I was thinking of using 2 coroutines running simultaneously and wait for the longest to finish, but I'm not sure if this can be done (I'm pretty new to C# Programming), any ideas? 我当时正在考虑使用2个协同程序同时运行并等待最长的协同完成时间,但是我不确定是否可以做到(我对C#编程很陌生),有什么想法吗?

Right now I'm waiting a fixed time of 1.6 Seg because my animations are equal in time, but that can change and that's the only way i could think of... 现在我正在等待1.6 Seg的固定时间,因为我的动画在时间上是相等的,但是这可以改变,这是我能想到的唯一方法...

public void GotoScene(string scene)
{
    // Start exit animations and wait
    CanvasAnimation.SetBool("hide", true);
    StartCoroutine(ChangeScene(1.6f, scene));
}

IEnumerator ChangeScene(float time, string goToScene)
{
    //Set the current Scene to be able to unload it later
    Scene currentScene = SceneManager.GetActiveScene();

    // Wait for exit animation to finish
    yield return new WaitForSeconds(time);

    // The Application loads the Scene in the background at the same time as the current Scene.
    AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(goToScene, LoadSceneMode.Additive);

    //Wait until the last operation fully loads to return anything
    while (!asyncLoad.isDone)
    {
        yield return null;
    }

    //Move the GameObject (you attach this in the Inspector) to the newly loaded Scene
    SceneManager.MoveGameObjectToScene(WireRoomObj, SceneManager.GetSceneByName(goToScene));

    //Unload the previous Scene
    SceneManager.UnloadSceneAsync(currentScene);
}

You could probably check animation state from AnimatorStateInfo.normalizedTime and then wait in coroutine while normalizedTime of current animations are below 1. For example: 您可能可以从AnimatorStateInfo.normalizedTime检查动画状态,然后在协程中等待当前动画的normalizedTime低于1。例如:

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

public class WaitUntilComplete : MonoBehaviour {

    // Use this for initialization
    void Start () {
        StartCoroutine(WaitUntilAllAnimationsCompleted());
    }

    IEnumerator WaitUntilAllAnimationsCompleted() {
        print("waiting started " + Time.time);
        yield return new WaitWhile(() => GetAllAnimationStates().Any(state => state.normalizedTime < 1f));
        print("waiting ended " + Time.time);
    }

    List<AnimatorStateInfo> GetAllAnimationStates() {
        List<AnimatorStateInfo> states = new List<AnimatorStateInfo>();
        var animatorList = GetComponentsInChildren<Animator>();
        foreach (var anim in animatorList) {
            for (int i = 0; i < anim.layerCount; ++i) {
                states.Add(anim.GetCurrentAnimatorStateInfo(i));
            }
        }
        return states;
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM