diff --git a/Runtime/ISceneChange.cs b/Runtime/ISceneChange.cs index 3f149b8..1762f87 100644 --- a/Runtime/ISceneChange.cs +++ b/Runtime/ISceneChange.cs @@ -12,10 +12,10 @@ public interface ISceneChange { bool IsActive(SceneDefinition scene); - void Switch(SceneDefinition scene); + Task Unload(SceneDefinition scene, CancellationToken token); Task Reload(IEnumerable addOperations, CancellationToken token); - Task SwitchAsync(SceneDefinition scene, IEnumerable addOperations, CancellationToken token); + Task Load(SceneDefinition scene, IEnumerable addOperations, CancellationToken token); } } \ No newline at end of file diff --git a/Runtime/SceneChange.cs b/Runtime/SceneChange.cs index 6e6b9c1..ccea206 100644 --- a/Runtime/SceneChange.cs +++ b/Runtime/SceneChange.cs @@ -1,6 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 // © 2023-2024 Nikolay Melnikov +using System; using System.Collections.Generic; using System.Linq; using System.Threading; @@ -26,7 +27,10 @@ public SceneChange(SceneDefinition initialScene, ILoadingCurtain loadingCurtain) public SceneDefinition ActiveScene { get; private set; } - private async Task SwitchAsyncInternal(SceneDefinition scene, IEnumerable addOperations, + public bool IsActive(SceneDefinition scene) => + scene == ActiveScene || scene.Name == SceneManager.GetActiveScene().name; + + private async Task LoadInternal(SceneDefinition scene, IEnumerable addOperations, CancellationToken token) { var operations = addOperations.Concat(new[] @@ -36,32 +40,19 @@ private async Task SwitchAsyncInternal(SceneDefinition scene, IEnumerable - scene == ActiveScene || scene.Name == SceneManager.GetActiveScene().name; + Task ISceneChange.Load(SceneDefinition scene, IEnumerable addOperations, + CancellationToken token) => IsActive(scene) + ? throw new UnexpectedSceneSwitch(scene.Name) + : LoadInternal(ActiveScene = scene, addOperations, token); - void ISceneChange.Switch(SceneDefinition scene) + async Task ISceneChange.Unload(SceneDefinition scene, CancellationToken token) { - if (IsActive(scene)) - { - throw new UnexpectedSceneSwitch(scene.Name); - } - - ActiveScene = scene; - SceneManager.LoadScene(ActiveScene.Name, ActiveScene.LoadMode); - } - - Task ISceneChange.SwitchAsync(SceneDefinition scene, IEnumerable addOperations, - CancellationToken token) - { - if (IsActive(scene)) - { - throw new UnexpectedSceneSwitch(scene.Name); - } - - return SwitchAsyncInternal(ActiveScene = scene, addOperations, token); + var operations = new[] { new SceneLoadingOperation(scene, OperationDescription.Default(scene.Name)) }; + ILoadingCurtain cleanCurtain = new CleanLoadingCurtain(); + await cleanCurtain.Load(operations, token); } Task ISceneChange.Reload(IEnumerable addOperations, CancellationToken token) => - SwitchAsyncInternal(ActiveScene, addOperations, token); + LoadInternal(ActiveScene, addOperations, token); } } \ No newline at end of file diff --git a/Runtime/SceneDefinition.cs b/Runtime/SceneDefinition.cs index 5314891..c8bacc5 100644 --- a/Runtime/SceneDefinition.cs +++ b/Runtime/SceneDefinition.cs @@ -15,6 +15,7 @@ public sealed partial class SceneDefinition [SerializeField] private string _title; [SerializeField] private LoadSceneMode _loadMode; [TextArea] [SerializeField] private string _description; + [SerializeField] private bool _activateOnLoad = true; public SceneDefinition(string name, LoadSceneMode loadMode) { @@ -27,6 +28,8 @@ public SceneDefinition(string name, LoadSceneMode loadMode) public LoadSceneMode LoadMode => _loadMode; public Scene Handle => SceneManager.GetSceneByName(Name); public string Title => string.IsNullOrEmpty(_title) ? Name : _title; + + internal bool ActivateOnLoad => _activateOnLoad; } public sealed partial class SceneDefinition : IEquatable diff --git a/Runtime/SceneLoadingOperation.cs b/Runtime/SceneLoadingOperation.cs index e2ae6e2..fdb2948 100644 --- a/Runtime/SceneLoadingOperation.cs +++ b/Runtime/SceneLoadingOperation.cs @@ -2,6 +2,7 @@ // © 2023-2024 Nikolay Melnikov using System; +using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; using Depra.Loading.Operations; @@ -21,6 +22,15 @@ public SceneLoadingOperation(SceneDefinition sceneDefinition, OperationDescripti public OperationDescription Description { get; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void ActivateIfNeeded(SceneDefinition scene) + { + if (scene.ActivateOnLoad) + { + SceneManager.SetActiveScene(scene.Handle); + } + } + async Task ILoadingOperation.Load(Action onProgress, CancellationToken token) { onProgress?.Invoke(0); @@ -34,6 +44,7 @@ async Task ILoadingOperation.Load(Action onProgress, CancellationToken to } onProgress?.Invoke(1); + ActivateIfNeeded(_sceneDefinition); } } } \ No newline at end of file diff --git a/Runtime/SceneUnloadingOperation.cs b/Runtime/SceneUnloadingOperation.cs new file mode 100644 index 0000000..bec6dfc --- /dev/null +++ b/Runtime/SceneUnloadingOperation.cs @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: Apache-2.0 +// © 2023-2024 Nikolay Melnikov + +using System; +using System.Threading; +using System.Threading.Tasks; +using Depra.Loading.Operations; +using UnityEngine.SceneManagement; + +namespace Depra.Scenes +{ + public sealed class SceneUnloadingOperation : ILoadingOperation + { + private readonly SceneDefinition _sceneDefinition; + + public SceneUnloadingOperation(SceneDefinition sceneDefinition, OperationDescription description) + { + Description = description; + _sceneDefinition = sceneDefinition; + } + + public OperationDescription Description { get; } + + async Task ILoadingOperation.Load(Action onProgress, CancellationToken token) + { + onProgress?.Invoke(0); + var operation = SceneManager.UnloadSceneAsync(_sceneDefinition.Name); + operation.allowSceneActivation = true; + + while (operation.isDone == false) + { + onProgress?.Invoke(operation.progress); + await Task.Yield(); + } + + onProgress?.Invoke(1); + } + } +} \ No newline at end of file diff --git a/Runtime/SceneUnloadingOperation.cs.meta b/Runtime/SceneUnloadingOperation.cs.meta new file mode 100644 index 0000000..2e03f69 --- /dev/null +++ b/Runtime/SceneUnloadingOperation.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 0011b70eba594bb6a04d2b4a2a089e06 +timeCreated: 1706309793 \ No newline at end of file diff --git a/package.json b/package.json index 58a7376..211d53a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "com.depra.scenes", - "version": "0.0.4", + "version": "0.0.5", "displayName": "Depra.Scenes", "description": "", "unity": "2022.3",