Skip to content

Commit ba12fce

Browse files
committed
add reload scene methods and tests
1 parent 4239936 commit ba12fce

File tree

9 files changed

+239
-0
lines changed

9 files changed

+239
-0
lines changed

Packages/com.mygamedevtools.scene-loader/Runtime/CoreSceneManager.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,15 @@ public Task<SceneResult> TransitionAsync(SceneParameters sceneParameters, ILoadS
147147
: TransitionWithIntermediateAsync(sceneParameters, intermediateSceneReference, linkedSource.Token).RunAndDisposeToken(linkedSource);
148148
}
149149

150+
public Task<SceneResult> ReloadActiveSceneAsync(ILoadSceneInfo intermediateSceneReference = null, CancellationToken token = default)
151+
{
152+
if (_activeScene == null || !_activeScene.SceneReference.IsValid() || !_activeScene.SceneReference.isLoaded)
153+
throw new InvalidOperationException($"[{GetType().Name}] Cannot reload the active scene because it is null or not loaded. Make sure to load a scene before trying to reload it.");
154+
155+
ILoadSceneInfo targetSceneInfo = _activeScene.LoadSceneInfo;
156+
return TransitionAsync(new SceneParameters(targetSceneInfo, true), intermediateSceneReference, token);
157+
}
158+
150159
public Task<SceneResult> LoadAsync(SceneParameters sceneParameters, IProgress<float> progress = null, CancellationToken token = default)
151160
{
152161
CancellationTokenSource linkedSource = CancellationTokenSource.CreateLinkedTokenSource(_lifetimeTokenSource.Token, token);

Packages/com.mygamedevtools.scene-loader/Runtime/Interfaces/ISceneManager.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,17 @@ public interface ISceneManager : IDisposable
6969
/// <returns>A <see cref="System.Threading.Tasks.Task{TResult}"/> with all scenes loaded.</returns>
7070
Task<SceneResult> TransitionAsync(SceneParameters sceneParameters, ILoadSceneInfo intermediateSceneReference = default, CancellationToken token = default);
7171

72+
/// <summary>
73+
/// Reloads the active scene with an optional intermediate loading scene.
74+
/// </summary>
75+
/// <param name="intermediateSceneReference">
76+
/// A reference to the scene that's going to be loaded as the transition intermediate (as a loading scene).
77+
/// If null, the transition will not have an intermediate loading scene.
78+
/// </param>
79+
/// <param name="token">Optional token to manually cancel the operation. Note that Unity Scene Manager operations cannot be manually canceled and will continue to run.</param>
80+
/// <returns>A <see cref="System.Threading.Tasks.Task{TResult}"/> with all scenes reloaded.</returns>
81+
Task<SceneResult> ReloadActiveSceneAsync(ILoadSceneInfo intermediateSceneReference = default, CancellationToken token = default);
82+
7283
/// <summary>
7384
/// Loads the target scene or group of scenes provided via a <see cref="SceneParameters"/> struct.
7485
/// You may also provide the desired index to set as the active scene.

Packages/com.mygamedevtools.scene-loader/Runtime/MySceneManager.cs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,17 @@ public static event Action<Scene> SceneLoaded
100100
/// <returns>A <see cref="System.Threading.Tasks.Task{TResult}"/> with all scenes loaded.</returns>
101101
public static Task<SceneResult> TransitionAsync(SceneParameters sceneParameters, ILoadSceneInfo intermediateSceneReference = default, CancellationToken token = default) => Instance.TransitionAsync(sceneParameters, intermediateSceneReference, token);
102102

103+
/// <summary>
104+
/// Reloads the active scene with an optional intermediate loading scene.
105+
/// </summary>
106+
/// <param name="intermediateSceneReference">
107+
/// A reference to the scene that's going to be loaded as the transition intermediate (as a loading scene).
108+
/// If null, the transition will not have an intermediate loading scene.
109+
/// </param>
110+
/// <param name="token">Optional token to manually cancel the operation. Note that Unity Scene Manager operations cannot be manually canceled and will continue to run.</param>
111+
/// <returns>A <see cref="System.Threading.Tasks.Task{TResult}"/> with all scenes reloaded.</returns>
112+
public static Task<SceneResult> ReloadActiveSceneAsync(ILoadSceneInfo intermediateSceneReference = null, CancellationToken token = default) => Instance.ReloadActiveSceneAsync(intermediateSceneReference, token);
113+
103114
/// <summary>
104115
/// Loads the target scene or group of scenes provided via a <see cref="SceneParameters"/> struct.
105116
/// You may also provide the desired index to set as the active scene.
@@ -520,6 +531,52 @@ public static event Action<Scene> SceneLoaded
520531
public static Task<SceneResult> TransitionAddressableAsync(string targetAddress, string loadingAddress = null, CancellationToken token = default) => Instance.TransitionAddressableAsync(targetAddress, loadingAddress, token);
521532
#endif
522533

534+
/// <summary>
535+
/// Reloads the active scene with an optional intermediate loading scene.
536+
/// </summary>
537+
/// <param name="loadingSceneName">
538+
/// A reference to the scene that's going to be loaded as the transition intermediate (as a loading scene).
539+
/// If null, the transition will not have an intermediate loading scene.
540+
/// </param>
541+
/// <param name="token">Optional token to manually cancel the operation. Note that Unity Scene Manager operations cannot be manually canceled and will continue to run.</param>
542+
/// <returns>A <see cref="System.Threading.Tasks.Task{TResult}"/> with all scenes reloaded.</returns>
543+
public static Task<SceneResult> ReloadActiveSceneAsync(string loadingSceneName = null, CancellationToken token = default) => Instance.ReloadActiveSceneAsync(loadingSceneName, token);
544+
545+
/// <summary>
546+
/// Reloads the active scene with an optional intermediate loading scene.
547+
/// </summary>
548+
/// <param name="loadingBuildIndex">
549+
/// A reference to the scene that's going to be loaded as the transition intermediate (as a loading scene).
550+
/// If null, the transition will not have an intermediate loading scene.
551+
/// </param>
552+
/// <param name="token">Optional token to manually cancel the operation. Note that Unity Scene Manager operations cannot be manually canceled and will continue to run.</param>
553+
/// <returns>A <see cref="System.Threading.Tasks.Task{TResult}"/> with all scenes reloaded.</returns>
554+
public static Task<SceneResult> ReloadActiveSceneAsync(int loadingBuildIndex = -1, CancellationToken token = default) => Instance.ReloadActiveSceneAsync(loadingBuildIndex, token);
555+
556+
#if ENABLE_ADDRESSABLES
557+
/// <summary>
558+
/// Reloads the active scene with an optional intermediate loading scene.
559+
/// </summary>
560+
/// <param name="loadingAssetReference">
561+
/// A reference to the scene that's going to be loaded as the transition intermediate (as a loading scene).
562+
/// If null, the transition will not have an intermediate loading scene.
563+
/// </param>
564+
/// <param name="token">Optional token to manually cancel the operation. Note that Unity Scene Manager operations cannot be manually canceled and will continue to run.</param>
565+
/// <returns>A <see cref="System.Threading.Tasks.Task{TResult}"/> with all scenes reloaded.</returns>
566+
public static Task<SceneResult> ReloadActiveSceneAddressableAsync(AssetReference loadingAssetReference = null, CancellationToken token = default) => Instance.ReloadActiveSceneAddressableAsync(loadingAssetReference, token);
567+
568+
/// <summary>
569+
/// Reloads the active scene with an optional intermediate loading scene.
570+
/// </summary>
571+
/// <param name="loadingAddress">
572+
/// A reference to the scene that's going to be loaded as the transition intermediate (as a loading scene).
573+
/// If null, the transition will not have an intermediate loading scene.
574+
/// </param>
575+
/// <param name="token">Optional token to manually cancel the operation. Note that Unity Scene Manager operations cannot be manually canceled and will continue to run.</param>
576+
/// <returns>A <see cref="System.Threading.Tasks.Task{TResult}"/> with all scenes reloaded.</returns>
577+
public static Task<SceneResult> ReloadActiveSceneAddressableAsync(string loadingAddress = null, CancellationToken token = default) => Instance.ReloadActiveSceneAddressableAsync(loadingAddress, token);
578+
#endif
579+
523580
/// <summary>
524581
/// Unloads the target scene or group of scenes.
525582
/// </summary>

Packages/com.mygamedevtools.scene-loader/Runtime/Utilities/SceneManagerExtensions.cs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,68 @@ public static Task<SceneResult> TransitionAddressableAsync(this ISceneManager sc
447447
}
448448
#endif
449449

450+
/// <summary>
451+
/// Reloads the active scene with an optional intermediate loading scene.
452+
/// </summary>
453+
/// <param name="loadingSceneName">
454+
/// A reference to the scene that's going to be loaded as the transition intermediate (as a loading scene).
455+
/// If null, the transition will not have an intermediate loading scene.
456+
/// </param>
457+
/// <param name="token">Optional token to manually cancel the operation. Note that Unity Scene Manager operations cannot be manually canceled and will continue to run.</param>
458+
/// <returns>A <see cref="System.Threading.Tasks.Task{TResult}"/> with all scenes reloaded.</returns>
459+
public static Task<SceneResult> ReloadActiveSceneAsync(this ISceneManager sceneManager, string loadingSceneName = null, CancellationToken token = default)
460+
{
461+
ILoadSceneInfo loadingSceneInfo = string.IsNullOrWhiteSpace(loadingSceneName) ? null : new LoadSceneInfoName(loadingSceneName);
462+
return sceneManager.ReloadActiveSceneAsync(loadingSceneInfo, token);
463+
}
464+
465+
/// <summary>
466+
/// Reloads the active scene with an optional intermediate loading scene.
467+
/// </summary>
468+
/// <param name="loadingBuildIndex">
469+
/// A reference to the scene that's going to be loaded as the transition intermediate (as a loading scene).
470+
/// If null, the transition will not have an intermediate loading scene.
471+
/// </param>
472+
/// <param name="token">Optional token to manually cancel the operation. Note that Unity Scene Manager operations cannot be manually canceled and will continue to run.</param>
473+
/// <returns>A <see cref="System.Threading.Tasks.Task{TResult}"/> with all scenes reloaded.</returns>
474+
public static Task<SceneResult> ReloadActiveSceneAsync(this ISceneManager sceneManager, int loadingBuildIndex = -1, CancellationToken token = default)
475+
{
476+
ILoadSceneInfo loadingSceneInfo = loadingBuildIndex >= 0 ? new LoadSceneInfoIndex(loadingBuildIndex) : null;
477+
return sceneManager.ReloadActiveSceneAsync(loadingSceneInfo, token);
478+
}
479+
480+
#if ENABLE_ADDRESSABLES
481+
/// <summary>
482+
/// Reloads the active scene with an optional intermediate loading scene.
483+
/// </summary>
484+
/// <param name="loadingAssetReference">
485+
/// A reference to the scene that's going to be loaded as the transition intermediate (as a loading scene).
486+
/// If null, the transition will not have an intermediate loading scene.
487+
/// </param>
488+
/// <param name="token">Optional token to manually cancel the operation. Note that Unity Scene Manager operations cannot be manually canceled and will continue to run.</param>
489+
/// <returns>A <see cref="System.Threading.Tasks.Task{TResult}"/> with all scenes reloaded.</returns>
490+
public static Task<SceneResult> ReloadActiveSceneAddressableAsync(this ISceneManager sceneManager, AssetReference loadingAssetReference = null, CancellationToken token = default)
491+
{
492+
ILoadSceneInfo loadingSceneInfo = loadingAssetReference != null ? new LoadSceneInfoAssetReference(loadingAssetReference) : null;
493+
return sceneManager.ReloadActiveSceneAsync(loadingSceneInfo, token);
494+
}
495+
496+
/// <summary>
497+
/// Reloads the active scene with an optional intermediate loading scene.
498+
/// </summary>
499+
/// <param name="loadingAddress">
500+
/// A reference to the scene that's going to be loaded as the transition intermediate (as a loading scene).
501+
/// If null, the transition will not have an intermediate loading scene.
502+
/// </param>
503+
/// <param name="token">Optional token to manually cancel the operation. Note that Unity Scene Manager operations cannot be manually canceled and will continue to run.</param>
504+
/// <returns>A <see cref="System.Threading.Tasks.Task{TResult}"/> with all scenes reloaded.</returns>
505+
public static Task<SceneResult> ReloadActiveSceneAddressableAsync(this ISceneManager sceneManager, string loadingAddress = null, CancellationToken token = default)
506+
{
507+
ILoadSceneInfo loadingSceneInfo = string.IsNullOrWhiteSpace(loadingAddress) ? null : new LoadSceneInfoAddress(loadingAddress);
508+
return sceneManager.ReloadActiveSceneAsync(loadingSceneInfo, token);
509+
}
510+
#endif
511+
450512
/// <summary>
451513
/// Unloads the target scene or group of scenes.
452514
/// </summary>

Packages/com.mygamedevtools.scene-loader/Tests/Runtime/SceneManagerTests.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,12 @@ public void Unload_NotLoaded([ValueSource(typeof(SceneTestEnvironment), nameof(S
238238
Assert.Throws<AggregateException>(() => wait.MoveNext());
239239
}
240240

241+
[UnityTest]
242+
public IEnumerator Reload([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager, [ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SingleLoadSceneInfoList))] ILoadSceneInfo loadSceneInfo, [ValueSource(nameof(LoadingSceneInfos))] ILoadSceneInfo loadingScene)
243+
{
244+
yield return Reload_Template(manager, loadSceneInfo, () => manager.ReloadActiveSceneAsync(loadingScene));
245+
}
246+
241247
[UnityTest]
242248
public IEnumerator Transition([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager, [ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.
243249
TransitionSceneParametersList))] SceneParameters sceneParameters, [ValueSource(nameof(LoadingSceneInfos))] ILoadSceneInfo loadingScene)
@@ -367,6 +373,21 @@ public IEnumerator Load_Template(ISceneManager manager, Func<Task<SceneResult>>
367373
void reportSceneLoaded(Scene loadedScene) => reportedScenes.Add(loadedScene);
368374
}
369375

376+
public IEnumerator Reload_Template(ISceneManager manager, ILoadSceneInfo loadSceneInfo, Func<Task<SceneResult>> reloadTask)
377+
{
378+
yield return manager.LoadAsync(new SceneParameters(loadSceneInfo, true)).ToWaitTask();
379+
string activeScene = manager.GetActiveScene().name;
380+
381+
var task = reloadTask();
382+
yield return task.ToWaitTask();
383+
384+
Scene loadedScene = task.Result;
385+
Assert.AreEqual(manager.GetActiveScene(), loadedScene);
386+
Assert.AreEqual(activeScene, loadedScene.name);
387+
388+
yield return new WaitUntil(() => manager.TotalSceneCount == 1);
389+
}
390+
370391
public IEnumerator Transition_Template(ISceneManager manager, Func<Task<SceneResult>> transitionTask, int sceneCount, int setIndexActive)
371392
{
372393
yield return LoadFirstScene(manager);

Packages/com.mygamedevtools.scene-loader/Tests/Runtime/SceneManager_AssetReferenceTests.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ public IEnumerator Load_AssetReference([ValueSource(typeof(SceneTestEnvironment)
4141
yield return Load(manager, new SceneParameters(_assetReferenceLoadSceneInfos, setIndexActive));
4242
}
4343

44+
[UnityTest]
45+
public IEnumerator Reload_AssetReference([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager, [ValueSource(nameof(LoadingSceneInfos))] ILoadSceneInfo loadingScene)
46+
{
47+
yield return Reload(manager, _assetReferenceLoadSceneInfos[0], loadingScene);
48+
}
49+
4450
[UnityTest]
4551
public IEnumerator Unload_AssetReference([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager)
4652
{

Packages/com.mygamedevtools.scene-loader/Tests/Runtime/SceneManager_ExtensionTests.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,32 @@ public IEnumerator Transition_Extension_Addressable_ByAssetReference_Multiple([V
117117
}
118118
#endif
119119

120+
[UnityTest]
121+
public IEnumerator Reload_Extension_ByName([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager)
122+
{
123+
yield return Reload_Template(manager, new LoadSceneInfoName(SceneBuilder.SceneNames[1]), () => manager.ReloadActiveSceneAsync(SceneBuilder.SceneNames[1]));
124+
}
125+
126+
[UnityTest]
127+
public IEnumerator Reload_Extension_ByIndex([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager)
128+
{
129+
yield return Reload_Template(manager, new LoadSceneInfoIndex(1), () => manager.ReloadActiveSceneAsync(1));
130+
}
131+
132+
#if ENABLE_ADDRESSABLES
133+
[UnityTest]
134+
public IEnumerator Reload_Extension_Addressable_ByAddress([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager)
135+
{
136+
yield return Reload_Template(manager, new LoadSceneInfoAddress(SceneBuilder.SceneNames[1]), () => manager.ReloadActiveSceneAddressableAsync(SceneBuilder.SceneNames[1]));
137+
}
138+
139+
[UnityTest]
140+
public IEnumerator Reload_Extension_Addressable_ByAssetReference([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager)
141+
{
142+
yield return Reload_Template(manager, new LoadSceneInfoAssetReference(_assetReferences[1]), () => manager.ReloadActiveSceneAddressableAsync(_assetReferences[1]));
143+
}
144+
#endif
145+
120146
[UnityTest]
121147
public IEnumerator Unload_Extension_ByIndex([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager)
122148
{

Packages/com.mygamedevtools.scene-loader/Tests/Runtime/StaticSceneManager_ExtensionTests.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,32 @@ public IEnumerator Transition_Extension_Addressable_ByAssetReference_Multiple()
137137
}
138138
#endif
139139

140+
[UnityTest]
141+
public IEnumerator Reload_Extension_ByName()
142+
{
143+
yield return Reload_Template(new LoadSceneInfoName(SceneBuilder.SceneNames[1]), () => MySceneManager.ReloadActiveSceneAsync(SceneBuilder.SceneNames[1]));
144+
}
145+
146+
[UnityTest]
147+
public IEnumerator Reload_Extension_ByIndex()
148+
{
149+
yield return Reload_Template(new LoadSceneInfoIndex(1), () => MySceneManager.ReloadActiveSceneAsync(1));
150+
}
151+
152+
#if ENABLE_ADDRESSABLES
153+
[UnityTest]
154+
public IEnumerator Reload_Extension_Addressable_ByAddress()
155+
{
156+
yield return Reload_Template(new LoadSceneInfoAddress(SceneBuilder.SceneNames[1]), () => MySceneManager.ReloadActiveSceneAddressableAsync(SceneBuilder.SceneNames[1]));
157+
}
158+
159+
[UnityTest]
160+
public IEnumerator Reload_Extension_Addressable_ByAssetReference()
161+
{
162+
yield return Reload_Template(new LoadSceneInfoAssetReference(_assetReferences[1]), () => MySceneManager.ReloadActiveSceneAddressableAsync(_assetReferences[1]));
163+
}
164+
#endif
165+
140166
[UnityTest]
141167
public IEnumerator Unload_Extension_ByIndex()
142168
{

0 commit comments

Comments
 (0)