From 35dfe1a0805e2ea7e7955d081cc36a90f66574c3 Mon Sep 17 00:00:00 2001 From: NTG_Lenovo Date: Mon, 21 Jul 2025 16:53:39 +0900 Subject: [PATCH] =?UTF-8?q?Ui=20=EA=B8=B0=EB=B3=B8=20=EA=B5=AC=EC=A1=B0=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/_DDD/_Scripts/GameUi/BaseUi.cs | 26 ++++ Assets/_DDD/_Scripts/GameUi/FadeUi.cs | 51 +++++++ .../_DDD/_Scripts/GameUi/GlobalMessageUi.cs | 68 +++++++++ Assets/_DDD/_Scripts/GameUi/PopupUi.cs | 7 + Assets/_DDD/_Scripts/GameUi/ScreenUi.cs | 7 + Assets/_DDD/_Scripts/GameUi/UiManager.cs | 140 ++++++++++++++++++ 6 files changed, 299 insertions(+) create mode 100644 Assets/_DDD/_Scripts/GameUi/BaseUi.cs create mode 100644 Assets/_DDD/_Scripts/GameUi/FadeUi.cs create mode 100644 Assets/_DDD/_Scripts/GameUi/GlobalMessageUi.cs create mode 100644 Assets/_DDD/_Scripts/GameUi/PopupUi.cs create mode 100644 Assets/_DDD/_Scripts/GameUi/ScreenUi.cs create mode 100644 Assets/_DDD/_Scripts/GameUi/UiManager.cs diff --git a/Assets/_DDD/_Scripts/GameUi/BaseUi.cs b/Assets/_DDD/_Scripts/GameUi/BaseUi.cs new file mode 100644 index 000000000..da48fc1dd --- /dev/null +++ b/Assets/_DDD/_Scripts/GameUi/BaseUi.cs @@ -0,0 +1,26 @@ +using UnityEngine; + +namespace DDD +{ + public abstract class BaseUi : MonoBehaviour + { + public virtual bool IsBlockingTime => false; + public virtual bool IsOpen => gameObject.activeSelf; + + protected virtual void Start() + { + TryRegister(); + } + + protected virtual void OnDestroy() + { + TryUnregister(); + } + + protected virtual void TryRegister() { } + protected virtual void TryUnregister() { } + + public virtual void Open() => gameObject.SetActive(true); + public virtual void Close() => gameObject.SetActive(false); + } +} \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/GameUi/FadeUi.cs b/Assets/_DDD/_Scripts/GameUi/FadeUi.cs new file mode 100644 index 000000000..4469828d9 --- /dev/null +++ b/Assets/_DDD/_Scripts/GameUi/FadeUi.cs @@ -0,0 +1,51 @@ +using DG.Tweening; +using UnityEngine; + +namespace DDD +{ + public class FadeUi : MonoBehaviour, IEventHandler, IEventHandler + { + private CanvasGroup _canvasGroup; + + private void Awake() + { + _canvasGroup = GetComponent(); + + _canvasGroup.alpha = 0f; + _canvasGroup.gameObject.SetActive(false); + + EventBus.Register(this); + EventBus.Register(this); + } + + private void OnDestroy() + { + EventBus.Unregister(this); + EventBus.Unregister(this); + } + + public async void Invoke(FadeInEvent evt) + { + await _canvasGroup.DOFade(0f, evt.Duration) + .SetUpdate(true) + .AsyncWaitForCompletion(); + + _canvasGroup.blocksRaycasts = false; + _canvasGroup.gameObject.SetActive(false); + + evt.CompletionSource.SetResult(true); + } + + public async void Invoke(FadeOutEvent evt) + { + _canvasGroup.gameObject.SetActive(true); + _canvasGroup.blocksRaycasts = true; + + await _canvasGroup.DOFade(1f, evt.Duration) + .SetUpdate(true) + .AsyncWaitForCompletion(); + + evt.CompletionSource.SetResult(true); + } + } +} \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/GameUi/GlobalMessageUi.cs b/Assets/_DDD/_Scripts/GameUi/GlobalMessageUi.cs new file mode 100644 index 000000000..7d08b9621 --- /dev/null +++ b/Assets/_DDD/_Scripts/GameUi/GlobalMessageUi.cs @@ -0,0 +1,68 @@ +using System.Collections.Generic; +using DG.Tweening; +using TMPro; +using UnityEngine; + +namespace DDD +{ + public class GlobalMessageUi : BaseUi, IEventHandler + { + private CanvasGroup _canvasGroup; + private TextMeshProUGUI _messageText; + private Tween _fadeTween; + + private readonly Queue _messageQueue = new(); + private bool _isDisplayingMessage = false; + + private void Awake() + { + _canvasGroup = GetComponent(); + _messageText = GetComponentInChildren(); + + _canvasGroup.alpha = 0; + _messageText.text = null; + + EventBus.Register(this); + } + + protected override void OnDestroy() + { + base.OnDestroy(); + + EventBus.Unregister(this); + _fadeTween?.Kill(); + } + + public void Invoke(ShowGlobalMessageEvent evt) + { + _messageQueue.Enqueue(evt); + TryDisplayNext(); + } + + private void TryDisplayNext() + { + if (_isDisplayingMessage || _messageQueue.Count == 0) return; + + var evt = _messageQueue.Dequeue(); + _isDisplayingMessage = true; + + _messageText.text = LocalizationManager.GetString(TableName.Global_Message, evt.NewMessageKey); + Open(); + + _fadeTween?.Kill(); + _fadeTween = DOTween.Sequence() + .Append(_canvasGroup.DOFade(1f, evt.FadeDuration)) + .AppendInterval(evt.ShowDuration) + .Append(_canvasGroup.DOFade(0f, evt.FadeDuration)) + .OnComplete(() => + { + Close(); + _fadeTween = null; + _isDisplayingMessage = false; + + // 다음 메시지 처리 + TryDisplayNext(); + }); + } + } +} \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/GameUi/PopupUi.cs b/Assets/_DDD/_Scripts/GameUi/PopupUi.cs new file mode 100644 index 000000000..830988d16 --- /dev/null +++ b/Assets/_DDD/_Scripts/GameUi/PopupUi.cs @@ -0,0 +1,7 @@ +namespace DDD +{ + public class PopupUi : BaseUi + { + + } +} \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/GameUi/ScreenUi.cs b/Assets/_DDD/_Scripts/GameUi/ScreenUi.cs new file mode 100644 index 000000000..c4ab9b222 --- /dev/null +++ b/Assets/_DDD/_Scripts/GameUi/ScreenUi.cs @@ -0,0 +1,7 @@ +namespace DDD +{ + public class ScreenUi : BaseUi + { + + } +} \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/GameUi/UiManager.cs b/Assets/_DDD/_Scripts/GameUi/UiManager.cs new file mode 100644 index 000000000..6867b93d2 --- /dev/null +++ b/Assets/_DDD/_Scripts/GameUi/UiManager.cs @@ -0,0 +1,140 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace DDD +{ + public class UiManager : Singleton, IManager, IEventHandler, IEventHandler, + IEventHandler, IEventHandler + { + private readonly Dictionary _screenUIs = new(); + private readonly Dictionary _popupUIs = new(); + + private readonly object _uiPauseRequester = new(); + + public void PreInit() + { + EventBus.Register(this); + EventBus.Register(this); + EventBus.Register(this); + EventBus.Register(this); + } + + public Task Init() + { + return Task.CompletedTask; + } + + public void PostInit() + { + + } + + private void OnDestroy() + { + EventBus.Unregister(this); + EventBus.Unregister(this); + EventBus.Unregister(this); + EventBus.Unregister(this); + } + + public void RegisterScreenUI(ScreenUi ui) + { + var type = ui.GetType(); + _screenUIs.TryAdd(type, ui); + } + + public void UnregisterScreenUI(ScreenUi ui) + { + var type = ui.GetType(); + if (_screenUIs.TryGetValue(type, out var value) && value == ui) + { + _screenUIs.Remove(type); + } + } + + public void RegisterPopupUI(PopupUi ui) + { + var type = ui.GetType(); + _popupUIs.TryAdd(type, ui); + } + + public void UnregisterPopupUI(PopupUi ui) + { + var type = ui.GetType(); + if (_popupUIs.TryGetValue(type, out var registered) && registered == ui) + { + _popupUIs.Remove(type); + } + } + + private void CloseAllScreenUIs() + { + foreach (var screen in _screenUIs.Values) + { + if (screen.IsOpen) + { + screen.Close(); + + if (screen.IsBlockingTime) + { + EventBus.Broadcast(new TimeScaleChangeEvent(_uiPauseRequester, 1f)); + } + } + } + } + + public void Invoke(OpenScreenUiEvent evt) + { + if (_screenUIs.TryGetValue(evt.UiType, out var screen)) + { + CloseAllScreenUIs(); + screen.Open(); + + if (screen.IsBlockingTime) + { + EventBus.Broadcast(new TimeScaleChangeEvent(screen, 0f)); + } + } + } + + public void Invoke(CloseScreenUiEvent evt) + { + if (_screenUIs.TryGetValue(evt.UiType, out var screen)) + { + screen.Close(); + + if (screen.IsBlockingTime) + { + EventBus.Broadcast(new TimeScaleChangeEvent(screen, 1f)); + } + } + } + + public void Invoke(OpenPopupUiEvent evt) + { + if (_popupUIs.TryGetValue(evt.UiType, out var popup)) + { + popup.Open(); + + if (popup.IsBlockingTime) + { + EventBus.Broadcast(new TimeScaleChangeEvent(popup, 0f)); + } + } + } + + public void Invoke(ClosePopupUiEvent evt) + { + if (_screenUIs.TryGetValue(evt.UiType, out var popUp)) + { + popUp.Close(); + + if (popUp.IsBlockingTime) + { + EventBus.Broadcast(new TimeScaleChangeEvent(popUp, 1f)); + } + } + } + } +} \ No newline at end of file