106 lines
3.3 KiB
C#
106 lines
3.3 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;
|
|
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)
|
|
{
|
|
if ((await Addressables.LoadResourceLocationsAsync(configReferences).Task).Count != 0)
|
|
{
|
|
|
|
_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()
|
|
{
|
|
if(_configHandle.IsValid()) _configHandle.Release();
|
|
}
|
|
}
|
|
|
|
public interface ISceneConfigsLoadedHandle : IGlobalSubscriber
|
|
{
|
|
void SceneConfigsLoaded();
|
|
}
|
|
|
|
public interface ILoadedSceneHandle : IGlobalSubscriber
|
|
{
|
|
void SceneLoaded(SceneId sceneId);
|
|
}
|
|
} |