SceneType 제거 버전
This commit is contained in:
parent
51c5cace09
commit
2b6b425903
@ -49,7 +49,7 @@ public void ChangeFlow(GameFlowState newFlowState)
|
|||||||
|
|
||||||
EndCurrentFlow();
|
EndCurrentFlow();
|
||||||
|
|
||||||
ReadyNewFlow(newFlowState);
|
_ = ReadyNewFlow(newFlowState);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool CanChangeFlow(GameFlowState newFlowState)
|
private bool CanChangeFlow(GameFlowState newFlowState)
|
||||||
@ -62,7 +62,7 @@ private void EndCurrentFlow()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void ReadyNewFlow(GameFlowState newFlowState)
|
private async Task ReadyNewFlow(GameFlowState newFlowState)
|
||||||
{
|
{
|
||||||
GameFlowDataSo.CurrentGameState = newFlowState;
|
GameFlowDataSo.CurrentGameState = newFlowState;
|
||||||
|
|
||||||
@ -71,33 +71,26 @@ private async void ReadyNewFlow(GameFlowState newFlowState)
|
|||||||
await handler.OnReadyNewFlow(newFlowState);
|
await handler.OnReadyNewFlow(newFlowState);
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenFlowScene(newFlowState);
|
await OpenFlowScene(newFlowState);
|
||||||
|
|
||||||
StartFlow();
|
StartFlow();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void OpenFlowScene(GameFlowState newFlowState)
|
private async Task OpenFlowScene(GameFlowState newFlowState)
|
||||||
{
|
{
|
||||||
try
|
if (GetFlowScene(newFlowState))
|
||||||
{
|
{
|
||||||
if (GetFlowScene(newFlowState, out var sceneToLoad))
|
await SceneManager.Instance.ActivateScene(newFlowState);
|
||||||
{
|
|
||||||
await SceneManager.Instance.ActivateScene(sceneToLoad);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "Scene not found!");
|
Debug.Assert(false, "Scene not found!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Debug.LogError(e.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool GetFlowScene(GameFlowState flowState, out SceneType sceneType)
|
private bool GetFlowScene(GameFlowState flowState)
|
||||||
{
|
{
|
||||||
return GameFlowSceneMappingSo.FlowToSceneMapping.TryGetValue(flowState, out sceneType);
|
return GameFlowSceneMappingSo.FlowToSceneMapping.ContainsKey(flowState);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StartFlow()
|
private void StartFlow()
|
||||||
|
@ -9,7 +9,6 @@ namespace DDD
|
|||||||
[CreateAssetMenu(fileName = "GameFlowSceneMappingSo", menuName = "GameFlow/GameFlowSceneMappingSo")]
|
[CreateAssetMenu(fileName = "GameFlowSceneMappingSo", menuName = "GameFlow/GameFlowSceneMappingSo")]
|
||||||
public class GameFlowSceneMappingSo : SerializedScriptableObject
|
public class GameFlowSceneMappingSo : SerializedScriptableObject
|
||||||
{
|
{
|
||||||
public Dictionary<GameFlowState, SceneType> FlowToSceneMapping = new();
|
public Dictionary<GameFlowState, AssetReference> FlowToSceneMapping = new();
|
||||||
public Dictionary<SceneType, AssetReference> AssetMapping = new();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -15,7 +15,7 @@ public class FadeSceneTransitionHandlerSo : SceneTransitionHandler
|
|||||||
[SerializeField]
|
[SerializeField]
|
||||||
private float _fadeInDuration = 0.5f;
|
private float _fadeInDuration = 0.5f;
|
||||||
|
|
||||||
public override async Task OnBeforeSceneActivate(SceneType sceneType)
|
public override async Task OnBeforeSceneActivate()
|
||||||
{
|
{
|
||||||
var evt = GameEvents.FadeOutEvent;
|
var evt = GameEvents.FadeOutEvent;
|
||||||
evt.Duration = _fadeOutDuration;
|
evt.Duration = _fadeOutDuration;
|
||||||
@ -23,7 +23,7 @@ public override async Task OnBeforeSceneActivate(SceneType sceneType)
|
|||||||
await evt.WaitAsync();
|
await evt.WaitAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task OnAfterSceneActivate(SceneType sceneType)
|
public override async Task OnAfterSceneActivate()
|
||||||
{
|
{
|
||||||
float seconds = _delayBeforeFadeIn * 1000;
|
float seconds = _delayBeforeFadeIn * 1000;
|
||||||
await Task.Delay((int)(seconds));
|
await Task.Delay((int)(seconds));
|
||||||
|
@ -6,19 +6,12 @@
|
|||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
#endif
|
#endif
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using UnityEngine.AddressableAssets;
|
||||||
using UnityEngine.ResourceManagement.ResourceProviders;
|
using UnityEngine.ResourceManagement.ResourceProviders;
|
||||||
using UnityEngine.SceneManagement;
|
using UnityEngine.SceneManagement;
|
||||||
|
|
||||||
namespace DDD
|
namespace DDD
|
||||||
{
|
{
|
||||||
public enum SceneType
|
|
||||||
{
|
|
||||||
None = 0,
|
|
||||||
Entry = 1,
|
|
||||||
Restaurant = 2,
|
|
||||||
Voyage = 3
|
|
||||||
}
|
|
||||||
|
|
||||||
public class SceneData
|
public class SceneData
|
||||||
{
|
{
|
||||||
public Scene Scene { get; }
|
public Scene Scene { get; }
|
||||||
@ -36,45 +29,39 @@ public class SceneManager : Singleton<SceneManager>, IManager
|
|||||||
[SerializeField]
|
[SerializeField]
|
||||||
private SceneTransitionHandlerSo _sceneTransitionHandlerSo;
|
private SceneTransitionHandlerSo _sceneTransitionHandlerSo;
|
||||||
|
|
||||||
private Dictionary<SceneType, SceneData> _loadedSceneDatas;
|
private readonly Dictionary<GameFlowState, SceneData> _loadedSceneDatas = new();
|
||||||
private SceneType _currentSceneType = SceneType.None;
|
private readonly Dictionary<string, SceneData> _assetKeyToSceneData = new();
|
||||||
|
|
||||||
public void PreInit()
|
public void PreInit()
|
||||||
{
|
{
|
||||||
Array sceneTypeArray = Enum.GetValues(typeof(SceneType));
|
_loadedSceneDatas.Clear();
|
||||||
_loadedSceneDatas = new Dictionary<SceneType, SceneData>(sceneTypeArray.Length - 1);
|
_assetKeyToSceneData.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Init()
|
public async Task Init()
|
||||||
{
|
{
|
||||||
var activeScene = UnityEngine.SceneManagement.SceneManager.GetActiveScene();
|
var activeScene = UnityEngine.SceneManagement.SceneManager.GetActiveScene();
|
||||||
var activeScenePath = activeScene.path;
|
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
foreach (var sceneAssetPair in GameFlowManager.Instance.GameFlowSceneMappingSo.AssetMapping)
|
var flowToSceneMapping = GameFlowManager.Instance.GameFlowSceneMappingSo.FlowToSceneMapping;
|
||||||
{
|
|
||||||
var asset = sceneAssetPair.Value.editorAsset;
|
|
||||||
if (asset == null) continue;
|
|
||||||
|
|
||||||
string assetPath = AssetDatabase.GetAssetPath(asset);
|
foreach (var pair in flowToSceneMapping)
|
||||||
if (string.IsNullOrWhiteSpace(assetPath)) continue;
|
|
||||||
|
|
||||||
if (assetPath == activeScenePath)
|
|
||||||
{
|
{
|
||||||
_currentSceneType = sceneAssetPair.Key;
|
var editorAsset = pair.Value.editorAsset;
|
||||||
_loadedSceneDatas.Add(_currentSceneType, new SceneData(activeScene, null));
|
if (editorAsset == null) continue;
|
||||||
|
|
||||||
|
var path = AssetDatabase.GetAssetPath(editorAsset);
|
||||||
|
if (string.IsNullOrWhiteSpace(path) == false && path == activeScene.path)
|
||||||
|
{
|
||||||
|
var data = new SceneData(activeScene, null);
|
||||||
|
_loadedSceneDatas[pair.Key] = data;
|
||||||
|
_assetKeyToSceneData[GetRuntimeKey(pair.Value)] = data;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_currentSceneType == SceneType.None)
|
|
||||||
{
|
|
||||||
Debug.LogWarning($"[SceneManager] 활성 씬이 AssetMapping에 존재하지 않습니다: {activeScenePath}");
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
_currentSceneType = SceneType.Entry;
|
var data = new SceneData(activeScene, null);
|
||||||
_loadedSceneDatas.Add(_currentSceneType, new SceneData(activeScene, null));
|
_loadedSceneDatas[GameFlowState.None] = data;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
await PreloadAll();
|
await PreloadAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,56 +70,86 @@ public void PostInit()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task PreloadSceneBySceneType(SceneType sceneType)
|
public async Task PreloadScene(GameFlowState gameFlowState)
|
||||||
{
|
{
|
||||||
if (_loadedSceneDatas.ContainsKey(sceneType)) return;
|
if (_loadedSceneDatas.ContainsKey(gameFlowState)) return;
|
||||||
|
|
||||||
var kvp = GameFlowManager.Instance.GameFlowSceneMappingSo.AssetMapping.FirstOrDefault(kvp => kvp.Key == sceneType);
|
if (!GameFlowManager.Instance.GameFlowSceneMappingSo.FlowToSceneMapping.TryGetValue(gameFlowState, out var assetRef))
|
||||||
var preloadedSceneInstance = await AssetManager.LoadScene(kvp.Value);
|
{
|
||||||
|
Debug.LogError($"[SceneManager] {gameFlowState}의 AssetReference가 없습니다.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (preloadedSceneInstance.Scene.IsValid())
|
var runtimeKey = GetRuntimeKey(assetRef);
|
||||||
|
if (_assetKeyToSceneData.TryGetValue(runtimeKey, out var existing))
|
||||||
{
|
{
|
||||||
DeactivateScene(preloadedSceneInstance.Scene);
|
_loadedSceneDatas[gameFlowState] = existing;
|
||||||
_loadedSceneDatas.Add(kvp.Key, new SceneData(preloadedSceneInstance.Scene, preloadedSceneInstance));
|
return;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
var loadedInstance = await AssetManager.LoadScene(assetRef);
|
||||||
|
if (!loadedInstance.Scene.IsValid())
|
||||||
{
|
{
|
||||||
Debug.LogError($"[SceneManager] {sceneType}의 씬이 존재하지 않습니다.");
|
Debug.LogError($"[SceneManager] {gameFlowState}의 씬 로딩 실패");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DeactivateScene(loadedInstance.Scene);
|
||||||
|
|
||||||
|
var data = new SceneData(loadedInstance.Scene, loadedInstance);
|
||||||
|
_loadedSceneDatas[gameFlowState] = data;
|
||||||
|
_assetKeyToSceneData[runtimeKey] = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task PreloadAll()
|
public async Task PreloadAll()
|
||||||
{
|
{
|
||||||
var assetMapping = GameFlowManager.Instance.GameFlowSceneMappingSo.AssetMapping;
|
var flowToSceneMapping = GameFlowManager.Instance.GameFlowSceneMappingSo.FlowToSceneMapping;
|
||||||
foreach (var kvp in assetMapping)
|
|
||||||
{
|
|
||||||
if (_loadedSceneDatas.ContainsKey(kvp.Key)) continue;
|
|
||||||
|
|
||||||
var preloadedSceneInstance = await AssetManager.LoadScene(kvp.Value);
|
foreach (var pair in flowToSceneMapping)
|
||||||
|
{
|
||||||
|
if (_loadedSceneDatas.ContainsKey(pair.Key)) continue;
|
||||||
|
|
||||||
if (preloadedSceneInstance.Scene.IsValid())
|
var runtimeKey = GetRuntimeKey(pair.Value);
|
||||||
|
if (_assetKeyToSceneData.TryGetValue(runtimeKey, out var existing))
|
||||||
{
|
{
|
||||||
DeactivateScene(preloadedSceneInstance.Scene);
|
_loadedSceneDatas[pair.Key] = existing;
|
||||||
_loadedSceneDatas.Add(kvp.Key, new SceneData(preloadedSceneInstance.Scene, preloadedSceneInstance));
|
continue;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
var instance = await AssetManager.LoadScene(pair.Value);
|
||||||
|
if (!instance.Scene.IsValid())
|
||||||
{
|
{
|
||||||
Debug.LogError($"[SceneManager] {kvp.Key}의 씬이 존재하지 않습니다.");
|
Debug.LogError($"[SceneManager] {pair.Key}의 씬 로딩 실패");
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DeactivateScene(instance.Scene);
|
||||||
|
var data = new SceneData(instance.Scene, instance);
|
||||||
|
_loadedSceneDatas[pair.Key] = data;
|
||||||
|
_assetKeyToSceneData[runtimeKey] = data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task ActivateScene(SceneType sceneType)
|
public async Task ActivateScene(GameFlowState newFlowState)
|
||||||
{
|
{
|
||||||
if (_currentSceneType == sceneType) return;
|
if (!_loadedSceneDatas.TryGetValue(newFlowState, out var sceneData))
|
||||||
|
{
|
||||||
|
Debug.LogError($"[SceneManager] Scene not loaded: {newFlowState}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var activeScene = UnityEngine.SceneManagement.SceneManager.GetActiveScene();
|
||||||
|
if (sceneData.Scene == activeScene)
|
||||||
|
{
|
||||||
|
Debug.Log($"[SceneManager] 이미 활성화된 씬입니다: {newFlowState}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var handler in _sceneTransitionHandlerSo.Handlers.Where(handler => handler != null))
|
foreach (var handler in _sceneTransitionHandlerSo.Handlers.Where(handler => handler != null))
|
||||||
{
|
{
|
||||||
await handler.OnBeforeSceneActivate(sceneType);
|
await handler.OnBeforeSceneActivate();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_loadedSceneDatas.TryGetValue(sceneType, out var sceneData))
|
|
||||||
{
|
|
||||||
foreach (var root in sceneData.Scene.GetRootGameObjects())
|
foreach (var root in sceneData.Scene.GetRootGameObjects())
|
||||||
{
|
{
|
||||||
root.SetActive(true);
|
root.SetActive(true);
|
||||||
@ -141,32 +158,23 @@ public async Task ActivateScene(SceneType sceneType)
|
|||||||
if (sceneData.Scene.IsValid())
|
if (sceneData.Scene.IsValid())
|
||||||
{
|
{
|
||||||
UnityEngine.SceneManagement.SceneManager.SetActiveScene(sceneData.Scene);
|
UnityEngine.SceneManagement.SceneManager.SetActiveScene(sceneData.Scene);
|
||||||
_currentSceneType = sceneType;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Debug.LogError($"[SceneManager] {sceneType}의 Scene이 유효하지 않습니다.");
|
Debug.LogError($"[SceneManager] {newFlowState}의 Scene이 유효하지 않습니다.");
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Debug.LogError($"[SceneManager] Scene not loaded: {sceneType}");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var handler in _sceneTransitionHandlerSo.Handlers.Where(handler => handler != null))
|
foreach (var handler in _sceneTransitionHandlerSo.Handlers.Where(handler => handler != null))
|
||||||
{
|
{
|
||||||
await handler.OnAfterSceneActivate(sceneType);
|
await handler.OnAfterSceneActivate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DeactivateScene(SceneType sceneType)
|
public void DeactivateScene(GameFlowState gameFlowState)
|
||||||
{
|
{
|
||||||
if (_loadedSceneDatas.TryGetValue(sceneType, out var sceneData))
|
if (_loadedSceneDatas.TryGetValue(gameFlowState, out var sceneData))
|
||||||
{
|
{
|
||||||
foreach (var root in sceneData.Scene.GetRootGameObjects())
|
DeactivateScene(sceneData.Scene);
|
||||||
{
|
|
||||||
root.SetActive(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,17 +186,23 @@ private void DeactivateScene(Scene scene)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task UnloadSceneBySceneType(SceneType sceneType)
|
public async Task UnloadScene(GameFlowState gameFlowState)
|
||||||
{
|
{
|
||||||
if (_loadedSceneDatas.TryGetValue(sceneType, out var sceneData))
|
if (_loadedSceneDatas.TryGetValue(gameFlowState, out var sceneData))
|
||||||
{
|
{
|
||||||
if (sceneData.SceneInstance == null) return;
|
if (sceneData.SceneInstance == null) return;
|
||||||
|
|
||||||
if (GameFlowManager.Instance.GameFlowSceneMappingSo.AssetMapping.ContainsKey(sceneType))
|
if (GameFlowManager.Instance.GameFlowSceneMappingSo.FlowToSceneMapping
|
||||||
|
.TryGetValue(gameFlowState, out var assetRef))
|
||||||
{
|
{
|
||||||
await AssetManager.UnloadScene((SceneInstance)sceneData.SceneInstance);
|
_assetKeyToSceneData.Remove(GetRuntimeKey(assetRef));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_loadedSceneDatas.Remove(gameFlowState);
|
||||||
|
await AssetManager.UnloadScene(sceneData.SceneInstance.Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string GetRuntimeKey(AssetReference reference) => reference.RuntimeKey.ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,7 +5,7 @@ namespace DDD
|
|||||||
{
|
{
|
||||||
public abstract class SceneTransitionHandler : ScriptableObject
|
public abstract class SceneTransitionHandler : ScriptableObject
|
||||||
{
|
{
|
||||||
public abstract Task OnBeforeSceneActivate(SceneType sceneType);
|
public abstract Task OnBeforeSceneActivate();
|
||||||
public abstract Task OnAfterSceneActivate(SceneType sceneType);
|
public abstract Task OnAfterSceneActivate();
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user