mirror of
https://github.com/Kaveinator/NetickProForUnity.git
synced 2025-10-26 17:59:07 -07:00
Added support for custom scene handling, in addition to an addressable scene handler.
This commit is contained in:
166
Scripts/AddressableSceneHandler.cs
Normal file
166
Scripts/AddressableSceneHandler.cs
Normal file
@@ -0,0 +1,166 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEngine.AddressableAssets;
|
||||
using UnityEngine.ResourceManagement.AsyncOperations;
|
||||
using UnityEngine.ResourceManagement.ResourceProviders;
|
||||
using UnityEngine;
|
||||
using Netick.Unity;
|
||||
|
||||
namespace Netick.Samples
|
||||
{
|
||||
[AddComponentMenu("Netick/Addressable Scene Handler")]
|
||||
public class AddressableSceneHandler : NetworkSceneHandler
|
||||
{
|
||||
private class AddressableSceneOperation : ISceneOperation
|
||||
{
|
||||
AsyncOperationHandle<SceneInstance> Handle;
|
||||
bool ISceneOperation.IsDone => Handle.IsDone;
|
||||
float ISceneOperation.Progress => Handle.PercentComplete;
|
||||
public AddressableSceneOperation(AsyncOperationHandle<SceneInstance> handle)
|
||||
{
|
||||
Handle = handle;
|
||||
}
|
||||
}
|
||||
|
||||
public string[] AddressableScenes = new string[0];
|
||||
public override int CustomScenesCount => AddressableScenes != null ? AddressableScenes.Length : 0;
|
||||
|
||||
private Dictionary<string, int> _keyToIndex;
|
||||
private Dictionary<int, string> _indexToKey;
|
||||
private Dictionary<Scene, SceneInstance> _loadedScenes;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_keyToIndex = new(AddressableScenes.Length);
|
||||
_indexToKey = new(AddressableScenes.Length);
|
||||
_loadedScenes = new(AddressableScenes.Length);
|
||||
|
||||
for (int i = 0; i < AddressableScenes.Length; i++)
|
||||
{
|
||||
_keyToIndex.Add(AddressableScenes[i], i);
|
||||
_indexToKey.Add(i, AddressableScenes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
protected override ISceneOperation LoadCustomSceneAsync(int index, LoadSceneParameters loadSceneParameters, out string sceneName)
|
||||
{
|
||||
var key = _indexToKey[index];
|
||||
sceneName = key;
|
||||
|
||||
var handle = Addressables.LoadSceneAsync(key, loadSceneParameters);
|
||||
handle.Completed += handle =>
|
||||
{
|
||||
if (handle.Status == AsyncOperationStatus.Succeeded)
|
||||
_loadedScenes.Add(handle.Result.Scene, handle.Result);
|
||||
else
|
||||
Sandbox.LogError($"Addressables.LoadSceneAsync: failed to load an addressable scene {handle.DebugName}");
|
||||
};
|
||||
|
||||
return new AddressableSceneOperation(handle);
|
||||
}
|
||||
|
||||
protected override ISceneOperation UnloadCustomSceneAsync(Scene scene)
|
||||
{
|
||||
var didGetSceneInstance = _loadedScenes.TryGetValue(scene, out var sceneInstance);
|
||||
|
||||
if (!didGetSceneInstance || !scene.IsValid())
|
||||
{
|
||||
Sandbox.LogError($"Unloading scene: couldn't find a scene to unload {scene.name}");
|
||||
return null;
|
||||
}
|
||||
|
||||
var handle = Addressables.UnloadSceneAsync(sceneInstance);
|
||||
handle.Completed += handle =>
|
||||
{
|
||||
if (handle.Status == AsyncOperationStatus.Succeeded)
|
||||
_loadedScenes.Remove(handle.Result.Scene);
|
||||
else
|
||||
Sandbox.LogError($"Addressables.UnloadSceneAsync: failed to unload scene {scene.name}");
|
||||
};
|
||||
|
||||
return new AddressableSceneOperation(handle);
|
||||
}
|
||||
|
||||
// -- Addressable Scenes
|
||||
public void LoadAddressableSceneAsync(string key, LoadSceneMode loadSceneMode)
|
||||
{
|
||||
if (_keyToIndex.TryGetValue(key, out int customIndex))
|
||||
Sandbox.LoadCustomSceneAsync(customIndex, new LoadSceneParameters(loadSceneMode, Sandbox.GetDefaultPhysicsMode()));
|
||||
else
|
||||
Sandbox.LogError("Loading scene: failed to find the addressable scene key in the AddressableScenes array. Make sure to add all scenes keys to the array.");
|
||||
}
|
||||
|
||||
public void LoadAddressableSceneAsync(string key, LoadSceneParameters loadSceneParameters)
|
||||
{
|
||||
if (_keyToIndex.TryGetValue(key, out int customIndex))
|
||||
Sandbox.LoadCustomSceneAsync(customIndex, loadSceneParameters);
|
||||
else
|
||||
Sandbox.LogError("Loading scene: failed to find the addressable scene key in the AddressableScenes array. Make sure to add all scenes keys to the array.");
|
||||
}
|
||||
|
||||
public void UnloadAddressableSceneAsync(string key)
|
||||
{
|
||||
if (_keyToIndex.TryGetValue(key, out int customIndex))
|
||||
Sandbox.UnloadSceneAsync(customIndex);
|
||||
else
|
||||
Sandbox.LogError("Unloading scene: failed to find the addressable scene key in the AddressableScenes array. Make sure to add all scenes keys to the array.");
|
||||
}
|
||||
|
||||
public void UnloadAddressableSceneAsync(Scene scene)
|
||||
{
|
||||
Sandbox.UnloadSceneAsync(scene);
|
||||
}
|
||||
|
||||
// -- Build Scenes
|
||||
// NetworkSceneHandler already implements exactly the code shown here, the reason we still included it in here is for demonstration purposes.
|
||||
protected override AsyncOperation LoadBuildSceneAsync(int buildIndex, LoadSceneParameters loadSceneParameters) => SceneManager.LoadSceneAsync(buildIndex, loadSceneParameters);
|
||||
protected override AsyncOperation UnloadBuildSceneAsync(Scene scene) => SceneManager.UnloadSceneAsync(scene);
|
||||
}
|
||||
|
||||
public static class AddressableSceneHandlerSandboxExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// <i><b>[Server Only]</b></i> Loads an addressable scene asynchronously using a key.
|
||||
/// </summary>
|
||||
public static void LoadAddressableSceneAsync(this NetworkSandbox sandbox, string key, LoadSceneMode loadSceneMode)
|
||||
{
|
||||
if (sandbox.TryGetComponent<AddressableSceneHandler>(out var defaultSceneHandler))
|
||||
defaultSceneHandler.LoadAddressableSceneAsync(key, loadSceneMode);
|
||||
else
|
||||
sandbox.LogError($"{nameof(AddressableSceneHandler)} is not added to the sandbox. Make sure to add {nameof(AddressableSceneHandler)} to your sandbox prefab.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <i><b>[Server Only]</b></i> Loads an addressable scene asynchronously using a key.
|
||||
/// </summary>
|
||||
public static void LoadAddressableSceneAsync(this NetworkSandbox sandbox, string key, LoadSceneParameters loadSceneParameters)
|
||||
{
|
||||
if (sandbox.TryGetComponent<AddressableSceneHandler>(out var defaultSceneHandler))
|
||||
defaultSceneHandler.LoadAddressableSceneAsync(key, loadSceneParameters);
|
||||
else
|
||||
sandbox.LogError($"{nameof(AddressableSceneHandler)} is not added to the sandbox. Make sure to add {nameof(AddressableSceneHandler)} to your sandbox prefab.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <i><b>[Server Only]</b></i> Unloads an addressable scene asynchronously using a key.
|
||||
/// </summary>
|
||||
public static void UnloadAddressableSceneAsync(this NetworkSandbox sandbox, string key)
|
||||
{
|
||||
if (sandbox.TryGetComponent<AddressableSceneHandler>(out var defaultSceneHandler))
|
||||
defaultSceneHandler.UnloadAddressableSceneAsync(key);
|
||||
else
|
||||
sandbox.LogError($"{nameof(AddressableSceneHandler)} is not added to the sandbox. Make sure to add {nameof(AddressableSceneHandler)} to your sandbox prefab.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <i><b>[Server Only]</b></i> Unloads an addressable scene asynchronously using a Scene struct.
|
||||
/// </summary>
|
||||
public static void UnloadAddressableSceneAsync(this NetworkSandbox sandbox, Scene scene)
|
||||
{
|
||||
if (sandbox.TryGetComponent<AddressableSceneHandler>(out var defaultSceneHandler))
|
||||
defaultSceneHandler.UnloadAddressableSceneAsync(scene);
|
||||
else
|
||||
sandbox.LogError($"{nameof(AddressableSceneHandler)} is not added to the sandbox. Make sure to add {nameof(AddressableSceneHandler)} to your sandbox prefab.");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user