记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等待下一帧在执行,因为这个方法我没采用,就不演示了。