Skip to content

Commit

Permalink
fix: add scene manager extension tests
Browse files Browse the repository at this point in the history
BREAKING CHANGE: bump to major 4 (pre-release)
  • Loading branch information
joaoborks committed Dec 29, 2024
1 parent ed908f9 commit 867fe3f
Show file tree
Hide file tree
Showing 10 changed files with 267 additions and 168 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,9 @@ public Scene GetLoadedSceneByName(string name)

public ValueTask<SceneResult> 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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,16 +224,16 @@ public static ValueTask<SceneResult> LoadAddressableAsync(this ISceneManager sce
/// <param name="targetSceneNames">
/// An array of scenes by their names to transition to.
/// </param>
/// <param name="setIndexActive">
/// The index of the scene to be activated as the active scene.
/// </param>
/// <param name="loadingSceneName">
/// 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.
/// </param>
/// <param name="setIndexActive">
/// The index of the scene to be activated as the active scene. It must be greater than or equal 0.
/// </param>
/// <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>
/// <returns>A <see cref="System.Threading.Tasks.ValueTask{TResult}"/> with all scenes loaded.</returns>
public static ValueTask<SceneResult> TransitionAsync(this ISceneManager sceneManager, string[] targetSceneNames, int setIndexActive = -1, string loadingSceneName = null, CancellationToken token = default)
public static ValueTask<SceneResult> 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);
Expand All @@ -255,19 +255,19 @@ public static ValueTask<SceneResult> TransitionAsync(this ISceneManager sceneMan
/// <param name="targetBuildIndices">
/// An array of scenes by their build index to transition to.
/// </param>
/// <param name="setIndexActive">
/// The index of the scene to be activated as the active scene.
/// </param>
/// <param name="loadingBuildIndex">
/// 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.
/// </param>
/// <param name="setIndexActive">
/// The index of the scene to be activated as the active scene. It must be greater than or equal 0.
/// </param>
/// <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>
/// <returns>A <see cref="System.Threading.Tasks.ValueTask{TResult}"/> with all scenes loaded.</returns>
public static ValueTask<SceneResult> TransitionAsync(this ISceneManager sceneManager, int[] targetBuildIndices, int setIndexActive = -1, int? loadingBuildIndex = null, CancellationToken token = default)
public static ValueTask<SceneResult> 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);
}

Expand All @@ -286,18 +286,15 @@ public static ValueTask<SceneResult> TransitionAsync(this ISceneManager sceneMan
/// <param name="targetSceneName">
/// The target scene name to be transitioned to.
/// </param>
/// <param name="setIndexActive">
/// The index of the scene to be activated as the active scene.
/// </param>
/// <param name="loadingSceneName">
/// 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.
/// </param>
/// <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>
/// <returns>A <see cref="System.Threading.Tasks.ValueTask{TResult}"/> with all scenes loaded.</returns>
public static ValueTask<SceneResult> TransitionAsync(this ISceneManager sceneManager, string targetSceneName, bool setActive = false, string loadingSceneName = null, CancellationToken token = default)
public static ValueTask<SceneResult> 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);
}
Expand All @@ -317,19 +314,16 @@ public static ValueTask<SceneResult> TransitionAsync(this ISceneManager sceneMan
/// <param name="targetBuildIndex">
/// The target scene build index to be transitioned to.
/// </param>
/// <param name="setIndexActive">
/// The index of the scene to be activated as the active scene.
/// </param>
/// <param name="loadingBuildIndex">
/// 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.
/// </param>
/// <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>
/// <returns>A <see cref="System.Threading.Tasks.ValueTask{TResult}"/> with all scenes loaded.</returns>
public static ValueTask<SceneResult> TransitionAsync(this ISceneManager sceneManager, int targetBuildIndex, bool setActive = false, int? loadingBuildIndex = null, CancellationToken token = default)
public static ValueTask<SceneResult> 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);
}

Expand All @@ -349,16 +343,16 @@ public static ValueTask<SceneResult> TransitionAsync(this ISceneManager sceneMan
/// <param name="targetAssetReferences">
/// An array of scenes by their <see cref="AssetReference"/> to transition to.
/// </param>
/// <param name="setIndexActive">
/// The index of the scene to be activated as the active scene.
/// </param>
/// <param name="loadingAssetReference">
/// 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.
/// </param>
/// <param name="setIndexActive">
/// The index of the scene to be activated as the active scene. It must be greater than or equal 0.
/// </param>
/// <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>
/// <returns>A <see cref="System.Threading.Tasks.ValueTask{TResult}"/> with all scenes loaded.</returns>
public static ValueTask<SceneResult> TransitionAddressableAsync(this ISceneManager sceneManager, AssetReference[] targetAssetReferences, int setIndexActive = -1, AssetReference loadingAssetReference = null, CancellationToken token = default)
public static ValueTask<SceneResult> 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;
Expand All @@ -380,16 +374,16 @@ public static ValueTask<SceneResult> TransitionAddressableAsync(this ISceneManag
/// <param name="targetAddresses">
/// An array of scenes by their addressable addresses to transition to.
/// </param>
/// <param name="setIndexActive">
/// The index of the scene to be activated as the active scene.
/// </param>
/// <param name="loadingAddress">
/// 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.
/// </param>
/// <param name="setIndexActive">
/// The index of the scene to be activated as the active scene. It must be greater than or equal 0.
/// </param>
/// <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>
/// <returns>A <see cref="System.Threading.Tasks.ValueTask{TResult}"/> with all scenes loaded.</returns>
public static ValueTask<SceneResult> TransitionAddressableAsync(this ISceneManager sceneManager, string[] targetAddresses, int setIndexActive = -1, string loadingAddress = null, CancellationToken token = default)
public static ValueTask<SceneResult> 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);
Expand All @@ -411,18 +405,15 @@ public static ValueTask<SceneResult> TransitionAddressableAsync(this ISceneManag
/// <param name="targetAssetReference">
/// The target scene <see cref="AssetReference"/> to be transitioned to.
/// </param>
/// <param name="setIndexActive">
/// The index of the scene to be activated as the active scene.
/// </param>
/// <param name="loadingAssetReference">
/// 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.
/// </param>
/// <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>
/// <returns>A <see cref="System.Threading.Tasks.ValueTask{TResult}"/> with all scenes loaded.</returns>
public static ValueTask<SceneResult> TransitionAddressableAsync(this ISceneManager sceneManager, AssetReference targetAssetReference, bool setActive = false, AssetReference loadingAssetReference = null, CancellationToken token = default)
public static ValueTask<SceneResult> 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);
}
Expand All @@ -442,18 +433,15 @@ public static ValueTask<SceneResult> TransitionAddressableAsync(this ISceneManag
/// <param name="targetAddress">
/// The target scene addressable address to be transitioned to.
/// </param>
/// <param name="setIndexActive">
/// The index of the scene to be activated as the active scene.
/// </param>
/// <param name="loadingAddress">
/// 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.
/// </param>
/// <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>
/// <returns>A <see cref="System.Threading.Tasks.ValueTask{TResult}"/> with all scenes loaded.</returns>
public static ValueTask<SceneResult> TransitionAddressableAsync(this ISceneManager sceneManager, string targetAddress, bool setActive = false, string loadingAddress = null, CancellationToken token = default)
public static ValueTask<SceneResult> 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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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());
}
Expand Down Expand Up @@ -327,8 +331,7 @@ public IEnumerator Transition_Template(ISceneManager manager, Func<Task<SceneRes

Scene[] loadedScenes = task.Result;
Assert.AreEqual(sceneCount, loadedScenes.Length);
if (setIndexActive >= 0)
Assert.AreEqual(loadedScenes[setIndexActive], manager.GetActiveScene());
Assert.AreEqual(loadedScenes[setIndexActive], manager.GetActiveScene());

yield return new WaitUntil(() => manager.TotalSceneCount == sceneCount);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@ 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()
{
AsyncOperationHandle<SceneReferenceData> operationHandle = Addressables.LoadAssetAsync<SceneReferenceData>(nameof(SceneReferenceData));
operationHandle.WaitForCompletion();

SceneReferenceData sceneReferenceData = operationHandle.Result;
_assetReferences = sceneReferenceData.sceneReferences.ToArray();

_assetReferenceLoadSceneInfos = new ILoadSceneInfo[]
{
Expand All @@ -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));
}
Expand Down
Loading

0 comments on commit 867fe3f

Please sign in to comment.