docs: rebuild Input API content

This commit is contained in:
2026-03-26 17:39:53 +08:00
parent ec4edb2689
commit ce2eee32e3
54 changed files with 1108 additions and 941 deletions

View File

@@ -0,0 +1,115 @@
# Input Flow And Frame Semantics
## 这套输入系统怎么理解
当前 XCEngine 输入系统更接近“轻量级、同步、帧驱动的输入管理器”,而不是完整设备抽象框架。
它有两个核心层:
- `InputModule` 负责接平台消息。
- `InputManager` 负责保存状态并提供事件与查询接口。
这意味着真正的输入流向是:
1. 平台窗口系统产生命令或消息。
2. 平台后端把消息翻译成 `ProcessKeyDown``ProcessMouseMove` 一类调用。
3. `InputManager` 更新状态并同步广播事件。
4. 游戏或工具层在当前帧读取轮询状态。
5. `Update()` 在帧边界清理瞬时状态。
## 为什么同时保留事件和轮询
事件和轮询各有适合的地方:
- UI、输入法、编辑器面板更适合订阅事件。
- 游戏逻辑、相机控制、角色移动更适合每帧轮询。
`InputManager` 同时提供这两种方式,是为了避免你在上层自己重复维护一套输入缓存。
## 帧边界怎么理解
当前实现里,`Update()` 不是“采集输入”,而是“结束上一帧的瞬时状态”。
它会清理:
- `IsKeyPressed` 依赖的本帧按下标记
- `IsMouseButtonClicked` 依赖的本帧点击标记
- `GetMouseDelta`
- `GetMouseScrollDelta`
所以最重要的实践是:
- 每帧只调用一次 `Update()`
- 保持调用时机一致。
- 在清理之前,先消费掉当前帧的瞬时输入。
## 和 Unity 的对照
从使用方式上看,`InputManager` 很像 Unity 旧版 Input Manager
- 有具名轴:`Horizontal``Vertical`
- 有具名按钮:`Jump``Fire1``Fire2``Fire3`
- 查询接口偏向 `GetAxis` / `GetButton`
但当前实现并不等同于 Unity
- 没有平滑、重力、灵敏度、死区等高级参数。
- `GetAxisRaw` 当前只在“按下这一帧”返回非零,不等同于 Unity 中“原始持续值”的语义。
- `Mouse X``Mouse Y` 默认虽然被注册了,但当前实现并不会通过鼠标移动更新它们。
## 平台桥接是怎么接进来的
`InputModule` 的意义是把平台消息层隔离掉。当前 Windows 路径里:
- `WindowsInputModule::HandleMessage` 负责处理 `WM_KEYDOWN``WM_MOUSEMOVE``WM_MOUSEWHEEL` 等消息。
- 它再调用 `InputManager::Process*` 统一更新状态。
这样做的好处是:
- 游戏层不用知道 Win32 消息细节。
- 将来如果换 GLFW、SDL 或其它平台层,`InputManager` 可以不变。
## 当前版本最该知道的限制
- `KeyCode` 底层值当前有重复,部分键会共享状态槽。
- Windows 路径当前不能准确区分左右 Ctrl / Alt / Shift。
- 触摸与摇杆接口基本是预留位。
- 事件回调是同步执行的,不是异步消息队列。
- `Shutdown()` 当前不会清空事件监听器;如果单例跨生命周期反复初始化,要自己管理订阅者。
## 推荐使用方式
初始化阶段:
```cpp
using namespace XCEngine::Input;
InputManager::Get().Initialize(windowHandle);
```
平台消息阶段:
```cpp
windowsInputModule.HandleMessage(hwnd, msg, wParam, lParam);
```
游戏逻辑阶段:
```cpp
if (InputManager::Get().GetButton("Jump")) {
// ...
}
```
帧边界阶段:
```cpp
InputManager::Get().Update(deltaTime);
```
## 相关 API
- [Input](../../XCEngine/Input/Input.md)
- [InputManager](../../XCEngine/Input/InputManager/InputManager.md)
- [InputModule](../../XCEngine/Input/InputModule/InputModule.md)
- [InputTypes](../../XCEngine/Input/InputTypes/InputTypes.md)