Initial Unity project commit
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
using UnityEngine;
|
||||
#if ENABLE_INPUT_SYSTEM
|
||||
using UnityEngine.InputSystem;
|
||||
#endif
|
||||
|
||||
namespace UI.PanelStack
|
||||
{
|
||||
public class PlayerInputActionRouter : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private bool debugLogs = true;
|
||||
[SerializeField] private string pauseActionName = "Pause";
|
||||
[SerializeField] private string cancelActionName = "Cancel";
|
||||
|
||||
#if ENABLE_INPUT_SYSTEM
|
||||
private PlayerInput playerInput;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
TryBind();
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
Unbind();
|
||||
}
|
||||
|
||||
private void TryBind()
|
||||
{
|
||||
playerInput = FindPrimaryPlayerInput();
|
||||
if (playerInput == null)
|
||||
{
|
||||
if (debugLogs) Debug.Log("[PlayerInputActionRouter] No PlayerInput found; input routing disabled.");
|
||||
return;
|
||||
}
|
||||
|
||||
playerInput.onActionTriggered += OnActionTriggered;
|
||||
|
||||
if (debugLogs)
|
||||
{
|
||||
string map = playerInput.currentActionMap != null ? playerInput.currentActionMap.name : "(null)";
|
||||
bool hasPause = playerInput.actions != null && playerInput.actions.FindAction(pauseActionName, false) != null;
|
||||
bool hasCancel = playerInput.actions != null && playerInput.actions.FindAction(cancelActionName, false) != null;
|
||||
Debug.Log($"[PlayerInputActionRouter] Bound. currentMap={map}, hasPause={hasPause}, hasCancel={hasCancel}");
|
||||
}
|
||||
}
|
||||
|
||||
private static PlayerInput FindPrimaryPlayerInput()
|
||||
{
|
||||
Player.PlayerController playerController = FindObjectOfType<Player.PlayerController>(true);
|
||||
if (playerController != null)
|
||||
{
|
||||
PlayerInput playerInput = playerController.GetComponentInChildren<PlayerInput>(true);
|
||||
if (playerInput != null) { return playerInput; }
|
||||
}
|
||||
|
||||
return FindObjectOfType<PlayerInput>(true);
|
||||
}
|
||||
|
||||
private void Unbind()
|
||||
{
|
||||
if (playerInput != null)
|
||||
{
|
||||
playerInput.onActionTriggered -= OnActionTriggered;
|
||||
}
|
||||
playerInput = null;
|
||||
}
|
||||
|
||||
private void OnActionTriggered(InputAction.CallbackContext ctx)
|
||||
{
|
||||
if (ctx.action == null) { return; }
|
||||
if (ctx.performed == false) { return; }
|
||||
if (UIPanelStack.Instance == null) { return; }
|
||||
|
||||
string actionName = ctx.action.name;
|
||||
if (actionName == cancelActionName)
|
||||
{
|
||||
bool closed = UIPanelStack.Instance.CloseTop();
|
||||
if (debugLogs) Debug.Log($"[PlayerInputActionRouter] {cancelActionName} performed. closedTop={closed}");
|
||||
return;
|
||||
}
|
||||
|
||||
if (actionName == pauseActionName)
|
||||
{
|
||||
if (UIPanelStack.Instance.IsAnyOpen())
|
||||
{
|
||||
if (debugLogs) Debug.Log($"[PlayerInputActionRouter] {pauseActionName} performed but stack not empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
bool opened = UIPanelStack.Instance.TryOpenOnEscapeWhenEmpty();
|
||||
if (debugLogs) Debug.Log($"[PlayerInputActionRouter] {pauseActionName} performed. openedMenu={opened}");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dbb84ff6c82d9df468c6cc9c439f9f95
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,25 @@
|
||||
using UI.PanelStack;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UI.PanelStack
|
||||
{
|
||||
public class UIActionMapRouter : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private bool debugLogs = true;
|
||||
|
||||
public void OnUICancel()
|
||||
{
|
||||
if (UIPanelStack.Instance == null) { return; }
|
||||
bool closed = UIPanelStack.Instance.CloseTop();
|
||||
if (debugLogs) Debug.Log($"[UIActionMapRouter] UI/Cancel triggered. closedTop={closed}");
|
||||
}
|
||||
|
||||
public void OnUIPause()
|
||||
{
|
||||
if (UIPanelStack.Instance == null) { return; }
|
||||
if (UIPanelStack.Instance.IsAnyOpen()) { return; }
|
||||
bool opened = UIPanelStack.Instance.TryOpenOnEscapeWhenEmpty();
|
||||
if (debugLogs) Debug.Log($"[UIActionMapRouter] UI/Pause triggered. openedMenu={opened}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f71ed2608c4634c41821d378c37ae68f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace UI.PanelStack
|
||||
{
|
||||
public enum UIPanelKind
|
||||
{
|
||||
Settings = 0,
|
||||
Modal = 1,
|
||||
Pause = 2,
|
||||
Custom = 100
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1c207c3d0faf77841a5b735083d1d4b0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,130 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UI.PanelStack
|
||||
{
|
||||
public class UIPanelStack : MonoBehaviour
|
||||
{
|
||||
public static UIPanelStack Instance { get; private set; }
|
||||
|
||||
private readonly List<Entry> stack = new List<Entry>();
|
||||
private Func<bool> escapeOpenHandler;
|
||||
[SerializeField] private bool debugLogs = true;
|
||||
|
||||
private sealed class Entry
|
||||
{
|
||||
public UIPanelKind kind;
|
||||
public GameObject root;
|
||||
public Action closeAction;
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (Instance == null)
|
||||
{
|
||||
Instance = this;
|
||||
DontDestroyOnLoad(gameObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
Destroy(gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
public void Push(UIPanelKind kind, GameObject root, Action closeAction)
|
||||
{
|
||||
if (root == null) { return; }
|
||||
|
||||
Remove(root);
|
||||
|
||||
stack.Add(new Entry
|
||||
{
|
||||
kind = kind,
|
||||
root = root,
|
||||
closeAction = closeAction
|
||||
});
|
||||
if (debugLogs) Debug.Log($"[UIPanelStack] Push kind={kind} root={root.name} count={stack.Count}");
|
||||
}
|
||||
|
||||
public bool Remove(GameObject root)
|
||||
{
|
||||
if (root == null) { return false; }
|
||||
|
||||
for (int i = stack.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (stack[i].root == root)
|
||||
{
|
||||
stack.RemoveAt(i);
|
||||
if (debugLogs) Debug.Log($"[UIPanelStack] Remove root={root.name} count={stack.Count}");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool CloseTop()
|
||||
{
|
||||
CleanupInactive();
|
||||
|
||||
if (stack.Count == 0) { return false; }
|
||||
|
||||
Entry top = stack[stack.Count - 1];
|
||||
stack.RemoveAt(stack.Count - 1);
|
||||
|
||||
if (top.root == null) { return false; }
|
||||
|
||||
if (top.closeAction != null)
|
||||
{
|
||||
if (debugLogs) Debug.Log($"[UIPanelStack] CloseTop via action kind={top.kind} root={top.root.name} remain={stack.Count}");
|
||||
top.closeAction.Invoke();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (debugLogs) Debug.Log($"[UIPanelStack] CloseTop via SetActive(false) kind={top.kind} root={top.root.name} remain={stack.Count}");
|
||||
top.root.SetActive(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void SetEscapeOpenHandler(Func<bool> handler)
|
||||
{
|
||||
escapeOpenHandler = handler;
|
||||
if (debugLogs) Debug.Log($"[UIPanelStack] SetEscapeOpenHandler set={(handler!=null)}");
|
||||
}
|
||||
|
||||
public void ClearEscapeOpenHandler(Func<bool> handler)
|
||||
{
|
||||
if (handler == null) { return; }
|
||||
if (escapeOpenHandler == handler)
|
||||
{
|
||||
escapeOpenHandler = null;
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryOpenOnEscapeWhenEmpty()
|
||||
{
|
||||
if (escapeOpenHandler == null) { return false; }
|
||||
bool result = escapeOpenHandler.Invoke();
|
||||
if (debugLogs) Debug.Log($"[UIPanelStack] TryOpenOnEscapeWhenEmpty result={result}");
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool IsAnyOpen()
|
||||
{
|
||||
CleanupInactive();
|
||||
return stack.Count > 0;
|
||||
}
|
||||
|
||||
private void CleanupInactive()
|
||||
{
|
||||
for (int i = stack.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (stack[i].root == null || !stack[i].root.activeInHierarchy)
|
||||
{
|
||||
stack.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 35ee98817252d334e8278aafbe75db00
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,35 @@
|
||||
using UnityEngine;
|
||||
#if ENABLE_INPUT_SYSTEM
|
||||
using UnityEngine.InputSystem;
|
||||
#endif
|
||||
|
||||
namespace UI.PanelStack
|
||||
{
|
||||
public class UIPanelStackInput : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private bool enabledInput = true;
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!enabledInput) { return; }
|
||||
if (UIPanelStack.Instance == null) { return; }
|
||||
|
||||
if (IsEscapePressed())
|
||||
{
|
||||
if (!UIPanelStack.Instance.CloseTop())
|
||||
{
|
||||
UIPanelStack.Instance.TryOpenOnEscapeWhenEmpty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsEscapePressed()
|
||||
{
|
||||
#if ENABLE_INPUT_SYSTEM
|
||||
return Keyboard.current != null && Keyboard.current.escapeKey.wasPressedThisFrame;
|
||||
#else
|
||||
return Input.GetKeyDown(KeyCode.Escape);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cf4367c679ee66743bd76b7243797601
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user