记Addressables.LoadSceneAsync遇到的一个报错

前言

今天在使用Addressables.LoadSceneAsync遇到了一个报错:Reentering the Update method is not allowed. This can happen when calling WaitForCompletion on an operation while inside of a callback。大概意思是讲:“不允许重新进入Update方法,这可能是因为在回调函数中调用了WaitForCompletion导致的”。

解决过程

那么该如果解决这个呢?我们首先看看加载场景的代码:

        public void LoadSceneAsync(string sceneName, Action callback)
        {
            var handle = Addressables.LoadSceneAsync(sceneName);
            handle.Completed += (handle) =>
            {
                if (handle.Status == AsyncOperationStatus.Succeeded)
                {
                    callback?.Invoke();
                }
            };
        }

可以看到,在Completed回调中,加载完成后,我就立刻调用了自己注册进去的callback。这个callback触发了一个我另一个加载资源的函数,不过不是异步,是同步的:

        public void LoadGameObject(string assetPath, Action<Object> callback)
        {
            var handle = Addressables.InstantiateAsync(assetPath);
            handle.Completed += (handle) =>
            {
                if (handle.Status == AsyncOperationStatus.Succeeded)
                {
                    callback?.Invoke(handle.Result);
                }
            };
            handle.WaitForCompletion();
        }

可以看到,这里面刚好有调用一个“handle.WaitForCompletion()”,不难猜出,这个就是问题所在。

解决思路

一种问题解决思路是,不要在completed回调后立刻调用callback回调,而是等待一帧后再在执行:

        public void LoadSceneAsync(string sceneName, Action callback)
        {
            var handle = Addressables.LoadSceneAsync(sceneName);
            handle.Completed += (handle) =>
            {
                if (handle.Status == AsyncOperationStatus.Succeeded)
                {
                    StartCoroutine(LoadSceneBSyncCoroutine(callback));
                }
            };
        }

        private IEnumerator LoadSceneBSyncCoroutine(Action callback)
        {
            yield return null;
            callback?.Invoke();
        }

另一种解决思路是,在completed回调中,将callback方法注册进一个列表中,通过Update等待下一帧在执行,因为这个方法我没采用,就不演示了。

posted @ 2025-03-11 10:38  陈侠云  阅读(62)  评论(0)    收藏  举报
//雪花飘落效果