提问者:小点点

如何等到一个场景满载?


我需要等到一个场景被完全加载,以便将一个场景移动到它。如果执行得太快(就在调用),那么就会消失。基于这篇文章,我实现了一个场景加载类来解决这个问题:

public static class CustomSceneManager
{
    public delegate void SceneChange(string sceneName);

    public static event SceneChange LoadScene;
    public static event SceneChange UnloadScene;

    private static IEnumerator LoadLevel (string sceneName){
        var asyncLoadLevel = SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Single);
        while (!asyncLoadLevel.isDone){
            Debug.Log("Loading the Scene"); 
            yield return null;
        }
    }
    
    public static void OnLoadScene(string newSceneName)
    {
        OnUnloadScene(newSceneName);
        LoadLevel(newSceneName);
        LoadScene?.Invoke(newSceneName);
    }
    private static void OnUnloadScene(string newSceneName)
    {
        UnloadScene?.Invoke(newSceneName);
    }
}

我将从它调用两个事件(codeLoadScene/code>和不起作用--它只是不加载场景。我在这里做错了什么?

编辑:

现在我传递调用的脚本的引用,方法如下:

    public static void OnLoadScene(MonoBehaviour loader, string newSceneName)
    {
        UnloadScene?.Invoke(newSceneName);
        loader.StartCoroutine(LoadLevel(newSceneName));
        Debug.Log(SceneManager.GetActiveScene().name); // this line returns previous scene
        LoadScene?.Invoke(newSceneName);
    }

现在场景加载,但是当我检查当前加载的是什么场景时,它返回的是之前的场景名称。

编辑2:

更确切地说,我将替换为,它返回


共1个答案

匿名用户

您必须使用运行coroutienes。

您要么需要传入一个的引用,该引用将执行协同项,要么只是使您的类成为一个永远不会被销毁的单例

实际上,当事件还没有加载时,您会过早地调用它,但您刚刚开始加载它,因此更愿意这样做,例如。

public class CustomSceneManager : MonoBehaviour
{
    public delegate void SceneChange(string sceneName);

    public static event SceneChange LoadScene;
    public static event SceneChange UnloadScene;

    private CustomNetworkManager singleton;

    private void Awake ()
    {
        if(singleton && singleton != this)
        {
            Destroy(gameObject);
        }

        singleton = this;
        DontDestroyOnLoad (gameObject);
    }
    
    private static IEnumerator LoadLevel (string sceneName){
        var asyncLoadLevel = SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Single);
        while (!asyncLoadLevel.isDone){
            Debug.Log("Loading the Scene"); 
            yield return null;
        }

        LoadScene?.Invoke(newSceneName);
    }
    
    public static void OnLoadScene(string newSceneName)
    {
        if(! singleton)
        {
            singleton = new GameObject("CustomNetworkManager").AddComponent<CustomNetworkManager>();
        }

        OnUnloadScene(newSceneName);
        singleton.StartCoroutine(LoadLevel(newSceneName));
    }