UI 系统

This commit is contained in:
2026-06-09 10:41:43 +08:00
parent 247de307c6
commit e09bee31ec
31 changed files with 221439 additions and 997 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -27653,7 +27653,7 @@ BoxCollider:
m_ProvidesContacts: 0
m_Enabled: 1
serializedVersion: 3
m_Size: {x: 26.091469, y: 0, z: 1}
m_Size: {x: 20.912247, y: 0, z: 1}
m_Center: {x: 3.5, y: 3, z: -64}
--- !u!4 &1456787688
Transform:
@@ -215862,7 +215862,7 @@ BoxCollider:
m_ProvidesContacts: 0
m_Enabled: 1
serializedVersion: 3
m_Size: {x: 6.091469, y: 0, z: 1}
m_Size: {x: 0.9122467, y: 0, z: 1}
m_Center: {x: -1, y: 0.5, z: -64}
--- !u!4 &2043137492
Transform:

View File

@@ -124,10 +124,11 @@ namespace BaseGames.Core
// 等一帧:让 Persistent 内所有组件的 Start() 跑完(尤其 InputReaderBootstrap 的 EnableUIInput 兜底)。
yield return null;
// 复刻新游戏初始状态:确保槽 0 存在内存存档,供存档点 / 世界状态等系统使用。
var save = ServiceLocator.GetOrDefault<ISaveService>();
if (save != null && !save.HasSave(0))
save.CreateSlot(0, false);
// 复用正式新游戏会话入口:建档并应用 → ISaveablePlayerStats 等)广播初始数值 →
// 粘性事件频道_replayLastValueToNewSubscribers留存 → 随后激活的 HUD 订阅时回放,血条/灵珠等正确填充。
// 此处玩家已在场景中且已注册 ISaveableCreateSlot 会立即对其应用空档并广播(见 GameSaveManager.CreateSlot
// dev 与正常新游戏走同一 IGameSessionService.BeginNewGame不再手搓建档/广播,杜绝与正式流程分叉。
ServiceLocator.GetOrDefault<IGameSessionService>()?.BeginNewGame(0, DifficultyLevel.Normal);
// 驱动状态机走完整合法链路Initializing → MainMenu → LoadingScene → Gameplay。
// 期间不加载任何场景,仅切换全局状态;末态 Gameplay 使 HUD 显示、暂停可用、输入切到 Gameplay。
@@ -139,23 +140,32 @@ namespace BaseGames.Core
}
/// <summary>
/// 返回当前已加载的、非系统场景(即游玩场景)的名称;没有则返回 null
/// 返回当前“活动场景”的名称——仅当它是游玩场景(非系统场景)时;否则返回 null回退正常启动
/// <para>
/// 用活动场景而非遍历:按 Play 时你在编辑器里打开的那个场景即活动场景Persistent 是 Additive 加载(非活动)。
/// 这样从 MainMenu / Persistent 按 Play 时一定回退正常流程,不会被直连劫持。
/// 仅按场景名约定判断,避免 Core 反向依赖 World 程序集的 RoomController 类型。
/// </para>
/// </summary>
private static string FindOpenGameplaySceneName()
{
for (int i = 0; i < SceneManager.sceneCount; i++)
{
var scene = SceneManager.GetSceneAt(i);
if (!scene.isLoaded) continue;
string n = scene.name;
if (string.IsNullOrEmpty(n)) continue;
if (n == AddressKeys.ScenePersistentName || n == AddressKeys.ScenePersistent) continue;
if (n == AddressKeys.SceneMainMenu) continue;
return n;
}
return null;
var active = SceneManager.GetActiveScene();
if (!active.isLoaded) return null;
string n = active.name;
if (string.IsNullOrEmpty(n) || IsSystemScene(n)) return null;
return n;
}
/// <summary>
/// 是否为启动链路中的系统场景Persistent / MainMenu。从这些场景按 Play 应走正常启动流程,不触发直连。
/// 同时匹配 Unity 场景名(文件名,如 "MainMenu" / "Persistent")与 Addressable key"Scene_MainMenu" 等),
/// 因为两者并不一致(文件 MainMenu.unity → 场景名 "MainMenu"Addressable key 为 "Scene_MainMenu")。
/// </summary>
private static bool IsSystemScene(string n)
=> n == AddressKeys.ScenePersistentName // "Persistent"(场景名)
|| n == AddressKeys.ScenePersistent // "Scene_Persistent"Addressable key
|| n == AddressKeys.SceneMainMenu // "Scene_MainMenu"Addressable key
|| n == "MainMenu"; // 实际场景文件名 MainMenu.unity → 场景名
#endif
private void OnEnable()

View File

@@ -78,6 +78,9 @@ namespace BaseGames.Core
else
Debug.LogWarning("[GameServiceRegistrar] ⚠ _checkpointService 未绑定ICheckpointService 未注册。", this);
// 会话入口服务(无状态,调用时解析依赖;统一新游戏/继续/dev 直连的会话初始化)
ServiceLocator.Register<IGameSessionService>(new GameSessionService());
#if UNITY_EDITOR
var sb = new System.Text.StringBuilder("[GameServiceRegistrar] ✅ 服务注册完成:");
if (_deathRespawnService) sb.Append(" IDeathRespawnService");

View File

@@ -0,0 +1,46 @@
using UnityEngine;
using BaseGames.Core.Events; // DifficultyLevel
namespace BaseGames.Core
{
/// <summary>
/// 游戏会话入口服务:统一"开始一局新游戏"的初始化步骤,供主菜单新游戏、开发直连、调试入口共用,
/// 避免会话初始化逻辑在各入口分叉(历史上 dev 直连曾手搓建档 + 广播,导致与正式流程不一致的 bug
/// </summary>
public interface IGameSessionService
{
/// <summary>
/// 开始一局新游戏会话:
/// <list type="number">
/// <item>建立内存存档槽(<see cref="ISaveService.CreateSlot"/>)——其内部会立即对已注册的
/// ISaveable 应用空档并广播初始数值HP/MaxHP/货币等),配合粘性事件频道使 HUD 正确填充。</item>
/// <item>应用难度档位(<see cref="IDifficultyService.BeginNewGame"/>)。</item>
/// </list>
/// 不负责场景加载与状态机转换——调用方各自决定(正常流程发 SceneLoadRequestdev 直连原地切状态)。
/// </summary>
void BeginNewGame(int slotIndex, DifficultyLevel level);
}
/// <summary>
/// <see cref="IGameSessionService"/> 的默认实现。无状态,经 ServiceLocator 在调用时解析所需服务,
/// 因此不依赖服务注册顺序。由 GameServiceRegistrar 注册。
/// </summary>
public sealed class GameSessionService : IGameSessionService
{
public void BeginNewGame(int slotIndex, DifficultyLevel level)
{
var save = ServiceLocator.GetOrDefault<ISaveService>();
if (save == null)
{
Debug.LogError("[GameSessionService] ISaveService 未注册,无法开始新游戏会话。");
return;
}
// 建档CreateSlot 内部已对已注册 ISaveable 应用空档并广播初始值(见 GameSaveManager.CreateSlot
save.CreateSlot(slotIndex, level == DifficultyLevel.SteelSoul);
// 应用难度(可缺省,难度服务未注册时跳过)。
ServiceLocator.GetOrDefault<IDifficultyService>()?.BeginNewGame(level);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2b80eda21bea91c448dc1fdece4bc89d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -43,6 +43,29 @@ namespace BaseGames.Core.Save
ServiceLocator.Register<ISaveableRegistry>(this);
}
private void Start()
{
// 注册兜底:补登记"早于本注册表初始化就已存在于已加载场景中的 ISaveable"。
// 正常流程下游玩场景晚于 Persistent 加载saveable 在 OnEnable 即可取到 ISaveableRegistry 完成注册;
// 但开发直连(游玩场景作为首场景、与 Persistent 服务同帧初始化)时,这些 saveable 的 OnEnable
// 可能早于本注册表注册 → ServiceLocator.GetOrDefault<ISaveableRegistry>() 取到 null → 漏注册。
// 启动时全量扫描一次兜底确保不漏Register 幂等Add 去重),不会重复登记。
ReconcileSaveablesInLoadedScenes();
}
/// <summary>扫描所有已加载场景中的 ISaveable MonoBehaviour 并补登记(幂等)。仅启动时调用一次。</summary>
private void ReconcileSaveablesInLoadedScenes()
{
var all = FindObjectsOfType<MonoBehaviour>(true);
int added = 0;
foreach (var mb in all)
if (mb is ISaveable s && !_saveables.Contains(s)) { Register(s); added++; }
#if UNITY_EDITOR
if (added > 0)
Debug.Log($"[SaveManager] 启动兜底补登记 {added} 个早注册场景中的 ISaveableinit 时序兜底)。");
#endif
}
/// <summary>
/// 注入存储后端。由 GameServiceRegistrar.Awake 在注册服务后立即调用。
/// 允许在测试环境替换为 InMemoryStorage 等替代实现。
@@ -261,6 +284,13 @@ namespace BaseGames.Core.Save
_current = new SaveData();
_current.Meta.SlotIndex = slotIndex;
_current.Meta.IsSteelSoul = steelSoul;
// 与 LoadAsync 对称:立即对已注册的 ISaveable 应用新档(空档 → 各系统恢复为初始值并广播)。
// 这使"先注册、后建档"(如 dev 直连:玩家已在场景中、再建槽)与"先建档、后注册"(正常新游戏:
// 主菜单建槽、玩家随场景加载后注册由 Register 补发 OnLoad表现一致——
// 初始数值经事件频道广播配合粘性频道_replayLastValueToNewSubscribers让晚激活的 HUD 也能拿到。
var snapshot = _saveables.ToList();
foreach (var s in snapshot) s.OnLoad(_current);
}
public async Task DeleteSlotAsync(int slotIndex)

View File

@@ -30,9 +30,8 @@ namespace BaseGames.Editor.Debugging
return;
}
var save = ServiceLocator.GetOrDefault<ISaveService>();
if (save != null && !save.HasSave(0))
save.CreateSlot(0, false); // 建立内存存档,确保新游戏初始状态
// 统一会话入口建档内部应用空档并广播初始值HUD 正确填充)+ 应用难度。与正式新游戏共用。
ServiceLocator.GetOrDefault<IGameSessionService>()?.BeginNewGame(0, DifficultyLevel.Normal);
// 必须经事件频道 EVT_SceneLoadRequest 发请求SceneService 据此加载场景,
// GameManager 据此驱动状态机 LoadingScene → GameplayHUD/小地图随之显示)。

View File

@@ -29,6 +29,7 @@ namespace BaseGames.Editor.UI
// ── HUDRoot ───────────────────────────────────────────────────────
GameObject hudRootGo = GetOrCreateChild(canvasGo.transform, "HUDRoot").gameObject;
StretchFull(hudRootGo.transform); // 铺满 Canvas使子元件的四角锚定映射到真实屏幕角
HUDController hudCtrl = GetOrAddComponent<HUDController>(hudRootGo);
// 若场景中已存在 UIManager自动将 _hudRoot 指向本 HUDRoot
@@ -72,11 +73,18 @@ namespace BaseGames.Editor.UI
// ── 形态图标Form Icons × 4────────────────────────────────────
const int kFormIconCount = 4;
GameObject formIconsRoot = GetOrCreateChild(hudRootGo.transform, "FormIcons").gameObject;
var formLayout = GetOrAddComponent<HorizontalLayoutGroup>(formIconsRoot);
formLayout.childForceExpandWidth = false;
formLayout.childForceExpandHeight = false;
formLayout.spacing = 6f;
Image[] formImages = new Image[kFormIconCount];
for (int i = 0; i < kFormIconCount; i++)
{
GameObject iconGo = GetOrCreateChild(formIconsRoot.transform, $"FormIcon_{i}").gameObject;
formImages[i] = GetOrAddComponent<Image>(iconGo);
var le = GetOrAddComponent<LayoutElement>(iconGo);
le.preferredWidth = 40f;
le.preferredHeight = 40f;
}
// ── 交互提示InteractPrompt─────────────────────────────────────
@@ -242,6 +250,25 @@ namespace BaseGames.Editor.UI
AssignAsset(toolHUD, "_onToolUsed", report, false, "EVT_ToolUsed");
// ── 布局摆位(点锚定到屏幕四角,避免元件堆叠在中心;尺寸/留白为占位,美术可再精修)──
// 左上角:战斗信息簇(血条 / 魄元 / 灵力 / 灵泉 / 形态 / 灵铢 / 状态效果,自上而下)
SetRect(hpContainerGo.transform, TopLeft, TopLeft, new Vector2(40f, -40f), new Vector2(500f, 50f));
SetRect(soulGaugeGo.transform, TopLeft, TopLeft, new Vector2(40f, -100f), new Vector2(240f, 22f));
SetRect(spiritGaugeGo.transform, TopLeft, TopLeft, new Vector2(40f, -128f), new Vector2(240f, 22f));
SetRect(springContainerGo.transform, TopLeft, TopLeft, new Vector2(40f, -160f), new Vector2(240f, 32f));
SetRect(formIconsRoot.transform, TopLeft, TopLeft, new Vector2(40f, -200f), new Vector2(240f, 44f));
SetRect(lingZhuGo.transform, TopLeft, TopLeft, new Vector2(40f, -252f), new Vector2(200f, 40f));
SetRect(statusHUDGo.transform, TopLeft, TopLeft, new Vector2(40f, -300f), new Vector2(320f, 44f));
// 顶部居中Boss 血条(默认隐藏)
SetRect(bossBarGo.transform, TopCenter, TopCenter, new Vector2(0f, -40f), new Vector2(720f, 60f));
// 右上角:任务追踪
SetRect(questTrackerGo.transform, TopRight, TopRight, new Vector2(-40f, -40f), new Vector2(320f, 220f));
// 右下角:法术槽 + 工具栏
SetRect(spellSlotGo.transform, BottomRight, BottomRight, new Vector2(-40f, 40f), new Vector2(90f, 90f));
SetRect(toolHUDGo.transform, BottomRight, BottomRight, new Vector2(-150f, 40f), new Vector2(180f, 90f));
// 底部居中:交互提示
SetRect(interactPromptGo.transform, BottomCenter, BottomCenter, new Vector2(0f, 140f), new Vector2(320f, 64f));
// ── 手工步骤说明 ──────────────────────────────────────────────────
// _hpCellPrefab / _springIconPrefab 已自动创建并绑定(占位红/青方块,美术可替换)。
report.Add("BossHPBar._phaseMarkerPrefab请将阶段标记点 Prefab 赋给该字段。");
@@ -352,12 +379,47 @@ namespace BaseGames.Editor.UI
Transform child = parent.Find(name);
if (child != null) return child;
GameObject go = new GameObject(name);
// UI 节点必须是 RectTransformnew GameObject 默认创建普通 Transform
// 仅当随后挂上 Graphic/LayoutGroup 时才会被隐式转换——纯逻辑容器FormIcons / SpellSlot 等)
// 会停留为普通 Transform 而无法锚定/定位。显式带 RectTransform 创建,杜绝该缺陷。
GameObject go = new GameObject(name, typeof(RectTransform));
Undo.RegisterCreatedObjectUndo(go, $"Create {name}");
go.transform.SetParent(parent, false);
return go.transform;
}
// ── 锚定 / 布局 ───────────────────────────────────────────────────────
/// <summary>设置 RectTransform 的锚点 / 轴心 / 锚定坐标 / 尺寸(统一布局入口)。</summary>
private static void SetRect(Transform t, Vector2 anchor, Vector2 pivot, Vector2 anchoredPos, Vector2 size)
{
var rt = t as RectTransform;
if (rt == null) return;
rt.anchorMin = anchor;
rt.anchorMax = anchor;
rt.pivot = pivot;
rt.sizeDelta = size;
rt.anchoredPosition = anchoredPos;
}
/// <summary>将 RectTransform 设为全屏拉伸铺满父节点offset 全 0。用于 HUDRoot 等容器根。</summary>
private static void StretchFull(Transform t)
{
var rt = t as RectTransform;
if (rt == null) return;
rt.anchorMin = Vector2.zero;
rt.anchorMax = Vector2.one;
rt.pivot = new Vector2(0.5f, 0.5f);
rt.offsetMin = Vector2.zero;
rt.offsetMax = Vector2.zero;
}
// 常用锚/轴心常量(点锚定,非拉伸)
private static readonly Vector2 TopLeft = new(0f, 1f);
private static readonly Vector2 TopCenter = new(0.5f, 1f);
private static readonly Vector2 TopRight = new(1f, 1f);
private static readonly Vector2 BottomRight = new(1f, 0f);
private static readonly Vector2 BottomCenter= new(0.5f, 0f);
private static T GetOrAddComponent<T>(GameObject go) where T : Component
{
T c = go.GetComponent<T>();

View File

@@ -232,6 +232,8 @@ namespace BaseGames.Input
BindStarted(_ui, "InventoryTabPrev", () => _onInventoryTabPrev?.Raise());
// 快速直达UI Map 同名 ActionHub 已开时按 M 直接跳地图 Tab。共用 Gameplay 同一频道。
BindStarted(_ui, "QuickMap", () => _onQuickMap?.Raise());
// 背包键UI Map 同名 ActionTabHub 已开时按 Tab 关闭(与 Gameplay 同频道UIManager 做 toggle
BindStarted(_ui, "Inventory", () => _onInventoryOpen?.Raise());
}
_isBound = true;

View File

@@ -129,6 +129,12 @@ namespace BaseGames.UI.Inventory
if (_tabs[i].content != null && _tabs[i].content.name == contentName) { SelectTab(i); return; }
}
/// <summary>当前选中 Tab 的内容根名(如 "Content_Map");无有效 Tab 时为 null。供"同键 toggle"判断当前是否已在目标 Tab。</summary>
public string CurrentContentName
=> _tabs != null && _currentIndex >= 0 && _currentIndex < _tabs.Length && _tabs[_currentIndex].content != null
? _tabs[_currentIndex].content.name
: null;
private void SelectTab(int index, bool raise, bool animateEntry)
{
if (_tabs == null || _tabs.Length == 0) return;

View File

@@ -149,9 +149,8 @@ namespace BaseGames.UI.Menus
if (svc.HasSave(slotIndex))
await svc.DeleteSlotAsync(slotIndex);
bool steel = level == DifficultyLevel.SteelSoul;
svc.CreateSlot(slotIndex, steel);
ServiceLocator.GetOrDefault<IDifficultyService>()?.BeginNewGame(level);
// 统一会话入口:建档(内部应用空档并广播初始值)+ 应用难度。与 dev 直连共用,避免分叉。
ServiceLocator.GetOrDefault<IGameSessionService>()?.BeginNewGame(slotIndex, level);
_onSlotConfirmed?.Raise(slotIndex);
}

View File

@@ -161,8 +161,12 @@ namespace BaseGames.UI
}
// ── 状态响应 ──────────────────────────────────────────────────────────
/// <summary>最近一次的游戏状态。用于背包/地图同键 toggle 时判断"是否在游戏内",避免在主菜单等 UI 上下文误开 Hub。</summary>
private GameStateId _currentState;
private void HandleGameStateChanged(GameStateId state)
{
_currentState = state;
bool showHud = state == GameStates.Gameplay || state == GameStates.BossFight;
if (_hudRoot != null) _hudRoot.SetActive(showHud);
@@ -284,19 +288,20 @@ namespace BaseGames.UI
private void OpenCharmPanel() => OpenPanel(PanelId.CharmPanel);
private void OpenSpellSelect() => OpenPanel(PanelId.SpellSelect);
/// <summary>背包键 toggle若统一背包屏正位于栈顶则关闭否则打开同键开/关。</summary>
/// <summary>背包键 toggle若统一背包屏正位于栈顶则关闭否则(仅游戏内)打开同键开/关。</summary>
private void OpenInventory()
{
if (_panelRegistry.TryGetValue(PanelId.Inventory, out var inv)
&& Navigator?.Top != null && Navigator.Top.gameObject == inv)
Navigator.Pop();
else
OpenPanel(PanelId.Inventory);
if (!_panelRegistry.TryGetValue(PanelId.Inventory, out var inv) || inv == null) return;
if (HubIsTop(inv)) { Navigator.Pop(); return; } // 已开 → 关闭
if (!InGameplay) return; // 仅游戏内允许打开(避免主菜单等误开)
OpenPanel(PanelId.Inventory);
}
/// <summary>
/// 快速直达:确保统一背包屏打开,并定位到指定内容根名对应的 Tab如 "Content_Map")。
/// 已打开则只切 Tab不关闭未打开则打开后切。按名定位与 Tab 顺序解耦
/// 快速直达:定位到指定内容根名对应的 Tab如 "Content_Map")。同键 toggle
/// 已在该 Tab → 关闭 Hub在其他 Tab → 切到该 Tab未打开 → (仅游戏内)打开并切到该 Tab
/// 按名定位,与 Tab 顺序解耦。
/// </summary>
private void OpenInventoryAt(string contentName)
{
@@ -305,11 +310,29 @@ namespace BaseGames.UI
Debug.LogWarning("[UIManager] 统一背包屏PanelId.Inventory未注册快速直达失败。", this);
return;
}
bool hubTop = Navigator?.Top != null && Navigator.Top.gameObject == inv;
if (!hubTop) OpenPanel(PanelId.Inventory); // 激活时 OnEnable 同步运行
inv.GetComponent<Inventory.InventoryHubPanel>()?.SelectTabByContentName(contentName);
var hub = inv.GetComponent<Inventory.InventoryHubPanel>();
if (HubIsTop(inv))
{
// 已显示目标 Tab → 同键关闭;否则切到目标 Tab不关闭
if (hub != null && hub.CurrentContentName == contentName) { Navigator.Pop(); return; }
hub?.SelectTabByContentName(contentName);
return;
}
if (!InGameplay) return; // 仅游戏内允许打开
OpenPanel(PanelId.Inventory); // 激活时 OnEnable 同步运行
hub?.SelectTabByContentName(contentName);
}
/// <summary>统一背包屏当前是否位于导航栈顶(即正在显示)。</summary>
private bool HubIsTop(GameObject inv)
=> Navigator?.Top != null && Navigator.Top.gameObject == inv;
/// <summary>当前是否处于游戏内Gameplay / BossFight——决定是否允许用快捷键打开 Hub。</summary>
private bool InGameplay
=> _currentState == GameStates.Gameplay || _currentState == GameStates.BossFight;
// ── 编辑器工具 ────────────────────────────────────────────────────────
[ContextMenu("验证面板注册表")]
private void EditorValidateRegistry()

View File

@@ -768,6 +768,15 @@ public partial class @PlayerInputActions: IInputActionCollection2, IDisposable
""processors"": """",
""interactions"": """",
""initialStateCheck"": false
},
{
""name"": ""Inventory"",
""type"": ""Button"",
""id"": ""a1b2c3d4-e5f6-0001-0002-000000000201"",
""expectedControlType"": """",
""processors"": """",
""interactions"": """",
""initialStateCheck"": false
}
],
""bindings"": [
@@ -1298,6 +1307,28 @@ public partial class @PlayerInputActions: IInputActionCollection2, IDisposable
""action"": ""QuickMap"",
""isComposite"": false,
""isPartOfComposite"": false
},
{
""name"": """",
""id"": ""a1b2c3d4-e5f6-0001-0002-000000000202"",
""path"": ""<Keyboard>/tab"",
""interactions"": """",
""processors"": """",
""groups"": ""Keyboard&Mouse"",
""action"": ""Inventory"",
""isComposite"": false,
""isPartOfComposite"": false
},
{
""name"": """",
""id"": ""a1b2c3d4-e5f6-0001-0002-000000000203"",
""path"": ""<Gamepad>/select"",
""interactions"": """",
""processors"": """",
""groups"": ""Gamepad"",
""action"": ""Inventory"",
""isComposite"": false,
""isPartOfComposite"": false
}
]
}
@@ -1370,6 +1401,7 @@ public partial class @PlayerInputActions: IInputActionCollection2, IDisposable
m_UI_InventoryTabNext = m_UI.FindAction("InventoryTabNext", throwIfNotFound: true);
m_UI_InventoryTabPrev = m_UI.FindAction("InventoryTabPrev", throwIfNotFound: true);
m_UI_QuickMap = m_UI.FindAction("QuickMap", throwIfNotFound: true);
m_UI_Inventory = m_UI.FindAction("Inventory", throwIfNotFound: true);
}
~@PlayerInputActions()
@@ -1760,6 +1792,7 @@ public partial class @PlayerInputActions: IInputActionCollection2, IDisposable
private readonly InputAction m_UI_InventoryTabNext;
private readonly InputAction m_UI_InventoryTabPrev;
private readonly InputAction m_UI_QuickMap;
private readonly InputAction m_UI_Inventory;
/// <summary>
/// Provides access to input actions defined in input action map "UI".
/// </summary>
@@ -1832,6 +1865,10 @@ public partial class @PlayerInputActions: IInputActionCollection2, IDisposable
/// </summary>
public InputAction @QuickMap => m_Wrapper.m_UI_QuickMap;
/// <summary>
/// Provides access to the underlying input action "UI/Inventory".
/// </summary>
public InputAction @Inventory => m_Wrapper.m_UI_Inventory;
/// <summary>
/// Provides access to the underlying input action map instance.
/// </summary>
public InputActionMap Get() { return m_Wrapper.m_UI; }
@@ -1902,6 +1939,9 @@ public partial class @PlayerInputActions: IInputActionCollection2, IDisposable
@QuickMap.started += instance.OnQuickMap;
@QuickMap.performed += instance.OnQuickMap;
@QuickMap.canceled += instance.OnQuickMap;
@Inventory.started += instance.OnInventory;
@Inventory.performed += instance.OnInventory;
@Inventory.canceled += instance.OnInventory;
}
/// <summary>
@@ -1958,6 +1998,9 @@ public partial class @PlayerInputActions: IInputActionCollection2, IDisposable
@QuickMap.started -= instance.OnQuickMap;
@QuickMap.performed -= instance.OnQuickMap;
@QuickMap.canceled -= instance.OnQuickMap;
@Inventory.started -= instance.OnInventory;
@Inventory.performed -= instance.OnInventory;
@Inventory.canceled -= instance.OnInventory;
}
/// <summary>
@@ -2270,5 +2313,12 @@ public partial class @PlayerInputActions: IInputActionCollection2, IDisposable
/// <seealso cref="UnityEngine.InputSystem.InputAction.performed" />
/// <seealso cref="UnityEngine.InputSystem.InputAction.canceled" />
void OnQuickMap(InputAction.CallbackContext context);
/// <summary>
/// Method invoked when associated input action "Inventory" is either <see cref="UnityEngine.InputSystem.InputAction.started" />, <see cref="UnityEngine.InputSystem.InputAction.performed" /> or <see cref="UnityEngine.InputSystem.InputAction.canceled" />.
/// </summary>
/// <seealso cref="UnityEngine.InputSystem.InputAction.started" />
/// <seealso cref="UnityEngine.InputSystem.InputAction.performed" />
/// <seealso cref="UnityEngine.InputSystem.InputAction.canceled" />
void OnInventory(InputAction.CallbackContext context);
}
}

View File

@@ -682,6 +682,15 @@
"processors": "",
"interactions": "",
"initialStateCheck": false
},
{
"name": "Inventory",
"type": "Button",
"id": "a1b2c3d4-e5f6-0001-0002-000000000201",
"expectedControlType": "",
"processors": "",
"interactions": "",
"initialStateCheck": false
}
],
"bindings": [
@@ -1212,6 +1221,28 @@
"action": "QuickMap",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "a1b2c3d4-e5f6-0001-0002-000000000202",
"path": "<Keyboard>/tab",
"interactions": "",
"processors": "",
"groups": "Keyboard&Mouse",
"action": "Inventory",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "a1b2c3d4-e5f6-0001-0002-000000000203",
"path": "<Gamepad>/select",
"interactions": "",
"processors": "",
"groups": "Gamepad",
"action": "Inventory",
"isComposite": false,
"isPartOfComposite": false
}
]
}