키 바인딩 시스템에 맞게 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;
public virtual bool IsBlockingTime => false;
public virtual bool IsOpen => gameObject.activeSelf;
public virtual bool IsOpen => _panel.activeSelf;
protected virtual void Awake()
{
@ -16,6 +16,7 @@ protected virtual void Awake()
protected virtual void Start()
{
TryRegister();
Close();
}
protected virtual void OnDestroy()

View File

@ -5,40 +5,56 @@
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();
public override InputActionMaps InputActionMaps => _baseUiActionsInputBindingSo.InputActionMaps;
private bool _isTopPopup => UiManager.Instance.IsTopPopup(this);
private const string InputBindingSo = "InputBindingSo";
protected override async void TryRegister()
{
base.TryRegister();
UiManager.Instance.RegisterPopupUI(this);
// So의 이름을 통일 : TestUi_UiInputBindingSo
string addressableKey = $"{GetType().Name}_{DataConstants.UiInputBindingSo}";
_uiInputBindingSo = await AssetManager.LoadAsset<UiInputBindingSo>(addressableKey);
Debug.Assert(_uiInputBindingSo != null, "_uiInputBindingSo != null");
string addressableKey = $"{GetType().Name}_{typeof(T).Name}_{InputBindingSo}";
_baseUiActionsInputBindingSo = await AssetManager.LoadAsset<BaseUiActionsInputBindingSo<T>>(addressableKey);
Debug.Assert(_baseUiActionsInputBindingSo != null, $"InputBindingSo not found: {addressableKey}");
foreach (var binding in _uiInputBindingSo.Bindings)
foreach (var actionEnum in _baseUiActionsInputBindingSo.BindingActions.GetFlags())
{
if (binding.InputAction == null) continue;
if (actionEnum.Equals(default(T))) continue;
var inputAction = InputManager.Instance.GetAction(_baseUiActionsInputBindingSo.InputActionMaps, actionEnum.ToString());
if (inputAction == null) continue;
var action = binding.InputAction.action;
if (action == null) continue;
var handler = new Action<InputAction.CallbackContext>(ctx =>
var handler = new Action<InputAction.CallbackContext>(context =>
{
if (UiManager.Instance.IsTopPopup(this))
{
OnInputPerformed(binding.ActionName, ctx);
}
if (!_isTopPopup) return;
OnInputPerformed(actionEnum, context);
});
action.Enable();
action.performed += handler;
_registeredHandlers.Add((action, handler));
inputAction.performed += handler;
_registeredHandlers.Add((inputAction, handler));
}
}
@ -67,12 +83,10 @@ public override void Open()
if (UiManager.Instance.IsTopPopup(this))
{
InputManager.Instance.SwitchCurrentActionMap(_uiInputBindingSo.InputActionMaps);
InputManager.Instance.SwitchCurrentActionMap(_baseUiActionsInputBindingSo.InputActionMaps);
}
}
protected virtual void OnInputPerformed(string actionName, InputAction.CallbackContext ctx) { }
public InputActionMaps GetInputActionMaps() => _uiInputBindingSo.InputActionMaps;
protected abstract void OnInputPerformed(T actionEnum, InputAction.CallbackContext ctx);
}
}

View File

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