키 바인딩 시스템에 맞게 ui 시스템 개편

This commit is contained in:
NTG_Lenovo 2025-07-23 12:24:52 +09:00
parent 7d9c064165
commit 2b483bf213
7 changed files with 87 additions and 34 deletions

View File

@ -0,0 +1,7 @@
namespace DDD
{
public abstract class BasePopupUi : BaseUi
{
public abstract InputActionMaps InputActionMaps { get; }
}
}

View File

@ -6,7 +6,7 @@ public abstract class BaseUi : MonoBehaviour
{ {
protected GameObject _panel; protected GameObject _panel;
public virtual bool IsBlockingTime => false; public virtual bool IsBlockingTime => false;
public virtual bool IsOpen => gameObject.activeSelf; public virtual bool IsOpen => _panel.activeSelf;
protected virtual void Awake() protected virtual void Awake()
{ {
@ -16,6 +16,7 @@ protected virtual void Awake()
protected virtual void Start() protected virtual void Start()
{ {
TryRegister(); TryRegister();
Close();
} }
protected virtual void OnDestroy() protected virtual void OnDestroy()

View File

@ -5,40 +5,56 @@
namespace DDD namespace DDD
{ {
public class PopupUi : BaseUi public static class EnumExtensions
{ {
protected UiInputBindingSo _uiInputBindingSo; public static IEnumerable<T> GetFlags<T>(this T input) where T : Enum
{
foreach (T value in Enum.GetValues(typeof(T)))
{
int intValue = Convert.ToInt32(value);
int inputValue = Convert.ToInt32(input);
if (intValue != 0 && (inputValue & intValue) == intValue) yield return value;
}
}
}
public abstract class PopupUi<T> : BasePopupUi where T : Enum
{
protected BaseUiActionsInputBindingSo<T> _baseUiActionsInputBindingSo;
protected readonly List<(InputAction action, Action<InputAction.CallbackContext> handler)> _registeredHandlers = new(); protected readonly List<(InputAction action, Action<InputAction.CallbackContext> handler)> _registeredHandlers = new();
public override InputActionMaps InputActionMaps => _baseUiActionsInputBindingSo.InputActionMaps;
private bool _isTopPopup => UiManager.Instance.IsTopPopup(this);
private const string InputBindingSo = "InputBindingSo";
protected override async void TryRegister() protected override async void TryRegister()
{ {
base.TryRegister(); base.TryRegister();
UiManager.Instance.RegisterPopupUI(this); UiManager.Instance.RegisterPopupUI(this);
// So의 이름을 통일 : TestUi_UiInputBindingSo string addressableKey = $"{GetType().Name}_{typeof(T).Name}_{InputBindingSo}";
string addressableKey = $"{GetType().Name}_{DataConstants.UiInputBindingSo}"; _baseUiActionsInputBindingSo = await AssetManager.LoadAsset<BaseUiActionsInputBindingSo<T>>(addressableKey);
_uiInputBindingSo = await AssetManager.LoadAsset<UiInputBindingSo>(addressableKey);
Debug.Assert(_uiInputBindingSo != null, "_uiInputBindingSo != null");
foreach (var binding in _uiInputBindingSo.Bindings) Debug.Assert(_baseUiActionsInputBindingSo != null, $"InputBindingSo not found: {addressableKey}");
foreach (var actionEnum in _baseUiActionsInputBindingSo.BindingActions.GetFlags())
{ {
if (binding.InputAction == null) continue; if (actionEnum.Equals(default(T))) continue;
var action = binding.InputAction.action; var inputAction = InputManager.Instance.GetAction(_baseUiActionsInputBindingSo.InputActionMaps, actionEnum.ToString());
if (action == null) continue; if (inputAction == null) continue;
var handler = new Action<InputAction.CallbackContext>(ctx => var handler = new Action<InputAction.CallbackContext>(context =>
{ {
if (UiManager.Instance.IsTopPopup(this)) if (!_isTopPopup) return;
{
OnInputPerformed(binding.ActionName, ctx); OnInputPerformed(actionEnum, context);
}
}); });
action.Enable(); inputAction.performed += handler;
action.performed += handler; _registeredHandlers.Add((inputAction, handler));
_registeredHandlers.Add((action, handler));
} }
} }
@ -67,12 +83,10 @@ public override void Open()
if (UiManager.Instance.IsTopPopup(this)) if (UiManager.Instance.IsTopPopup(this))
{ {
InputManager.Instance.SwitchCurrentActionMap(_uiInputBindingSo.InputActionMaps); InputManager.Instance.SwitchCurrentActionMap(_baseUiActionsInputBindingSo.InputActionMaps);
} }
} }
protected virtual void OnInputPerformed(string actionName, InputAction.CallbackContext ctx) { } protected abstract void OnInputPerformed(T actionEnum, InputAction.CallbackContext ctx);
public InputActionMaps GetInputActionMaps() => _uiInputBindingSo.InputActionMaps;
} }
} }

View File

@ -7,8 +7,8 @@ namespace DDD
{ {
public class UiManager : Singleton<UiManager>, IManager, IEventHandler<OpenPopupUiEvent>, IEventHandler<ClosePopupUiEvent> public class UiManager : Singleton<UiManager>, IManager, IEventHandler<OpenPopupUiEvent>, IEventHandler<ClosePopupUiEvent>
{ {
private readonly Dictionary<Type, PopupUi> _popupUIs = new(); private readonly Dictionary<Type, BasePopupUi> _popupUIs = new();
private readonly Stack<PopupUi> _popupStack = new(); private readonly Stack<BasePopupUi> _popupStack = new();
private InputActionMaps _previousActionMap = InputActionMaps.None; private InputActionMaps _previousActionMap = InputActionMaps.None;
private readonly object _uiPauseRequester = new(); private readonly object _uiPauseRequester = new();
@ -35,13 +35,13 @@ private void OnDestroy()
EventBus.Unregister<ClosePopupUiEvent>(this); EventBus.Unregister<ClosePopupUiEvent>(this);
} }
public void RegisterPopupUI(PopupUi ui) public void RegisterPopupUI(BasePopupUi ui)
{ {
var type = ui.GetType(); var type = ui.GetType();
_popupUIs.TryAdd(type, ui); _popupUIs.TryAdd(type, ui);
} }
public void UnregisterPopupUI(PopupUi ui) public void UnregisterPopupUI(BasePopupUi ui)
{ {
var type = ui.GetType(); var type = ui.GetType();
if (_popupUIs.TryGetValue(type, out var registered) && registered == ui) if (_popupUIs.TryGetValue(type, out var registered) && registered == ui)
@ -56,8 +56,8 @@ public void Invoke(OpenPopupUiEvent evt)
{ {
if (!popup.IsOpen) if (!popup.IsOpen)
{ {
popup.Open();
PushPopup(popup); PushPopup(popup);
popup.Open();
if (popup.IsBlockingTime) if (popup.IsBlockingTime)
{ {
@ -90,12 +90,12 @@ public void Invoke(ClosePopupUiEvent evt)
} }
} }
public bool IsTopPopup(PopupUi popup) public bool IsTopPopup(BasePopupUi popup)
{ {
return _popupStack.Count > 0 && _popupStack.Peek() == popup; return _popupStack.Count > 0 && _popupStack.Peek() == popup;
} }
public void PushPopup(PopupUi popup) public void PushPopup(BasePopupUi popup)
{ {
if (_popupStack.Contains(popup)) return; if (_popupStack.Contains(popup)) return;
@ -107,7 +107,7 @@ public void PushPopup(PopupUi popup)
_popupStack.Push(popup); _popupStack.Push(popup);
} }
public void PopPopup(PopupUi popup) public void PopPopup(BasePopupUi popup)
{ {
if (_popupStack.Count == 0) return; if (_popupStack.Count == 0) return;
@ -127,7 +127,7 @@ public void PopPopup(PopupUi popup)
if (_popupStack.TryPeek(out var topPopup) && topPopup.IsOpen) if (_popupStack.TryPeek(out var topPopup) && topPopup.IsOpen)
{ {
InputManager.Instance.SwitchCurrentActionMap(topPopup.GetInputActionMaps()); InputManager.Instance.SwitchCurrentActionMap(topPopup.InputActionMaps);
} }
else else
{ {

View File

@ -0,0 +1,17 @@
using System;
using Sirenix.OdinInspector;
using UnityEngine;
namespace DDD
{
public class BaseUiActionsInputBindingSo<T> : ScriptableObject where T : Enum
{
public InputActionMaps InputActionMaps;
[EnumToggleButtons]
public T BindingActions;
[ReadOnly, LabelText("Addressable Key")]
public string AddressableKey => $"{typeof(T).Name}_InputBindingSo";
}
}

View File

@ -0,0 +1,7 @@
using UnityEngine;
namespace DDD
{
[CreateAssetMenu(fileName = "_RestaurantActions_InputBindingSo", menuName = "Ui/RestaurantActions_InputBindingSo")]
public class RestaurantActionsInputBindingSo : BaseUiActionsInputBindingSo<RestaurantActions> { }
}

View File

@ -0,0 +1,7 @@
using UnityEngine;
namespace DDD
{
[CreateAssetMenu(fileName = "_RestaurantUiActions_InputBindingSo", menuName = "Ui/RestaurantUiActions_InputBindingSo")]
public class RestaurantUiActionsInputBindingSo : BaseUiActionsInputBindingSo<RestaurantUiActions> { }
}