Files
zeling_v2/Assets/_Game/Scripts/Input/InputReaderBootstrap.cs
2026-06-05 18:41:33 +08:00

70 lines
3.1 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using UnityEngine;
using BaseGames.Core.Events;
namespace BaseGames.Input
{
/// <summary>
/// 运行时初始化 InputReaderSO并让输入 ActionMap 跟随游戏状态切换。
/// 挂在 Persistent 场景的 InputReaderHolder 上。
///
/// 输入模式由游戏状态驱动(通过 EVT_GameStateChanged 频道订阅,避免 Core→Input 程序集循环):
/// · Gameplay / BossFight → 启用 Gameplay 输入
/// · 其余状态MainMenu / Paused / Dead / Cutscene / LoadingScene / Initializing 等)→ 启用 UI 输入
///
/// 这样主菜单等 UI 场景下 UI ActionMap 才会被启用,保证 EventSystemInputSystemUIInputModule
/// 能接收鼠标点击 / 手柄导航。Dialogue / Cutscene 等 Gameplay 内子流程的临时切换由各自管理器处理,
/// 不经过此处(其状态仍为 Gameplay本组件不干预
///
/// _inputReader 与 _onGameStateChanged 必须在 Inspector 中赋值,框架不提供运行时自动查找回退。
/// </summary>
public sealed class InputReaderBootstrap : MonoBehaviour
{
[SerializeField] private InputReaderSO _inputReader;
[Header("状态驱动输入切换")]
[Tooltip("游戏状态变化频道EVT_GameStateChanged。据此在 Gameplay 输入与 UI 输入间切换。")]
[SerializeField] private GameStateEventChannelSO _onGameStateChanged;
private readonly CompositeDisposable _subs = new();
private void Awake()
{
Debug.Assert(_inputReader != null,
"[InputReaderBootstrap] _inputReader 未在 Inspector 中赋值!请在 Persistent 场景的 InputReaderHolder 上手动指定 InputReaderSO 资产。",
this);
Debug.Assert(_onGameStateChanged != null,
"[InputReaderBootstrap] _onGameStateChanged 未赋值,请在 Inspector 中指定 EVT_GameStateChanged否则输入模式无法跟随游戏状态切换。",
this);
}
private void OnEnable()
{
_onGameStateChanged?.Subscribe(HandleGameStateChanged).AddTo(_subs);
}
private void Start()
{
if (_inputReader == null) return;
_inputReader.LoadBindingOverrides(); // 从 PlayerPrefs 恢复用户自定义绑定
// 启动初始状态为 Initializing → MainMenu使用 UI 输入作为兜底;
// 之后由 HandleGameStateChanged 跟随游戏状态切换(不再硬编码 EnableGameplayInput
_inputReader.EnableUIInput();
}
private void HandleGameStateChanged(GameStateId state)
{
if (_inputReader == null) return;
// Gameplay / BossFight 使用游戏输入;其余状态(菜单 / 暂停 / 死亡 / 过场 / 加载)使用 UI 输入。
bool gameplay = state.Id == "Gameplay" || state.Id == "BossFight";
if (gameplay) _inputReader.EnableGameplayInput();
else _inputReader.EnableUIInput();
}
private void OnDisable()
{
_subs.Clear();
_inputReader?.DisableAllInput();
}
}
}