4.5 KiB
InputModule 常见问题
编译错误
CS0117: 'GameEntry' does not contain a definition for 'InputModule'
原因: 基座项目的 GameEntry.Custom.cs 中没有添加 InputModule 静态属性。
解决:
- 在
GameEntry.Custom.cs中添加:public static InputModuleComponent InputModule { get; private set; } - 在
InitCustomComponents()中赋值:InputModule = UnityGameFramework.Runtime.GameEntry.GetComponent<InputModuleComponent>();
如果项目决定不接入 InputModule,请确保场景中没有挂载
VirtualJoystickBridge/VirtualButtonBridge(或删除Presentation/目录)。这两个 bridge 会自动查找场景中的InputModuleComponent,但不再硬编码依赖GameEntry.InputModule。
The type or namespace name 'InputModuleComponent' could not be found
原因: 使用了 InputModuleComponent 的代码所在程序集没有引用 SepCore.Runtime 或 SepCore.InputModule.Base。
解决: 检查相关 .asmdef 的 references 中是否包含 SepCore.Runtime(因为 InputModuleComponent 通过 asmref 编译进 SepCore.Runtime)。
SepCore.Presentation 编译失败,找不到 InputCommand 等类型
原因: SepCore.Presentation.asmdef 没有引用 SepCore.InputModule.Base。
解决: 在 SepCore.Presentation.asmdef 的 references 中添加 GUID:d54b9488b03814a44ab937f0aeb738b1(即 SepCore.InputModule.Base)。
运行时问题
Play 后输入没有反应
检查清单:
Launcher场景中是否挂载了InputModuleComponent- 启动 Procedure 中是否调用了
GameEntry.InputModule?.OnInit() - 当前上下文是否正确设置(默认初始化后为
None,需要SetContext或SetGameplayExploreContext) - 是否有 listener 注册到了正确的
InputActionId
UI 打开后 Gameplay 输入没有禁用
原因: 没有使用 PushContext(InputContextId.Dialog) 或 SetContext(InputContextId.UI)。
解决:
- 对于覆盖层弹窗(从 Gameplay 打开 Dialog):使用
PushContext(InputContextId.Dialog),关闭时PopContext() - 对于大场景切换(Menu -> Main):使用
SetContext(InputContextId.GameplayExplore)
重绑后绑定没有保存
原因: InputModuleComponent 的 _saveBindingOverridesOnDestroy 为 false,且没有手动调用 SaveBindingOverrides()。
解决:
- 在 Inspector 中勾选
_saveBindingOverridesOnDestroy - 或在重绑成功后手动调用
GameEntry.InputModule.SaveBindingOverrides()
重绑时报冲突
原因: 新绑定的按键与 Global map 或同一 map 内的其他 action 冲突。
解决: 当前设计不允许同设备冲突绑定。如果确实需要共享按键(例如同一按钮在不同上下文下做不同的事),应通过上下文切换来隔离,而不是把两个 action 绑定到同一个按键上。
设备与提示
手柄插入后 UI 提示没有刷新
原因: 没有监听 DeviceKindChanged 事件。
解决:
GameEntry.InputModule.DeviceKindChanged += OnDeviceChanged;
private void OnDeviceChanged(InputDeviceKind kind)
{
// 刷新所有按键提示
}
触摸虚拟摇杆后设备类型没有变为 Touch
原因: VirtualJoystickBridge 的 _injectDeviceKind 为 false。
解决: 在 Inspector 中勾选 _injectDeviceKind。
设计约束
能否在业务代码里直接判断 CurrentDeviceKind == Gamepad?
不推荐。 业务层应消费 InputCommand 的语义值,设备判断留给 UI/Presentation 层。如果确实需要,建议通过 DeviceKindChanged 事件在 UI 层做适配,而不是分散在 gameplay 逻辑中。
为什么 UI 点击不经过 InputModule?
这是 P2 的设计决策:UI 原始输入(点击、拖拽、导航)继续由 Unity EventSystem 处理。InputModule 只负责 gameplay 语义输入和上下文切换。这样避免了双重分发和跨平台复杂度。
能否把 InputModule 完全独立成一个不依赖 UGF 的模块?
当前版本有 3 个地方依赖 UGF:
InputModuleComponent继承自GameFrameworkComponent- 绑定覆盖持久化使用
SettingComponent GameEntry接入约定
如果要完全剥离 UGF,需要:
- 把
InputModuleComponent改为普通MonoBehaviour - 自己实现设置持久化接口
- 去掉
GameEntry相关的接入模板
这不是当前 P6 的目标,但架构上 Base 层本身已经零依赖 UGF。