Skip to content

Commit

Permalink
add new transitions to scene loaders
Browse files Browse the repository at this point in the history
  • Loading branch information
joaoborks committed Aug 26, 2024
1 parent fe03993 commit 2f2fcf4
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -59,9 +79,11 @@ public void LoadScene(ILoadSceneInfo sceneInfo, bool setActive = false)

public ValueTask<Scene[]> 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<Scene> TransitionToSceneAsync(ILoadSceneInfo targetSceneInfo, ILoadSceneInfo intermediateSceneInfo = default)
Expand All @@ -70,6 +92,33 @@ public async ValueTask<Scene> TransitionToSceneAsync(ILoadSceneInfo targetSceneI
return result == null || result.Length == 0 ? default : result[0];
}

public ValueTask<Scene[]> 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<Scene> 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<Scene[]> 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<Scene> 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<Scene[]> LoadScenesAsync(ILoadSceneInfo[] sceneReferences, int setIndexActive = -1, IProgress<float> progress = null)
{
return _manager.LoadScenesAsync(sceneReferences, setIndexActive, progress, _lifetimeTokenSource.Token);
Expand All @@ -90,15 +139,15 @@ public ValueTask<Scene> UnloadSceneAsync(ILoadSceneInfo sceneInfo)
return _manager.UnloadSceneAsync(sceneInfo, _lifetimeTokenSource.Token);
}

async ValueTask<Scene[]> TransitionDirectlyAsync(ILoadSceneInfo[] targetScenes, int setIndexActive, CancellationToken token)
async ValueTask<Scene[]> 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;
if (SceneManager.sceneCount <= 1)
{
tempScene = SceneManager.CreateScene("temp-transition-scene");
}
await UnloadSourceSceneAsync(token);
await UnloadSourceScenesAsync(fromScenes, token);

Scene[] loadedScenes = await _manager.LoadScenesAsync(targetScenes, setIndexActive, token: token);

Expand All @@ -109,7 +158,7 @@ async ValueTask<Scene[]> TransitionDirectlyAsync(ILoadSceneInfo[] targetScenes,
return loadedScenes;
}

async ValueTask<Scene[]> TransitionWithIntermediateAsync(ILoadSceneInfo[] targetScenes, int setIndexActive, ILoadSceneInfo intermediateSceneInfo, CancellationToken token)
async ValueTask<Scene[]> TransitionWithIntermediateAsync(ILoadSceneInfo[] targetScenes, ILoadSceneInfo[] fromScenes, int setIndexActive, ILoadSceneInfo intermediateSceneInfo, CancellationToken token)
{
Scene loadingScene;
try
Expand All @@ -129,19 +178,19 @@ async ValueTask<Scene[]> TransitionWithIntermediateAsync(ILoadSceneInfo[] target
LoadingBehavior loadingBehavior = UnityEngine.Object.FindObjectsOfType<LoadingBehavior>().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<Scene[]> TransitionWithIntermediateLoadingAsync(ILoadSceneInfo[] targetScenes, int setIndexActive, ILoadSceneInfo intermediateSceneInfo, LoadingBehavior loadingBehavior, CancellationToken token)
async ValueTask<Scene[]> TransitionWithIntermediateLoadingAsync(ILoadSceneInfo[] targetScenes, ILoadSceneInfo[] fromScenes, int setIndexActive, ILoadSceneInfo intermediateSceneInfo, LoadingBehavior loadingBehavior, CancellationToken token)
{
LoadingProgress progress = loadingBehavior.Progress;
while (progress.State != LoadingState.Loading && !token.IsCancellationRequested)
await Task.Yield();

token.ThrowIfCancellationRequested();

await UnloadSourceSceneAsync(token);
await UnloadSourceScenesAsync(fromScenes, token);

Scene[] loadedScenes = await _manager.LoadScenesAsync(targetScenes, setIndexActive, progress, token);
progress.SetState(LoadingState.TargetSceneLoaded);
Expand All @@ -155,21 +204,31 @@ async ValueTask<Scene[]> TransitionWithIntermediateLoadingAsync(ILoadSceneInfo[]
return loadedScenes;
}

async ValueTask<Scene[]> TransitionWithIntermediateNoLoadingAsync(ILoadSceneInfo[] targetScenes, int setIndexActive, ILoadSceneInfo intermediateSceneInfo, CancellationToken token)
async ValueTask<Scene[]> 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<Scene> UnloadSourceSceneAsync(CancellationToken token)
ValueTask<Scene[]> 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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -63,6 +83,26 @@ public WaitTask<Scene> TransitionToSceneAsync(ILoadSceneInfo targetSceneReferenc
return new WaitTask<Scene>(_sceneLoaderAsync.TransitionToSceneAsync(targetSceneReference, intermediateSceneReference).AsTask());
}

public WaitTask<Scene[]> TransitionToScenesFromScenesAsync(ILoadSceneInfo[] targetScenes, ILoadSceneInfo[] fromScenes, int setIndexActive, ILoadSceneInfo intermediateSceneReference = null)
{
return new WaitTask<Scene[]>(_sceneLoaderAsync.TransitionToScenesFromScenesAsync(targetScenes, fromScenes, setIndexActive, intermediateSceneReference).AsTask());
}

public WaitTask<Scene> TransitionToSceneFromScenesAsync(ILoadSceneInfo targetSceneReference, ILoadSceneInfo[] fromScenes, ILoadSceneInfo intermediateSceneReference = null)
{
return new WaitTask<Scene>(_sceneLoaderAsync.TransitionToSceneFromScenesAsync(targetSceneReference, fromScenes, intermediateSceneReference).AsTask());
}

public WaitTask<Scene[]> TransitionToScenesFromAllAsync(ILoadSceneInfo[] targetScenes, int setIndexActive, ILoadSceneInfo intermediateSceneReference = null)
{
return new WaitTask<Scene[]>(_sceneLoaderAsync.TransitionToScenesFromAllAsync(targetScenes, setIndexActive, intermediateSceneReference).AsTask());
}

public WaitTask<Scene> TransitionToSceneFromAllAsync(ILoadSceneInfo targetSceneReference, ILoadSceneInfo intermediateSceneReference = null)
{
return new WaitTask<Scene>(_sceneLoaderAsync.TransitionToSceneFromAllAsync(targetSceneReference, intermediateSceneReference).AsTask());
}

public WaitTask<Scene[]> UnloadScenesAsync(ILoadSceneInfo[] sceneReferences)
{
return new WaitTask<Scene[]>(_sceneLoaderAsync.UnloadScenesAsync(sceneReferences).AsTask());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -65,6 +85,26 @@ public UniTask<Scene> TransitionToSceneAsync(ILoadSceneInfo targetSceneReference
return _sceneLoaderAsync.TransitionToSceneAsync(targetSceneReference, intermediateSceneReference).AsTask().AsUniTask();
}

public UniTask<Scene[]> TransitionToScenesFromScenesAsync(ILoadSceneInfo[] targetScenes, ILoadSceneInfo[] fromScenes, int setIndexActive, ILoadSceneInfo intermediateSceneReference = null)
{
return _sceneLoaderAsync.TransitionToScenesFromScenesAsync(targetScenes, fromScenes, setIndexActive, intermediateSceneReference).AsTask().AsUniTask();
}

public UniTask<Scene> TransitionToSceneFromScenesAsync(ILoadSceneInfo targetSceneReference, ILoadSceneInfo[] fromScenes, ILoadSceneInfo intermediateSceneReference = null)
{
return _sceneLoaderAsync.TransitionToSceneFromScenesAsync(targetSceneReference, fromScenes, intermediateSceneReference).AsTask().AsUniTask();
}

public UniTask<Scene[]> TransitionToScenesFromAllAsync(ILoadSceneInfo[] targetScenes, int setIndexActive, ILoadSceneInfo intermediateSceneReference = null)
{
return _sceneLoaderAsync.TransitionToScenesFromAllAsync(targetScenes, setIndexActive, intermediateSceneReference).AsTask().AsUniTask();
}

public UniTask<Scene> TransitionToSceneFromAllAsync(ILoadSceneInfo targetSceneReference, ILoadSceneInfo intermediateSceneReference = null)
{
return _sceneLoaderAsync.TransitionToSceneFromAllAsync(targetSceneReference, intermediateSceneReference).AsTask().AsUniTask();
}

public UniTask<Scene[]> UnloadScenesAsync(ILoadSceneInfo[] sceneReferences)
{
return _sceneLoaderAsync.UnloadScenesAsync(sceneReferences).AsTask().AsUniTask();
Expand Down

0 comments on commit 2f2fcf4

Please sign in to comment.