using UnityEngine; using BaseGames.Input; namespace BaseGames.UI { /// /// 挂在"游戏内全屏菜单"根节点(如 InventoryHubRoot)上: /// 打开(OnEnable)时冻结游戏(Time.timeScale=0)并切到 UI 输入;关闭(OnDisable)时恢复时间并切回 Gameplay 输入。 /// /// 解决的 bug:游戏内菜单(统一背包屏)打开时本不改 GameState,导致 Gameplay 输入仍激活、 /// 按 Esc 触发的是"暂停"而非"关闭菜单",且关闭后状态错乱使 Esc 不再暂停。 /// 切到 UI 输入后:菜单内 Esc=关闭(UINavigator Cancel),关闭后 Esc=暂停(Gameplay)。 /// 同时冻结时间符合"打开背包暂停游戏"的常规手感。 /// /// 仅作用于本菜单的开/关;与暂停菜单(PausedState)的真实暂停相互独立、互不冲突。 /// [DisallowMultipleComponent] public class MenuPauseScope : MonoBehaviour { [SerializeField] private InputReaderSO _inputReader; [Tooltip("打开时是否冻结游戏时间(Time.timeScale=0)。菜单动画须用 unscaledDeltaTime。")] [SerializeField] private bool _freezeTime = true; private float _prevTimeScale = 1f; private void OnEnable() { if (_freezeTime) { _prevTimeScale = Time.timeScale; Time.timeScale = 0f; } _inputReader?.EnableUIInput(); } private void OnDisable() { if (_freezeTime) Time.timeScale = _prevTimeScale; // 恢复打开前的时间倍率(若打开前已是 0 则维持暂停,正确) _inputReader?.EnableGameplayInput(); } } }