Skip to content

Commit

Permalink
Merge pull request #30 from mewlist/sceneloader-progression
Browse files Browse the repository at this point in the history
Sceneloader progression
  • Loading branch information
mewlist authored Feb 22, 2024
2 parents ebad95a + 4374bdd commit a01f1a8
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 43 deletions.
31 changes: 0 additions & 31 deletions Runtime/Assets/Compatibility/CompatibleSceneLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,10 @@
using Cysharp.Threading.Tasks;
#endif

#if UNITY_EDITOR
using UnityEditor.SceneManagement;
#endif

namespace Mew.Core.Assets
{
internal static class CompatibleSceneLoader
{
internal static async ValueTask<SceneHandle> LoadSceneAsync(UnifiedScene unifiedScene, LoadSceneParameters parameters)
{
#if UNITY_2023_2_OR_NEWER || USE_UNITASK
await SceneManager.LoadSceneAsync(unifiedScene.SceneReference, parameters);
#else
var asyncOp = SceneManager.LoadSceneAsync(unifiedScene.SceneReference, parameters);
while (!asyncOp.isDone) await TaskHelper.NextFrame();
#endif
var loadedScene = SceneManager.GetSceneAt(SceneManager.loadedSceneCount - 1);
return new SceneHandle(loadedScene);
}

internal static async ValueTask UnloadSceneAsync(SceneHandle sceneHandle)
{
#if UNITY_2023_2_OR_NEWER || USE_UNITASK
Expand All @@ -36,20 +20,5 @@ internal static async ValueTask UnloadSceneAsync(SceneHandle sceneHandle)
while (!asyncOp.isDone) await TaskHelper.NextFrame();
#endif
}

#if UNITY_EDITOR
public static async Task<ISceneHandle> LoadEditorSceneAsync(UnifiedScene unifiedScene, LoadSceneParameters parameters)
{

#if UNITY_2023_2_OR_NEWER || USE_UNITASK
await EditorSceneManager.LoadSceneAsyncInPlayMode(unifiedScene.EditorScenePath , parameters ) ;
#else
var asyncOp = EditorSceneManager.LoadSceneAsyncInPlayMode(unifiedScene.EditorScenePath , parameters ) ;
while (!asyncOp.isDone) await TaskHelper.NextFrame();
#endif
var loadedScene = SceneManager.GetSceneAt(SceneManager.loadedSceneCount - 1);
return new SceneHandle(loadedScene);
}
#endif
}
}
5 changes: 4 additions & 1 deletion Runtime/Assets/Scene/ISceneHandle.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using UnityEngine.SceneManagement;

namespace Mew.Core.Assets
{
public interface ISceneHandle : IEquatable<Scene>
{
ValueTask<Scene> GetScene();
ValueTask<Scene> GetScene(CancellationToken ct);
public float Progress { get; }
bool Completed { get; }
}
}
43 changes: 39 additions & 4 deletions Runtime/Assets/Scene/SceneHandle.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,55 @@
using System.Threading.Tasks;
using System.Threading;
using System.Threading.Tasks;
using Mew.Core.TaskHelpers;
using UnityEngine;
using UnityEngine.SceneManagement;

namespace Mew.Core.Assets
{
public class SceneHandle : ISceneHandle
{
public Scene Scene { get; }
public AsyncOperation AsyncOp { get; }
public Scene Scene { get; private set; }
public float Progress => AsyncOp.progress;
public bool Completed => AsyncOp.isDone;

public SceneHandle(AsyncOperation asyncOp)
{
AsyncOp = asyncOp;
AsyncOp.completed += OnCompleted;
}

public SceneHandle(Scene scene)
{
Scene = scene;
}

public async ValueTask<Scene> GetScene()
private void OnCompleted(AsyncOperation operation)
{
AsyncOp.completed -= OnCompleted;
Scene = SceneManager.GetSceneAt(SceneManager.sceneCount - 1);
}

public async ValueTask<Scene> GetScene(CancellationToken ct)
{
return await Task.FromResult(Scene);
if (!AsyncOp.isDone)
{
#if UNITY_2023_2_OR_NEWER
await AsyncOp;
#else
while (!AsyncOp.isDone) await TaskHelper.NextFrame(ct);
#endif
}

// not pass cancellation token to SceneManager.UnloadSceneAsync
if (!Scene.IsValid()) await TaskHelper.NextFrame();

if (ct.IsCancellationRequested)
{
SceneManager.UnloadSceneAsync(Scene);
ct.ThrowIfCancellationRequested();
}
return Scene;
}

public bool Equals(Scene other)
Expand Down
13 changes: 11 additions & 2 deletions Runtime/Assets/Scene/SceneInstanceHandle.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#if USE_MEW_CORE_ASSETS
using System.Threading;
using System.Threading.Tasks;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.ResourceManagement.Exceptions;
Expand All @@ -10,17 +11,25 @@ namespace Mew.Core.Assets
public class SceneInstanceHandle : ISceneHandle
{
public AsyncOperationHandle<SceneInstance> Handle { get; }
private bool Comeleted => Handle.IsDone;
public float Progress => Handle.PercentComplete;
public bool Completed => Handle.IsDone;

public SceneInstanceHandle(AsyncOperationHandle<SceneInstance> asyncOperationHandle)
{
Handle = asyncOperationHandle;
}

public async ValueTask<Scene> GetScene()
public async ValueTask<Scene> GetScene(CancellationToken ct)
{
if (!Handle.IsDone)
await Handle.Task;

if (ct.IsCancellationRequested)
{
await UnifiedSceneLoader.UnloadAsync(this);
ct.ThrowIfCancellationRequested();
}

return Handle.Result.Scene;
}

Expand Down
13 changes: 11 additions & 2 deletions Runtime/Assets/Scene/SceneLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,27 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Mew.Core.TaskHelpers;
using UnityEngine;
using UnityEngine.SceneManagement;

namespace Mew.Core.Assets
{
public class SceneLoader : IAsyncDisposable
{
private List<ISceneHandle> SceneHandles { get; } = new();
private List<ISceneHandle> LoadingHandles { get; } = new();
private bool Disposed { get; set; }
public float Progression
=> LoadingHandles.Any()
? LoadingHandles.Sum(x => x.Progress) / LoadingHandles.Count
: 1f;

public async ValueTask<Scene> LoadAsync(UnifiedScene unifiedScene, CancellationToken cancellationToken = default)
{
var handle = await UnifiedSceneLoader.LoadAsync(unifiedScene, cancellationToken);
var scene = await handle.GetScene();
var handle = UnifiedSceneLoader.LoadAsync(unifiedScene);
LoadingHandles.Add(handle);
var scene = await handle.GetScene(cancellationToken);

if (Disposed)
{
Expand All @@ -27,6 +35,7 @@ public async ValueTask<Scene> LoadAsync(UnifiedScene unifiedScene, CancellationT
throw new TaskCanceledException();
}

LoadingHandles.Remove(handle);
SceneHandles.Add(handle);
return scene;
}
Expand Down
8 changes: 5 additions & 3 deletions Runtime/Assets/Scene/UnifiedSceneLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace Mew.Core.Assets
{
public static class UnifiedSceneLoader
{
public static async Task<ISceneHandle> LoadAsync(UnifiedScene unifiedScene, CancellationToken cancellationToken)
public static ISceneHandle LoadAsync(UnifiedScene unifiedScene)
{
var parameters = new LoadSceneParameters(LoadSceneMode.Additive, LocalPhysicsMode.None);
ISceneHandle handle;
Expand All @@ -42,13 +42,15 @@ public static async Task<ISceneHandle> LoadAsync(UnifiedScene unifiedScene, Canc
#endif
if (unifiedScene.SceneReference is not null && unifiedScene.SceneReference.IsValid)
{
handle = await CompatibleSceneLoader.LoadSceneAsync(unifiedScene, parameters);
var asyncOp = SceneManager.LoadSceneAsync(unifiedScene.SceneReference, parameters);
handle = new SceneHandle(asyncOp);
}
#if UNITY_EDITOR
// for test use
else if (!string.IsNullOrEmpty(unifiedScene.EditorScenePath))
{
handle = await CompatibleSceneLoader.LoadEditorSceneAsync(unifiedScene, parameters);
var asyncOp = EditorSceneManager.LoadSceneAsyncInPlayMode(unifiedScene.EditorScenePath , parameters ) ;
handle = new SceneHandle(asyncOp);
}
#endif
else
Expand Down

0 comments on commit a01f1a8

Please sign in to comment.