Files
Infratest/Assets/Code/Infrastructure/SceneLoader/SceneLoader.cs
T

97 lines
3.2 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using Code.Infrastructure.Configs;
using Code.Infrastructure.EventBus;
using Code.Infrastructure.Generators;
using Cysharp.Threading.Tasks;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.ResourceManagement.ResourceProviders;
using UnityEngine.SceneManagement;
namespace Code.Infrastructure.SceneLoader
{
[Config("Configs/SceneConfig",true)]
public class SceneInfo
{
[ToConfig] public AssetReference SceneAsset;
[ToConfig] public SceneId SceneId;
}
public partial class SceneLoader : IDisposable
{
private Dictionary<SceneId, SceneInfo> _sceneInfos = new();
private Dictionary<SceneId, Action> _scenesActions = new();
private EventBus.EventBus _eventBus;
partial void SetupScenesInfo();
private AsyncOperationHandle<IList<SceneInfoConfig>> _loadHandle;
public SceneLoader(EventBus.EventBus eventBus, IConfigLocator configLocator)
{
_eventBus = eventBus;
LoadConfigs(configLocator.TryGetManyConfigAssetReferences<SceneInfoConfig>()).Forget();
}
// TODO типилище
public async UniTaskVoid LoadSceneAsync(SceneId id, LoadSceneMode loadMode)
{
if (loadMode == LoadSceneMode.Single)
for (var i = 0; i < _loadedScenes.Count; i++)
UnloadSceneAsync(_loadedScenes.Keys.ToList()[i]).Forget();
_loadedScenes.Add(id,Addressables.LoadSceneAsync(_sceneInfos[id].SceneAsset, loadMode));
await _loadedScenes[id];
_scenesActions[id]();
}
private Dictionary<SceneId, AsyncOperationHandle<SceneInstance>> _loadedScenes = new();
public Scene GetScene(SceneId id) => _loadedScenes[id].Result.Scene;
public async UniTaskVoid UnloadSceneAsync(SceneId id)
{
await Addressables.UnloadSceneAsync(_loadedScenes[id]);
_loadedScenes.Remove(id);
}
private AsyncOperationHandle<IList<SceneInfoConfig>> _configHandle;
private async UniTaskVoid LoadConfigs(string configReferences)
{
_configHandle = Addressables.LoadAssetsAsync<SceneInfoConfig>(configReferences, OnSceneConfigLoaded, Addressables.MergeMode.Union);
await _configHandle.ToUniTask();
SetupScenesInfo();
_eventBus.RaiseEvent<ISceneConfigsLoadedHandle>(h => h.SceneConfigsLoaded());
}
private void OnSceneConfigLoaded(SceneInfoConfig sceneInfoConfig)
{
SceneInfo sceneInfo = new();
sceneInfo.SceneId = sceneInfoConfig.SceneId;
sceneInfo.SceneAsset = sceneInfoConfig.SceneAsset;
_sceneInfos.Add(sceneInfoConfig.SceneId, sceneInfo);
}
public void Dispose()
{
Addressables.Release(_configHandle);
}
}
public interface ISceneConfigsLoadedHandle : IGlobalSubscriber
{
void SceneConfigsLoaded();
}
public interface ILoadedSceneHandle : IGlobalSubscriber
{
void SceneLoaded(SceneId sceneId);
}
}