From 2f2fcf419c997ad3526a533cdda7cfd251720a42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Borks?= Date: Mon, 26 Aug 2024 19:12:58 -0300 Subject: [PATCH] add new transitions to scene loaders --- .../Runtime/SceneLoaders/SceneLoaderAsync.cs | 89 +++++++++++++++---- .../SceneLoaders/SceneLoaderCoroutine.cs | 40 +++++++++ .../SceneLoaders/SceneLoaderUniTask.cs | 40 +++++++++ 3 files changed, 154 insertions(+), 15 deletions(-) diff --git a/Packages/com.mygamedevtools.scene-loader/Runtime/SceneLoaders/SceneLoaderAsync.cs b/Packages/com.mygamedevtools.scene-loader/Runtime/SceneLoaders/SceneLoaderAsync.cs index 3398991..eed0012 100644 --- a/Packages/com.mygamedevtools.scene-loader/Runtime/SceneLoaders/SceneLoaderAsync.cs +++ b/Packages/com.mygamedevtools.scene-loader/Runtime/SceneLoaders/SceneLoaderAsync.cs @@ -37,6 +37,26 @@ public void TransitionToScene(ILoadSceneInfo targetSceneInfo, ILoadSceneInfo int TransitionToSceneAsync(targetSceneInfo, intermediateSceneInfo).AsTask().Forget(HandleFireAndForgetException); } + public void TransitionToScenesFromScenes(ILoadSceneInfo[] targetScenes, ILoadSceneInfo[] fromScenes, int setIndexActive, ILoadSceneInfo intermediateSceneInfo = null) + { + TransitionToScenesFromScenesAsync(targetScenes, fromScenes, setIndexActive, intermediateSceneInfo).Forget(HandleFireAndForgetException); + } + + public void TransitionToSceneFromScenes(ILoadSceneInfo targetSceneInfo, ILoadSceneInfo[] fromScenes, ILoadSceneInfo intermediateSceneInfo = null) + { + TransitionToSceneFromScenesAsync(targetSceneInfo, fromScenes, intermediateSceneInfo).Forget(HandleFireAndForgetException); + } + + public void TransitionToScenesFromAll(ILoadSceneInfo[] targetScenes, int setIndexActive, ILoadSceneInfo intermediateSceneInfo = null) + { + TransitionToScenesFromAllAsync(targetScenes, setIndexActive, intermediateSceneInfo).Forget(HandleFireAndForgetException); + } + + public void TransitionToSceneFromAll(ILoadSceneInfo targetSceneInfo, ILoadSceneInfo intermediateSceneInfo = null) + { + TransitionToSceneFromAllAsync(targetSceneInfo, intermediateSceneInfo).Forget(HandleFireAndForgetException); + } + public void UnloadScenes(ILoadSceneInfo[] sceneInfos) { UnloadScenesAsync(sceneInfos).AsTask().Forget(HandleFireAndForgetException); @@ -59,9 +79,11 @@ public void LoadScene(ILoadSceneInfo sceneInfo, bool setActive = false) public ValueTask TransitionToScenesAsync(ILoadSceneInfo[] targetScenes, int setIndexActive, ILoadSceneInfo intermediateSceneReference = null) { + Scene activeScene = _manager.GetActiveScene(); + ILoadSceneInfo[] fromScenes = activeScene.IsValid() ? new ILoadSceneInfo[] { new LoadSceneInfoScene(activeScene) } : null; return intermediateSceneReference == null - ? TransitionDirectlyAsync(targetScenes, setIndexActive, _lifetimeTokenSource.Token) - : TransitionWithIntermediateAsync(targetScenes, setIndexActive, intermediateSceneReference, _lifetimeTokenSource.Token); + ? TransitionDirectlyAsync(targetScenes, fromScenes, setIndexActive, _lifetimeTokenSource.Token) + : TransitionWithIntermediateAsync(targetScenes, fromScenes, setIndexActive, intermediateSceneReference, _lifetimeTokenSource.Token); } public async ValueTask TransitionToSceneAsync(ILoadSceneInfo targetSceneInfo, ILoadSceneInfo intermediateSceneInfo = default) @@ -70,6 +92,33 @@ public async ValueTask TransitionToSceneAsync(ILoadSceneInfo targetSceneI return result == null || result.Length == 0 ? default : result[0]; } + public ValueTask TransitionToScenesFromScenesAsync(ILoadSceneInfo[] targetScenes, ILoadSceneInfo[] fromScenes, int setIndexActive, ILoadSceneInfo intermediateSceneReference = null) + { + return intermediateSceneReference == null + ? TransitionDirectlyAsync(targetScenes, fromScenes, setIndexActive, _lifetimeTokenSource.Token) + : TransitionWithIntermediateAsync(targetScenes, fromScenes, setIndexActive, intermediateSceneReference, _lifetimeTokenSource.Token); + } + + public async ValueTask TransitionToSceneFromScenesAsync(ILoadSceneInfo targetSceneInfo, ILoadSceneInfo[] fromScenes, ILoadSceneInfo intermediateSceneReference = null) + { + var result = await TransitionToScenesFromScenesAsync(new ILoadSceneInfo[] { targetSceneInfo }, fromScenes, 0, intermediateSceneReference); + return result == null || result.Length == 0 ? default : result[0]; + } + + public ValueTask TransitionToScenesFromAllAsync(ILoadSceneInfo[] targetScenes, int setIndexActive, ILoadSceneInfo intermediateSceneReference = null) + { + ILoadSceneInfo[] fromScenes = GetAllLoadedSceneInfos(); + return intermediateSceneReference == null + ? TransitionDirectlyAsync(targetScenes, fromScenes, setIndexActive, _lifetimeTokenSource.Token) + : TransitionWithIntermediateAsync(targetScenes, fromScenes, setIndexActive, intermediateSceneReference, _lifetimeTokenSource.Token); + } + + public async ValueTask TransitionToSceneFromAllAsync(ILoadSceneInfo targetSceneInfo, ILoadSceneInfo intermediateSceneReference = null) + { + var result = await TransitionToScenesFromAllAsync(new ILoadSceneInfo[] { targetSceneInfo }, 0, intermediateSceneReference); + return result == null || result.Length == 0 ? default : result[0]; + } + public ValueTask LoadScenesAsync(ILoadSceneInfo[] sceneReferences, int setIndexActive = -1, IProgress progress = null) { return _manager.LoadScenesAsync(sceneReferences, setIndexActive, progress, _lifetimeTokenSource.Token); @@ -90,7 +139,7 @@ public ValueTask UnloadSceneAsync(ILoadSceneInfo sceneInfo) return _manager.UnloadSceneAsync(sceneInfo, _lifetimeTokenSource.Token); } - async ValueTask TransitionDirectlyAsync(ILoadSceneInfo[] targetScenes, int setIndexActive, CancellationToken token) + async ValueTask TransitionDirectlyAsync(ILoadSceneInfo[] targetScenes, ILoadSceneInfo[] fromScenes, int setIndexActive, CancellationToken token) { // If only one scene is loaded, we need to create a temporary scene for transition. Scene tempScene = default; @@ -98,7 +147,7 @@ async ValueTask TransitionDirectlyAsync(ILoadSceneInfo[] targetScenes, { tempScene = SceneManager.CreateScene("temp-transition-scene"); } - await UnloadSourceSceneAsync(token); + await UnloadSourceScenesAsync(fromScenes, token); Scene[] loadedScenes = await _manager.LoadScenesAsync(targetScenes, setIndexActive, token: token); @@ -109,7 +158,7 @@ async ValueTask TransitionDirectlyAsync(ILoadSceneInfo[] targetScenes, return loadedScenes; } - async ValueTask TransitionWithIntermediateAsync(ILoadSceneInfo[] targetScenes, int setIndexActive, ILoadSceneInfo intermediateSceneInfo, CancellationToken token) + async ValueTask TransitionWithIntermediateAsync(ILoadSceneInfo[] targetScenes, ILoadSceneInfo[] fromScenes, int setIndexActive, ILoadSceneInfo intermediateSceneInfo, CancellationToken token) { Scene loadingScene; try @@ -129,11 +178,11 @@ async ValueTask TransitionWithIntermediateAsync(ILoadSceneInfo[] target LoadingBehavior loadingBehavior = UnityEngine.Object.FindObjectsOfType().FirstOrDefault(l => l.gameObject.scene == loadingScene); #endif return loadingBehavior - ? await TransitionWithIntermediateLoadingAsync(targetScenes, setIndexActive, intermediateSceneInfo, loadingBehavior, token) - : await TransitionWithIntermediateNoLoadingAsync(targetScenes, setIndexActive, intermediateSceneInfo, token); + ? await TransitionWithIntermediateLoadingAsync(targetScenes, fromScenes, setIndexActive, intermediateSceneInfo, loadingBehavior, token) + : await TransitionWithIntermediateNoLoadingAsync(targetScenes, fromScenes, setIndexActive, intermediateSceneInfo, token); } - async ValueTask TransitionWithIntermediateLoadingAsync(ILoadSceneInfo[] targetScenes, int setIndexActive, ILoadSceneInfo intermediateSceneInfo, LoadingBehavior loadingBehavior, CancellationToken token) + async ValueTask TransitionWithIntermediateLoadingAsync(ILoadSceneInfo[] targetScenes, ILoadSceneInfo[] fromScenes, int setIndexActive, ILoadSceneInfo intermediateSceneInfo, LoadingBehavior loadingBehavior, CancellationToken token) { LoadingProgress progress = loadingBehavior.Progress; while (progress.State != LoadingState.Loading && !token.IsCancellationRequested) @@ -141,7 +190,7 @@ async ValueTask TransitionWithIntermediateLoadingAsync(ILoadSceneInfo[] token.ThrowIfCancellationRequested(); - await UnloadSourceSceneAsync(token); + await UnloadSourceScenesAsync(fromScenes, token); Scene[] loadedScenes = await _manager.LoadScenesAsync(targetScenes, setIndexActive, progress, token); progress.SetState(LoadingState.TargetSceneLoaded); @@ -155,21 +204,31 @@ async ValueTask TransitionWithIntermediateLoadingAsync(ILoadSceneInfo[] return loadedScenes; } - async ValueTask TransitionWithIntermediateNoLoadingAsync(ILoadSceneInfo[] targetScenes, int setIndexActive, ILoadSceneInfo intermediateSceneInfo, CancellationToken token) + async ValueTask TransitionWithIntermediateNoLoadingAsync(ILoadSceneInfo[] targetScenes, ILoadSceneInfo[] fromScenes, int setIndexActive, ILoadSceneInfo intermediateSceneInfo, CancellationToken token) { - await UnloadSourceSceneAsync(token); + await UnloadSourceScenesAsync(fromScenes, token); Scene[] loadedScenes = await _manager.LoadScenesAsync(targetScenes, setIndexActive, token: token); _manager.UnloadSceneAsync(intermediateSceneInfo, token).Forget(HandleFireAndForgetException); return loadedScenes; } - ValueTask UnloadSourceSceneAsync(CancellationToken token) + ValueTask UnloadSourceScenesAsync(ILoadSceneInfo[] fromScenes, CancellationToken token) { - Scene sourceScene = _manager.GetActiveScene(); - if (!sourceScene.IsValid()) + if (fromScenes == null || fromScenes.Length == 0) return default; - return _manager.UnloadSceneAsync(new LoadSceneInfoScene(sourceScene), token); + return _manager.UnloadScenesAsync(fromScenes, token); + } + + ILoadSceneInfo[] GetAllLoadedSceneInfos() + { + int count = _manager.LoadedSceneCount; + ILoadSceneInfo[] loadedSceneInfos = new ILoadSceneInfo[count]; + for (int i = 0; i < count; i++) + { + loadedSceneInfos[i] = new LoadSceneInfoScene(_manager.GetLoadedSceneAt(i)); + } + return loadedSceneInfos; } void HandleFireAndForgetException(Exception exception) diff --git a/Packages/com.mygamedevtools.scene-loader/Runtime/SceneLoaders/SceneLoaderCoroutine.cs b/Packages/com.mygamedevtools.scene-loader/Runtime/SceneLoaders/SceneLoaderCoroutine.cs index bd347ca..11d5afb 100644 --- a/Packages/com.mygamedevtools.scene-loader/Runtime/SceneLoaders/SceneLoaderCoroutine.cs +++ b/Packages/com.mygamedevtools.scene-loader/Runtime/SceneLoaders/SceneLoaderCoroutine.cs @@ -33,6 +33,26 @@ public void TransitionToScene(ILoadSceneInfo targetSceneInfo, ILoadSceneInfo int TransitionToSceneAsync(targetSceneInfo, intermediateSceneInfo); } + public void TransitionToScenesFromScenes(ILoadSceneInfo[] targetScenes, ILoadSceneInfo[] fromScenes, int setIndexActive, ILoadSceneInfo intermediateSceneInfo = null) + { + TransitionToScenesFromScenesAsync(targetScenes, fromScenes, setIndexActive, intermediateSceneInfo); + } + + public void TransitionToSceneFromScenes(ILoadSceneInfo targetSceneInfo, ILoadSceneInfo[] fromScenes, ILoadSceneInfo intermediateSceneInfo = null) + { + TransitionToSceneFromScenesAsync(targetSceneInfo, fromScenes, intermediateSceneInfo); + } + + public void TransitionToScenesFromAll(ILoadSceneInfo[] targetScenes, int setIndexActive, ILoadSceneInfo intermediateSceneInfo = null) + { + TransitionToScenesFromAllAsync(targetScenes, setIndexActive, intermediateSceneInfo); + } + + public void TransitionToSceneFromAll(ILoadSceneInfo targetSceneInfo, ILoadSceneInfo intermediateSceneInfo = null) + { + TransitionToSceneFromAllAsync(targetSceneInfo, intermediateSceneInfo); + } + public void UnloadScenes(ILoadSceneInfo[] sceneInfos) { UnloadScenesAsync(sceneInfos); @@ -63,6 +83,26 @@ public WaitTask TransitionToSceneAsync(ILoadSceneInfo targetSceneReferenc return new WaitTask(_sceneLoaderAsync.TransitionToSceneAsync(targetSceneReference, intermediateSceneReference).AsTask()); } + public WaitTask TransitionToScenesFromScenesAsync(ILoadSceneInfo[] targetScenes, ILoadSceneInfo[] fromScenes, int setIndexActive, ILoadSceneInfo intermediateSceneReference = null) + { + return new WaitTask(_sceneLoaderAsync.TransitionToScenesFromScenesAsync(targetScenes, fromScenes, setIndexActive, intermediateSceneReference).AsTask()); + } + + public WaitTask TransitionToSceneFromScenesAsync(ILoadSceneInfo targetSceneReference, ILoadSceneInfo[] fromScenes, ILoadSceneInfo intermediateSceneReference = null) + { + return new WaitTask(_sceneLoaderAsync.TransitionToSceneFromScenesAsync(targetSceneReference, fromScenes, intermediateSceneReference).AsTask()); + } + + public WaitTask TransitionToScenesFromAllAsync(ILoadSceneInfo[] targetScenes, int setIndexActive, ILoadSceneInfo intermediateSceneReference = null) + { + return new WaitTask(_sceneLoaderAsync.TransitionToScenesFromAllAsync(targetScenes, setIndexActive, intermediateSceneReference).AsTask()); + } + + public WaitTask TransitionToSceneFromAllAsync(ILoadSceneInfo targetSceneReference, ILoadSceneInfo intermediateSceneReference = null) + { + return new WaitTask(_sceneLoaderAsync.TransitionToSceneFromAllAsync(targetSceneReference, intermediateSceneReference).AsTask()); + } + public WaitTask UnloadScenesAsync(ILoadSceneInfo[] sceneReferences) { return new WaitTask(_sceneLoaderAsync.UnloadScenesAsync(sceneReferences).AsTask()); diff --git a/Packages/com.mygamedevtools.scene-loader/Runtime/SceneLoaders/SceneLoaderUniTask.cs b/Packages/com.mygamedevtools.scene-loader/Runtime/SceneLoaders/SceneLoaderUniTask.cs index 60c99f6..c2c9d9c 100644 --- a/Packages/com.mygamedevtools.scene-loader/Runtime/SceneLoaders/SceneLoaderUniTask.cs +++ b/Packages/com.mygamedevtools.scene-loader/Runtime/SceneLoaders/SceneLoaderUniTask.cs @@ -35,6 +35,26 @@ public void TransitionToScene(ILoadSceneInfo targetSceneInfo, ILoadSceneInfo int TransitionToSceneAsync(targetSceneInfo, intermediateSceneInfo); } + public void TransitionToScenesFromScenes(ILoadSceneInfo[] targetScenes, ILoadSceneInfo[] fromScenes, int setIndexActive, ILoadSceneInfo intermediateSceneInfo = null) + { + TransitionToScenesFromScenesAsync(targetScenes, fromScenes, setIndexActive, intermediateSceneInfo); + } + + public void TransitionToSceneFromScenes(ILoadSceneInfo targetSceneInfo, ILoadSceneInfo[] fromScenes, ILoadSceneInfo intermediateSceneInfo = null) + { + TransitionToSceneFromScenesAsync(targetSceneInfo, fromScenes, intermediateSceneInfo); + } + + public void TransitionToScenesFromAll(ILoadSceneInfo[] targetScenes, int setIndexActive, ILoadSceneInfo intermediateSceneInfo = null) + { + TransitionToScenesFromAllAsync(targetScenes, setIndexActive, intermediateSceneInfo); + } + + public void TransitionToSceneFromAll(ILoadSceneInfo targetSceneInfo, ILoadSceneInfo intermediateSceneInfo = null) + { + TransitionToSceneFromAllAsync(targetSceneInfo, intermediateSceneInfo); + } + public void UnloadScenes(ILoadSceneInfo[] sceneInfos) { UnloadScenesAsync(sceneInfos); @@ -65,6 +85,26 @@ public UniTask TransitionToSceneAsync(ILoadSceneInfo targetSceneReference return _sceneLoaderAsync.TransitionToSceneAsync(targetSceneReference, intermediateSceneReference).AsTask().AsUniTask(); } + public UniTask TransitionToScenesFromScenesAsync(ILoadSceneInfo[] targetScenes, ILoadSceneInfo[] fromScenes, int setIndexActive, ILoadSceneInfo intermediateSceneReference = null) + { + return _sceneLoaderAsync.TransitionToScenesFromScenesAsync(targetScenes, fromScenes, setIndexActive, intermediateSceneReference).AsTask().AsUniTask(); + } + + public UniTask TransitionToSceneFromScenesAsync(ILoadSceneInfo targetSceneReference, ILoadSceneInfo[] fromScenes, ILoadSceneInfo intermediateSceneReference = null) + { + return _sceneLoaderAsync.TransitionToSceneFromScenesAsync(targetSceneReference, fromScenes, intermediateSceneReference).AsTask().AsUniTask(); + } + + public UniTask TransitionToScenesFromAllAsync(ILoadSceneInfo[] targetScenes, int setIndexActive, ILoadSceneInfo intermediateSceneReference = null) + { + return _sceneLoaderAsync.TransitionToScenesFromAllAsync(targetScenes, setIndexActive, intermediateSceneReference).AsTask().AsUniTask(); + } + + public UniTask TransitionToSceneFromAllAsync(ILoadSceneInfo targetSceneReference, ILoadSceneInfo intermediateSceneReference = null) + { + return _sceneLoaderAsync.TransitionToSceneFromAllAsync(targetSceneReference, intermediateSceneReference).AsTask().AsUniTask(); + } + public UniTask UnloadScenesAsync(ILoadSceneInfo[] sceneReferences) { return _sceneLoaderAsync.UnloadScenesAsync(sceneReferences).AsTask().AsUniTask();