diff --git a/Packages/com.mygamedevtools.scene-loader/Runtime/AdvancedSceneManager.cs b/Packages/com.mygamedevtools.scene-loader/Runtime/AdvancedSceneManager.cs index b9044ff..95c01b4 100644 --- a/Packages/com.mygamedevtools.scene-loader/Runtime/AdvancedSceneManager.cs +++ b/Packages/com.mygamedevtools.scene-loader/Runtime/AdvancedSceneManager.cs @@ -138,6 +138,9 @@ public Scene GetLoadedSceneByName(string name) public ValueTask TransitionAsync(SceneParameters sceneParameters, ILoadSceneInfo intermediateSceneReference = null, CancellationToken token = default) { + if (!sceneParameters.ShouldSetActive()) + throw new ArgumentException($"[{GetType().Name}] You need to provide a SceneParameters object with a valid 'setIndexActive' value to perform scene transitions.", nameof(sceneParameters)); + CancellationTokenSource linkedSource = CancellationTokenSource.CreateLinkedTokenSource(_lifetimeTokenSource.Token, token); return intermediateSceneReference == null ? TransitionDirectlyAsync(sceneParameters, linkedSource.Token).RunAndDisposeToken(linkedSource) diff --git a/Packages/com.mygamedevtools.scene-loader/Runtime/Utilities/SceneManagerExtensions.cs b/Packages/com.mygamedevtools.scene-loader/Runtime/Utilities/SceneManagerExtensions.cs index 5647f11..26e7bbb 100644 --- a/Packages/com.mygamedevtools.scene-loader/Runtime/Utilities/SceneManagerExtensions.cs +++ b/Packages/com.mygamedevtools.scene-loader/Runtime/Utilities/SceneManagerExtensions.cs @@ -224,16 +224,16 @@ public static ValueTask LoadAddressableAsync(this ISceneManager sce /// /// An array of scenes by their names to transition to. /// - /// - /// The index of the scene to be activated as the active scene. - /// /// /// A reference to the scene that's going to be loaded as the transition intermediate (as a loading scene). /// If null, the transition will not have an intermediate loading scene. /// + /// + /// The index of the scene to be activated as the active scene. It must be greater than or equal 0. + /// /// Optional token to manually cancel the operation. Note that Unity Scene Manager operations cannot be manually canceled and will continue to run. /// A with all scenes loaded. - public static ValueTask TransitionAsync(this ISceneManager sceneManager, string[] targetSceneNames, int setIndexActive = -1, string loadingSceneName = null, CancellationToken token = default) + public static ValueTask TransitionAsync(this ISceneManager sceneManager, string[] targetSceneNames, string loadingSceneName = null, int setIndexActive = 0, CancellationToken token = default) { SceneParameters targetParams = new(targetSceneNames.Select(name => (ILoadSceneInfo)new LoadSceneInfoName(name)).ToArray(), setIndexActive); ILoadSceneInfo loadingSceneInfo = string.IsNullOrWhiteSpace(loadingSceneName) ? null : new LoadSceneInfoName(loadingSceneName); @@ -255,19 +255,19 @@ public static ValueTask TransitionAsync(this ISceneManager sceneMan /// /// An array of scenes by their build index to transition to. /// - /// - /// The index of the scene to be activated as the active scene. - /// /// /// A reference to the scene that's going to be loaded as the transition intermediate (as a loading scene). /// If null, the transition will not have an intermediate loading scene. /// + /// + /// The index of the scene to be activated as the active scene. It must be greater than or equal 0. + /// /// Optional token to manually cancel the operation. Note that Unity Scene Manager operations cannot be manually canceled and will continue to run. /// A with all scenes loaded. - public static ValueTask TransitionAsync(this ISceneManager sceneManager, int[] targetBuildIndices, int setIndexActive = -1, int? loadingBuildIndex = null, CancellationToken token = default) + public static ValueTask TransitionAsync(this ISceneManager sceneManager, int[] targetBuildIndices, int loadingBuildIndex = -1, int setIndexActive = 0, CancellationToken token = default) { SceneParameters targetParams = new(targetBuildIndices.Select(index => (ILoadSceneInfo)new LoadSceneInfoIndex(index)).ToArray(), setIndexActive); - ILoadSceneInfo loadingSceneInfo = loadingBuildIndex.HasValue ? new LoadSceneInfoIndex(loadingBuildIndex.Value) : null; + ILoadSceneInfo loadingSceneInfo = loadingBuildIndex >= 0 ? new LoadSceneInfoIndex(loadingBuildIndex) : null; return sceneManager.TransitionAsync(targetParams, loadingSceneInfo, token); } @@ -286,18 +286,15 @@ public static ValueTask TransitionAsync(this ISceneManager sceneMan /// /// The target scene name to be transitioned to. /// - /// - /// The index of the scene to be activated as the active scene. - /// /// /// A reference to the scene that's going to be loaded as the transition intermediate (as a loading scene). /// If null, the transition will not have an intermediate loading scene. /// /// Optional token to manually cancel the operation. Note that Unity Scene Manager operations cannot be manually canceled and will continue to run. /// A with all scenes loaded. - public static ValueTask TransitionAsync(this ISceneManager sceneManager, string targetSceneName, bool setActive = false, string loadingSceneName = null, CancellationToken token = default) + public static ValueTask TransitionAsync(this ISceneManager sceneManager, string targetSceneName, string loadingSceneName = null, CancellationToken token = default) { - SceneParameters targetParams = new(new LoadSceneInfoName(targetSceneName), setActive); + SceneParameters targetParams = new(new LoadSceneInfoName(targetSceneName), true); ILoadSceneInfo loadingSceneInfo = string.IsNullOrWhiteSpace(loadingSceneName) ? null : new LoadSceneInfoName(loadingSceneName); return sceneManager.TransitionAsync(targetParams, loadingSceneInfo, token); } @@ -317,19 +314,16 @@ public static ValueTask TransitionAsync(this ISceneManager sceneMan /// /// The target scene build index to be transitioned to. /// - /// - /// The index of the scene to be activated as the active scene. - /// /// /// A reference to the scene that's going to be loaded as the transition intermediate (as a loading scene). - /// If null, the transition will not have an intermediate loading scene. + /// If -1, the transition will not have an intermediate loading scene. /// /// Optional token to manually cancel the operation. Note that Unity Scene Manager operations cannot be manually canceled and will continue to run. /// A with all scenes loaded. - public static ValueTask TransitionAsync(this ISceneManager sceneManager, int targetBuildIndex, bool setActive = false, int? loadingBuildIndex = null, CancellationToken token = default) + public static ValueTask TransitionAsync(this ISceneManager sceneManager, int targetBuildIndex, int loadingBuildIndex = -1, CancellationToken token = default) { - SceneParameters targetParams = new(new LoadSceneInfoIndex(targetBuildIndex), setActive); - ILoadSceneInfo loadingSceneInfo = loadingBuildIndex.HasValue ? new LoadSceneInfoIndex(loadingBuildIndex.Value) : null; + SceneParameters targetParams = new(new LoadSceneInfoIndex(targetBuildIndex), true); + ILoadSceneInfo loadingSceneInfo = loadingBuildIndex >= 0 ? new LoadSceneInfoIndex(loadingBuildIndex) : null; return sceneManager.TransitionAsync(targetParams, loadingSceneInfo, token); } @@ -349,16 +343,16 @@ public static ValueTask TransitionAsync(this ISceneManager sceneMan /// /// An array of scenes by their to transition to. /// - /// - /// The index of the scene to be activated as the active scene. - /// /// /// A reference to the scene that's going to be loaded as the transition intermediate (as a loading scene). /// If null, the transition will not have an intermediate loading scene. /// + /// + /// The index of the scene to be activated as the active scene. It must be greater than or equal 0. + /// /// Optional token to manually cancel the operation. Note that Unity Scene Manager operations cannot be manually canceled and will continue to run. /// A with all scenes loaded. - public static ValueTask TransitionAddressableAsync(this ISceneManager sceneManager, AssetReference[] targetAssetReferences, int setIndexActive = -1, AssetReference loadingAssetReference = null, CancellationToken token = default) + public static ValueTask TransitionAddressableAsync(this ISceneManager sceneManager, AssetReference[] targetAssetReferences, AssetReference loadingAssetReference = null, int setIndexActive = 0, CancellationToken token = default) { SceneParameters targetParams = new(targetAssetReferences.Select(asset => (ILoadSceneInfo)new LoadSceneInfoAssetReference(asset)).ToArray(), setIndexActive); ILoadSceneInfo loadingSceneInfo = loadingAssetReference != null ? new LoadSceneInfoAssetReference(loadingAssetReference) : null; @@ -380,16 +374,16 @@ public static ValueTask TransitionAddressableAsync(this ISceneManag /// /// An array of scenes by their addressable addresses to transition to. /// - /// - /// The index of the scene to be activated as the active scene. - /// /// /// A reference to the scene that's going to be loaded as the transition intermediate (as a loading scene). /// If null, the transition will not have an intermediate loading scene. /// + /// + /// The index of the scene to be activated as the active scene. It must be greater than or equal 0. + /// /// Optional token to manually cancel the operation. Note that Unity Scene Manager operations cannot be manually canceled and will continue to run. /// A with all scenes loaded. - public static ValueTask TransitionAddressableAsync(this ISceneManager sceneManager, string[] targetAddresses, int setIndexActive = -1, string loadingAddress = null, CancellationToken token = default) + public static ValueTask TransitionAddressableAsync(this ISceneManager sceneManager, string[] targetAddresses, string loadingAddress = null, int setIndexActive = 0, CancellationToken token = default) { SceneParameters targetParams = new(targetAddresses.Select(address => (ILoadSceneInfo)new LoadSceneInfoAddress(address)).ToArray(), setIndexActive); ILoadSceneInfo loadingSceneInfo = string.IsNullOrWhiteSpace(loadingAddress) ? null : new LoadSceneInfoAddress(loadingAddress); @@ -411,18 +405,15 @@ public static ValueTask TransitionAddressableAsync(this ISceneManag /// /// The target scene to be transitioned to. /// - /// - /// The index of the scene to be activated as the active scene. - /// /// /// A reference to the scene that's going to be loaded as the transition intermediate (as a loading scene). /// If null, the transition will not have an intermediate loading scene. /// /// Optional token to manually cancel the operation. Note that Unity Scene Manager operations cannot be manually canceled and will continue to run. /// A with all scenes loaded. - public static ValueTask TransitionAddressableAsync(this ISceneManager sceneManager, AssetReference targetAssetReference, bool setActive = false, AssetReference loadingAssetReference = null, CancellationToken token = default) + public static ValueTask TransitionAddressableAsync(this ISceneManager sceneManager, AssetReference targetAssetReference, AssetReference loadingAssetReference = null, CancellationToken token = default) { - SceneParameters targetParams = new(new LoadSceneInfoAssetReference(targetAssetReference), setActive); + SceneParameters targetParams = new(new LoadSceneInfoAssetReference(targetAssetReference), true); ILoadSceneInfo loadingSceneInfo = loadingAssetReference != null ? new LoadSceneInfoAssetReference(loadingAssetReference) : null; return sceneManager.TransitionAsync(targetParams, loadingSceneInfo, token); } @@ -442,18 +433,15 @@ public static ValueTask TransitionAddressableAsync(this ISceneManag /// /// The target scene addressable address to be transitioned to. /// - /// - /// The index of the scene to be activated as the active scene. - /// /// /// A reference to the scene that's going to be loaded as the transition intermediate (as a loading scene). /// If null, the transition will not have an intermediate loading scene. /// /// Optional token to manually cancel the operation. Note that Unity Scene Manager operations cannot be manually canceled and will continue to run. /// A with all scenes loaded. - public static ValueTask TransitionAddressableAsync(this ISceneManager sceneManager, string targetAddress, bool setActive = false, string loadingAddress = null, CancellationToken token = default) + public static ValueTask TransitionAddressableAsync(this ISceneManager sceneManager, string targetAddress, string loadingAddress = null, CancellationToken token = default) { - SceneParameters targetParams = new(new LoadSceneInfoAddress(targetAddress), setActive); + SceneParameters targetParams = new(new LoadSceneInfoAddress(targetAddress), true); ILoadSceneInfo loadingSceneInfo = string.IsNullOrWhiteSpace(loadingAddress) ? null : new LoadSceneInfoAddress(loadingAddress); return sceneManager.TransitionAsync(targetParams, loadingSceneInfo, token); } diff --git a/Packages/com.mygamedevtools.scene-loader/Tests/Runtime/SceneManagerTests.cs b/Packages/com.mygamedevtools.scene-loader/Tests/Runtime/SceneManagerTests.cs index 6fd6be7..c615783 100644 --- a/Packages/com.mygamedevtools.scene-loader/Tests/Runtime/SceneManagerTests.cs +++ b/Packages/com.mygamedevtools.scene-loader/Tests/Runtime/SceneManagerTests.cs @@ -20,6 +20,9 @@ public partial class SceneManagerTests : SceneTestBase new LoadSceneInfoName(SceneBuilder.SceneNames[0]), }; + static readonly bool[] _setActiveParameterValues = new[] { false, true }; + static readonly int[] _setIndexActiveParameterValues = new[] { -1, 1 }; + int _scenesActivated; int _scenesUnloaded; int _scenesLoaded; @@ -237,7 +240,8 @@ public void Unload_NotLoaded([ValueSource(typeof(SceneTestEnvironment), nameof(S } [UnityTest] - public IEnumerator Transition([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager, [ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneParametersList))] SceneParameters sceneParameters, [ValueSource(nameof(LoadingSceneInfos))] ILoadSceneInfo loadingScene) + public IEnumerator Transition([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager, [ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment. + TransitionSceneParametersList))] SceneParameters sceneParameters, [ValueSource(nameof(LoadingSceneInfos))] ILoadSceneInfo loadingScene) { yield return Transition_Template(manager, () => manager.TransitionAsync(sceneParameters, loadingScene).AsTask(), sceneParameters.Length, sceneParameters.GetIndexToActivate()); } @@ -327,8 +331,7 @@ public IEnumerator Transition_Template(ISceneManager manager, Func= 0) - Assert.AreEqual(loadedScenes[setIndexActive], manager.GetActiveScene()); + Assert.AreEqual(loadedScenes[setIndexActive], manager.GetActiveScene()); yield return new WaitUntil(() => manager.TotalSceneCount == sceneCount); } diff --git a/Packages/com.mygamedevtools.scene-loader/Tests/Runtime/SceneManager_AssetReferenceTests.cs b/Packages/com.mygamedevtools.scene-loader/Tests/Runtime/SceneManager_AssetReferenceTests.cs index 47d1132..b6a8e45 100644 --- a/Packages/com.mygamedevtools.scene-loader/Tests/Runtime/SceneManager_AssetReferenceTests.cs +++ b/Packages/com.mygamedevtools.scene-loader/Tests/Runtime/SceneManager_AssetReferenceTests.cs @@ -12,10 +12,9 @@ namespace MyGameDevTools.SceneLoading.Tests // Unity Editor sessions. So, we must test AssetReference load scene infos "manually". public partial class SceneManagerTests { + AssetReference[] _assetReferences; ILoadSceneInfo[] _assetReferenceLoadSceneInfos; - static readonly int[] _setIndexActiveParameterValues = new[] { -1, 1 }; - [OneTimeSetUp] public void AssetReferenceSetup() { @@ -23,6 +22,7 @@ public void AssetReferenceSetup() operationHandle.WaitForCompletion(); SceneReferenceData sceneReferenceData = operationHandle.Result; + _assetReferences = sceneReferenceData.sceneReferences.ToArray(); _assetReferenceLoadSceneInfos = new ILoadSceneInfo[] { @@ -36,13 +36,13 @@ public void AssetReferenceSetup() } [UnityTest] - public IEnumerator LoadScenes_AssetReference([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager, [ValueSource(nameof(_setIndexActiveParameterValues))] int setIndexActive) + public IEnumerator Load_AssetReference([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager, [ValueSource(nameof(_setIndexActiveParameterValues))] int setIndexActive) { yield return Load(manager, new SceneParameters(_assetReferenceLoadSceneInfos, setIndexActive)); } [UnityTest] - public IEnumerator UnloadScenes_AssetReference([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager) + public IEnumerator Unload_AssetReference([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager) { yield return Unload(manager, new SceneParameters(_assetReferenceLoadSceneInfos)); } diff --git a/Packages/com.mygamedevtools.scene-loader/Tests/Runtime/SceneManager_CancellationTests.cs b/Packages/com.mygamedevtools.scene-loader/Tests/Runtime/SceneManager_CancellationTests.cs index 30d81eb..3ff4905 100644 --- a/Packages/com.mygamedevtools.scene-loader/Tests/Runtime/SceneManager_CancellationTests.cs +++ b/Packages/com.mygamedevtools.scene-loader/Tests/Runtime/SceneManager_CancellationTests.cs @@ -8,36 +8,10 @@ namespace MyGameDevTools.SceneLoading.Tests public class SceneManager_CancellationTests : SceneTestBase { [UnityTest] - public IEnumerator Cancellation_DuringLoadScene([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager, [ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SingleLoadSceneInfoList))] ILoadSceneInfo sceneInfo) + public IEnumerator Cancellation_DuringLoad([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager, [ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneParametersList))] SceneParameters sceneParameters) { CancellationTokenSource tokenSource = new(); - WaitTask waitTask = new(manager.LoadAsync(new SceneParameters(sceneInfo), token: tokenSource.Token).AsTask()); - tokenSource.Cancel(); - yield return waitTask; - Assert.That(waitTask.Task.IsCompleted); - tokenSource.Dispose(); - } - - [UnityTest] - public IEnumerator Cancellation_DuringLoadScenes([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager, [ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.MultipleLoadSceneInfoList))] ILoadSceneInfo[] sceneInfos) - { - CancellationTokenSource tokenSource = new(); - WaitTask waitTask = new(manager.LoadAsync(new SceneParameters(sceneInfos), token: tokenSource.Token).AsTask()); - tokenSource.Cancel(); - yield return waitTask; - Assert.True(waitTask.Task.IsCanceled); - tokenSource.Dispose(); - } - - [UnityTest] - public IEnumerator Cancellation_DuringUnloadScene([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager, [ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SingleLoadSceneInfoList))] ILoadSceneInfo sceneInfo) - { - CancellationTokenSource tokenSource = new(); - SceneParameters parameters = new SceneParameters(sceneInfo); - WaitTask waitTask = new(manager.LoadAsync(parameters).AsTask()); - yield return waitTask; - - waitTask = new(manager.UnloadAsync(parameters, token: tokenSource.Token).AsTask()); + WaitTask waitTask = new(manager.LoadAsync(sceneParameters, token: tokenSource.Token).AsTask()); tokenSource.Cancel(); yield return waitTask; Assert.True(waitTask.Task.IsCanceled); @@ -45,14 +19,13 @@ public IEnumerator Cancellation_DuringUnloadScene([ValueSource(typeof(SceneTestE } [UnityTest] - public IEnumerator Cancellation_DuringUnloadScenes([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager, [ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.MultipleLoadSceneInfoList))] ILoadSceneInfo[] sceneInfos) + public IEnumerator Cancellation_DuringUnload([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager, [ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneParametersList))] SceneParameters sceneParameters) { CancellationTokenSource tokenSource = new(); - SceneParameters parameters = new SceneParameters(sceneInfos); - WaitTask waitTask = new(manager.LoadAsync(parameters).AsTask()); + WaitTask waitTask = new(manager.LoadAsync(sceneParameters).AsTask()); yield return waitTask; - waitTask = new(manager.UnloadAsync(parameters, token: tokenSource.Token).AsTask()); + waitTask = new(manager.UnloadAsync(sceneParameters, token: tokenSource.Token).AsTask()); tokenSource.Cancel(); yield return waitTask; Assert.True(waitTask.Task.IsCanceled); diff --git a/Packages/com.mygamedevtools.scene-loader/Tests/Runtime/SceneManager_DisposeTests.cs b/Packages/com.mygamedevtools.scene-loader/Tests/Runtime/SceneManager_DisposeTests.cs index 5a91433..0fbc56a 100644 --- a/Packages/com.mygamedevtools.scene-loader/Tests/Runtime/SceneManager_DisposeTests.cs +++ b/Packages/com.mygamedevtools.scene-loader/Tests/Runtime/SceneManager_DisposeTests.cs @@ -22,87 +22,37 @@ public void Dispose_Simple([ValueSource(nameof(_sceneManagerCreateFuncs))] Func< } [UnityTest] - public IEnumerator Dispose_DuringLoadScene([ValueSource(nameof(_sceneManagerCreateFuncs))] Func managerCreateFunc, [ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SingleLoadSceneInfoList))] ILoadSceneInfo sceneInfo) + public IEnumerator Dispose_DuringLoad([ValueSource(nameof(_sceneManagerCreateFuncs))] Func managerCreateFunc, [ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneParametersList))] SceneParameters sceneParameters) { ISceneManager manager = managerCreateFunc(); - WaitTask waitTask = new(manager.LoadAsync(new SceneParameters(sceneInfo)).AsTask()); - manager.Dispose(); - yield return waitTask; - Assert.That(waitTask.Task.IsCompleted); - } - - [UnityTest] - public IEnumerator Dispose_DuringLoadScenes([ValueSource(nameof(_sceneManagerCreateFuncs))] Func managerCreateFunc, [ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.MultipleLoadSceneInfoList))] ILoadSceneInfo[] sceneInfos) - { - ISceneManager manager = managerCreateFunc(); - WaitTask waitTask = new(manager.LoadAsync(new SceneParameters(sceneInfos)).AsTask()); - manager.Dispose(); - yield return waitTask; - Assert.True(waitTask.Task.IsCanceled); - } - - [UnityTest] - public IEnumerator Dipose_DuringUnloadScene([ValueSource(nameof(_sceneManagerCreateFuncs))] Func managerCreateFunc, [ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SingleLoadSceneInfoList))] ILoadSceneInfo sceneInfo) - { - ISceneManager manager = managerCreateFunc(); - SceneParameters parameters = new SceneParameters(sceneInfo); - WaitTask waitTask = new(manager.LoadAsync(parameters).AsTask()); - yield return waitTask; - - waitTask = new(manager.UnloadAsync(parameters).AsTask()); + WaitTask waitTask = new(manager.LoadAsync(sceneParameters).AsTask()); manager.Dispose(); yield return waitTask; Assert.True(waitTask.Task.IsCanceled); } [UnityTest] - public IEnumerator Dipose_DuringUnloadScenes([ValueSource(nameof(_sceneManagerCreateFuncs))] Func managerCreateFunc, [ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.MultipleLoadSceneInfoList))] ILoadSceneInfo[] sceneInfos) + public IEnumerator Dipose_DuringUnload([ValueSource(nameof(_sceneManagerCreateFuncs))] Func managerCreateFunc, [ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneParametersList))] SceneParameters sceneParameters) { ISceneManager manager = managerCreateFunc(); - SceneParameters parameters = new SceneParameters(sceneInfos); - WaitTask waitTask = new(manager.LoadAsync(parameters).AsTask()); + WaitTask waitTask = new(manager.LoadAsync(sceneParameters).AsTask()); yield return waitTask; - waitTask = new(manager.UnloadAsync(parameters).AsTask()); + waitTask = new(manager.UnloadAsync(sceneParameters).AsTask()); manager.Dispose(); yield return waitTask; Assert.True(waitTask.Task.IsCanceled); } [UnityTest] - public IEnumerator Dispose_DuringTransitionToSceneAsync([ValueSource(nameof(_sceneManagerCreateFuncs))] Func managerCreateFunc, [ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SingleLoadSceneInfoList))] ILoadSceneInfo targetScene, [ValueSource(typeof(SceneManagerTests), nameof(SceneManagerTests.LoadingSceneInfos))] ILoadSceneInfo loadingScene) - { - async Awaitable Test() - { - ISceneManager manager = managerCreateFunc(); - await SceneManagerTests.LoadFirstScene(manager).ValueTask; - - var task = manager.TransitionAsync(new SceneParameters(targetScene), loadingScene); - manager.Dispose(); - - bool canceled = false; - try - { - await task; - } - catch (OperationCanceledException) - { - canceled = true; - } - Assert.True(canceled); - } - return Test(); - } - - [UnityTest] - public IEnumerator Dispose_DuringTransitionToScenesAsync([ValueSource(nameof(_sceneManagerCreateFuncs))] Func managerCreateFunc, [ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.MultipleLoadSceneInfoList))] ILoadSceneInfo[] targetScenes, [ValueSource(typeof(SceneManagerTests), nameof(SceneManagerTests.LoadingSceneInfos))] ILoadSceneInfo loadingScene) + public IEnumerator Dispose_DuringTransition([ValueSource(nameof(_sceneManagerCreateFuncs))] Func managerCreateFunc, [ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.TransitionSceneParametersList))] SceneParameters sceneParameters, [ValueSource(typeof(SceneManagerTests), nameof(SceneManagerTests.LoadingSceneInfos))] ILoadSceneInfo loadingScene) { async Awaitable Test() { ISceneManager manager = managerCreateFunc(); await SceneManagerTests.LoadFirstScene(manager).ValueTask; - var task = manager.TransitionAsync(new SceneParameters(targetScenes, 0), loadingScene); + var task = manager.TransitionAsync(sceneParameters, loadingScene); manager.Dispose(); bool canceled = false; diff --git a/Packages/com.mygamedevtools.scene-loader/Tests/Runtime/SceneManager_ExtensionTests.cs b/Packages/com.mygamedevtools.scene-loader/Tests/Runtime/SceneManager_ExtensionTests.cs new file mode 100644 index 0000000..199b3cb --- /dev/null +++ b/Packages/com.mygamedevtools.scene-loader/Tests/Runtime/SceneManager_ExtensionTests.cs @@ -0,0 +1,169 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine.TestTools; + +namespace MyGameDevTools.SceneLoading.Tests +{ + public partial class SceneManagerTests + { + int[] _buildIndexes = new[] { 0, 1, 2, 3 }; + + [UnityTest] + public IEnumerator Load_Extension_ByIndex([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager) + { + var progress = new SimpleProgress(); + yield return Load_Template(manager, () => manager.LoadAsync(1, true, progress), progress, 1, 0); + } + + [UnityTest] + public IEnumerator Load_Extension_ByIndex_Multiple([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager) + { + var progress = new SimpleProgress(); + yield return Load_Template(manager, () => manager.LoadAsync(_buildIndexes, 1, progress), progress, _buildIndexes.Length, 1); + } + + [UnityTest] + public IEnumerator Load_Extension_ByName([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager) + { + var progress = new SimpleProgress(); + yield return Load_Template(manager, () => manager.LoadAsync(SceneBuilder.SceneNames[1], true, progress), progress, 1, 0); + } + + [UnityTest] + public IEnumerator Load_Extension_ByName_Multiple([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager) + { + var progress = new SimpleProgress(); + yield return Load_Template(manager, () => manager.LoadAsync(SceneBuilder.SceneNames, 1, progress), progress, SceneBuilder.SceneNames.Length, 1); + } + +#if ENABLE_ADDRESSABLES + [UnityTest] + public IEnumerator Load_Extension_Addressable_ByAddress([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager) + { + var progress = new SimpleProgress(); + yield return Load_Template(manager, () => manager.LoadAddressableAsync(SceneBuilder.SceneNames[1], true, progress), progress, 1, 0); + } + + [UnityTest] + public IEnumerator Load_Extension_Addressable_ByAddress_Multiple([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager) + { + var progress = new SimpleProgress(); + yield return Load_Template(manager, () => manager.LoadAddressableAsync(SceneBuilder.SceneNames, 1, progress), progress, SceneBuilder.SceneNames.Length, 1); + } + + [UnityTest] + public IEnumerator Load_Extension_Addressable_ByAssetReference([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager) + { + var progress = new SimpleProgress(); + yield return Load_Template(manager, () => manager.LoadAddressableAsync(_assetReferences[1], true, progress), progress, 1, 0); + } + + [UnityTest] + public IEnumerator Load_Extension_Addressable_ByAssetReference_Multiple([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager) + { + var progress = new SimpleProgress(); + yield return Load_Template(manager, () => manager.LoadAddressableAsync(_assetReferences, 1, progress), progress, _assetReferences.Length, 1); + } +#endif + + [UnityTest] + public IEnumerator Transition_Extension_ByIndex([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager) + { + yield return Transition_Template(manager, () => manager.TransitionAsync(1, 0).AsTask(), 1, 0); + } + + [UnityTest] + public IEnumerator Transition_Extension_ByIndex_Multiple([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager) + { + yield return Transition_Template(manager, () => manager.TransitionAsync(_buildIndexes, 0).AsTask(), _buildIndexes.Length, 0); + } + + [UnityTest] + public IEnumerator Transition_Extension_ByName([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager) + { + yield return Transition_Template(manager, () => manager.TransitionAsync(SceneBuilder.SceneNames[1], SceneBuilder.SceneNames[0]).AsTask(), 1, 0); + } + + [UnityTest] + public IEnumerator Transition_Extension_ByName_Multiple([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager) + { + yield return Transition_Template(manager, () => manager.TransitionAsync(SceneBuilder.SceneNames, SceneBuilder.ScenePaths[0]).AsTask(), SceneBuilder.SceneNames.Length, 0); + } + +#if ENABLE_ADDRESSABLES + [UnityTest] + public IEnumerator Transition_Extension_Addressable_ByAddress([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager) + { + yield return Transition_Template(manager, () => manager.TransitionAddressableAsync(SceneBuilder.SceneNames[1], SceneBuilder.SceneNames[0]).AsTask(), 1, 0); + } + + [UnityTest] + public IEnumerator Transition_Extension_Addressable_ByAddress_Multiple([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager) + { + yield return Transition_Template(manager, () => manager.TransitionAddressableAsync(SceneBuilder.SceneNames, SceneBuilder.SceneNames[0]).AsTask(), SceneBuilder.SceneNames.Length, 0); + } + + [UnityTest] + public IEnumerator Transition_Extension_Addressable_ByAssetReference([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager) + { + yield return Transition_Template(manager, () => manager.TransitionAddressableAsync(_assetReferences[1], _assetReferences[0]).AsTask(), 1, 0); + } + + [UnityTest] + public IEnumerator Transition_Extension_Addressable_ByAssetReference_Multiple([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager) + { + yield return Transition_Template(manager, () => manager.TransitionAddressableAsync(_assetReferences, _assetReferences[0]).AsTask(), SceneBuilder.SceneNames.Length, 0); + } +#endif + + [UnityTest] + public IEnumerator Unload_Extension_ByIndex([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager) + { + yield return Unload_Template(manager, () => manager.LoadAsync(1, true), () => manager.UnloadAsync(1), 1); + } + + [UnityTest] + public IEnumerator Unload_Extension_ByIndex_Multiple([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager) + { + yield return Unload_Template(manager, () => manager.LoadAsync(_buildIndexes, 0), () => manager.UnloadAsync(_buildIndexes), _buildIndexes.Length); + } + + [UnityTest] + public IEnumerator Unload_Extension_ByName([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager) + { + yield return Unload_Template(manager, () => manager.LoadAsync(SceneBuilder.SceneNames[1], true), () => manager.UnloadAsync(SceneBuilder.SceneNames[1]), 1); + } + + [UnityTest] + public IEnumerator Unload_Extension_ByName_Multiple([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager) + { + yield return Unload_Template(manager, () => manager.LoadAsync(SceneBuilder.SceneNames, 0), () => manager.UnloadAsync(SceneBuilder.SceneNames), SceneBuilder.SceneNames.Length); + } + +#if ENABLE_ADDRESSABLES + [UnityTest] + public IEnumerator Unload_Extension_Addressable_ByAddress([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager) + { + yield return Unload_Template(manager, () => manager.LoadAddressableAsync(SceneBuilder.SceneNames[1], true), () => manager.UnloadAddressableAsync(SceneBuilder.SceneNames[1]), 1); + } + + [UnityTest] + public IEnumerator Unload_Extension_Addressable_ByAddress_Multiple([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager) + { + yield return Unload_Template(manager, () => manager.LoadAddressableAsync(SceneBuilder.SceneNames, 0), () => manager.UnloadAddressableAsync(SceneBuilder.SceneNames), SceneBuilder.SceneNames.Length); + } + + [UnityTest] + public IEnumerator Unload_Extension_Addressable_ByAssetReference([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager) + { + yield return Unload_Template(manager, () => manager.LoadAddressableAsync(_assetReferences[1], true), () => manager.UnloadAddressableAsync(_assetReferences[1]), 1); + } + + [UnityTest] + public IEnumerator Unload_Extension_Addressable_ByAssetReference_Multiple([ValueSource(typeof(SceneTestEnvironment), nameof(SceneTestEnvironment.SceneManagers))] ISceneManager manager) + { + yield return Unload_Template(manager, () => manager.LoadAddressableAsync(_assetReferences, 0), () => manager.UnloadAddressableAsync(_assetReferences), _assetReferences.Length); + } +#endif + } +} diff --git a/Packages/com.mygamedevtools.scene-loader/Tests/Runtime/SceneManager_ExtensionTests.cs.meta b/Packages/com.mygamedevtools.scene-loader/Tests/Runtime/SceneManager_ExtensionTests.cs.meta new file mode 100644 index 0000000..a9a1e3c --- /dev/null +++ b/Packages/com.mygamedevtools.scene-loader/Tests/Runtime/SceneManager_ExtensionTests.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: e7b3d6cfd812bb04c9b151cf3ebb4456 \ No newline at end of file diff --git a/Packages/com.mygamedevtools.scene-loader/Tests/Runtime/Utilities/SceneTestEnvironment.cs b/Packages/com.mygamedevtools.scene-loader/Tests/Runtime/Utilities/SceneTestEnvironment.cs index 1af2105..ef41485 100644 --- a/Packages/com.mygamedevtools.scene-loader/Tests/Runtime/Utilities/SceneTestEnvironment.cs +++ b/Packages/com.mygamedevtools.scene-loader/Tests/Runtime/Utilities/SceneTestEnvironment.cs @@ -22,34 +22,6 @@ public class SceneTestEnvironment : IPrebuildSetup, IPostBuildCleanup public const string ScenePathBase = "Assets/_test"; public const int DefaultTimeout = 3000; - public static readonly ILoadSceneInfo[][] MultipleLoadSceneInfoList = new ILoadSceneInfo[][] - { - new ILoadSceneInfo[] - { - new LoadSceneInfoName(SceneBuilder.SceneNames[0]), - new LoadSceneInfoIndex(1), -#if ENABLE_ADDRESSABLES - new LoadSceneInfoAddress(SceneBuilder.SceneNames[2]), - new LoadSceneInfoAddress(SceneBuilder.SceneNames[3]), -#endif - new LoadSceneInfoName(SceneBuilder.ScenePaths[3]) - }, - // This list of scenes expects two load scene infos that point to the same source scene, - // and validates whether that causes any issues when linking to the target loaded scene. - new ILoadSceneInfo[] - { - new LoadSceneInfoIndex(1), - new LoadSceneInfoName(SceneBuilder.SceneNames[1]), - new LoadSceneInfoName(SceneBuilder.ScenePaths[1]), -#if ENABLE_ADDRESSABLES - // Since we can't test statically with AssetReference, we should at least validate - // that two AsyncOperations with the same addressable source do not cause issues. - new LoadSceneInfoAddress(SceneBuilder.SceneNames[1]), - new LoadSceneInfoAddress(SceneBuilder.SceneNames[1]), -#endif - } - }; - public static readonly ILoadSceneInfo[] SingleLoadSceneInfoList = new ILoadSceneInfo[] { new LoadSceneInfoName(SceneBuilder.SceneNames[1]), @@ -72,10 +44,21 @@ public class SceneTestEnvironment : IPrebuildSetup, IPostBuildCleanup new(SingleLoadSceneInfoList[3], false), new(SingleLoadSceneInfoList[3], true), #endif - new(MultipleLoadSceneInfoList[0], -1), - new(MultipleLoadSceneInfoList[0], 1), - new(MultipleLoadSceneInfoList[1], -1), - new(MultipleLoadSceneInfoList[1], 1), + new(_multipleLoadSceneInfoList[0], -1), + new(_multipleLoadSceneInfoList[0], 1), + new(_multipleLoadSceneInfoList[1], -1), + new(_multipleLoadSceneInfoList[1], 1), + }; + public static readonly SceneParameters[] TransitionSceneParametersList = new SceneParameters[] + { + new(SingleLoadSceneInfoList[0], true), + new(SingleLoadSceneInfoList[1], true), + new(SingleLoadSceneInfoList[2], true), +#if ENABLE_ADDRESSABLES + new(SingleLoadSceneInfoList[3], true), +#endif + new(_multipleLoadSceneInfoList[0], 1), + new(_multipleLoadSceneInfoList[1], 1), }; public static readonly ISceneManager[] SceneManagers = new ISceneManager[] @@ -83,6 +66,34 @@ public class SceneTestEnvironment : IPrebuildSetup, IPostBuildCleanup new AdvancedSceneManager(), }; + static readonly ILoadSceneInfo[][] _multipleLoadSceneInfoList = new ILoadSceneInfo[][] + { + new ILoadSceneInfo[] + { + new LoadSceneInfoName(SceneBuilder.SceneNames[0]), + new LoadSceneInfoIndex(1), +#if ENABLE_ADDRESSABLES + new LoadSceneInfoAddress(SceneBuilder.SceneNames[2]), + new LoadSceneInfoAddress(SceneBuilder.SceneNames[3]), +#endif + new LoadSceneInfoName(SceneBuilder.ScenePaths[3]) + }, + // This list of scenes expects two load scene infos that point to the same source scene, + // and validates whether that causes any issues when linking to the target loaded scene. + new ILoadSceneInfo[] + { + new LoadSceneInfoIndex(1), + new LoadSceneInfoName(SceneBuilder.SceneNames[1]), + new LoadSceneInfoName(SceneBuilder.ScenePaths[1]), +#if ENABLE_ADDRESSABLES + // Since we can't test statically with AssetReference, we should at least validate + // that two AsyncOperations with the same addressable source do not cause issues. + new LoadSceneInfoAddress(SceneBuilder.SceneNames[1]), + new LoadSceneInfoAddress(SceneBuilder.SceneNames[1]), +#endif + } + }; + #if UNITY_EDITOR #if ENABLE_ADDRESSABLES const string _addressableScenePathBase = "Assets/_addressables-test"; diff --git a/ProjectSettings/Packages/com.unity.testtools.codecoverage/Settings.json b/ProjectSettings/Packages/com.unity.testtools.codecoverage/Settings.json index 985a113..e0fe6fa 100644 --- a/ProjectSettings/Packages/com.unity.testtools.codecoverage/Settings.json +++ b/ProjectSettings/Packages/com.unity.testtools.codecoverage/Settings.json @@ -34,7 +34,7 @@ { "type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "key": "GenerateTestReferences", - "value": "{\"m_Value\":true}" + "value": "{\"m_Value\":false}" } ] }