整理笔记 2025.6.20
This commit is contained in:
182
1Project/战斗编辑器/参考文章/输入框架/游戏输入框架的设计(基于Unity).md
Normal file
182
1Project/战斗编辑器/参考文章/输入框架/游戏输入框架的设计(基于Unity).md
Normal file
@@ -0,0 +1,182 @@
|
||||
https://zhuanlan.zhihu.com/p/424070778
|
||||
|
||||
### 游戏输入系统设计总结
|
||||
|
||||
#### **核心设计思路**
|
||||
|
||||
1. **输入抽象分层**:
|
||||
|
||||
- **基础输入层**:将输入抽象为按钮(`IButtonInput`)和轴值(`IAxisInput`)两类
|
||||
|
||||
- **复合输入层**:支持多个按键绑定到同一行为(`CompoundButtonInput`/`CompoundAxisInput`)
|
||||
|
||||
- **行为映射层**:将输入状态转化为游戏行为(`InputButtonProcessor`)
|
||||
|
||||
2. **关键接口设计**:
|
||||
|
||||
csharp
|
||||
|
||||
复制
|
||||
|
||||
下载
|
||||
|
||||
// 按钮输入
|
||||
public interface IButtonInput {
|
||||
bool GetButton(); // 获取按钮状态
|
||||
}
|
||||
|
||||
// 轴值输入
|
||||
public interface IAxisInput {
|
||||
float AxisValue(); // 获取轴值(-1~1)
|
||||
}
|
||||
|
||||
|
||||
#### **核心组件实现**
|
||||
|
||||
1. **基础输入实现**:
|
||||
|
||||
- `KeyCodeButtonInput`:封装Unity键值检测
|
||||
|
||||
- `ButtonAxisInput`:将按钮转为轴值(正/负方向)
|
||||
|
||||
2. **复合输入容器**:
|
||||
|
||||
csharp
|
||||
|
||||
复制
|
||||
|
||||
下载
|
||||
|
||||
// 复合按钮(OR逻辑)
|
||||
public class CompoundButtonInput : IButtonInput {
|
||||
public bool GetButton() {
|
||||
foreach(var btn in Buttons)
|
||||
if(btn.GetButton()) return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 复合轴值(取极值叠加)
|
||||
public class CompoundAxisInput : IAxisInput {
|
||||
public float AxisValue() {
|
||||
float max=0, min=0;
|
||||
foreach(var axis in Axis) {
|
||||
float val = axis.AxisValue();
|
||||
if(val<0) min = Mathf.Min(min, val);
|
||||
else max = Mathf.Max(max, val);
|
||||
}
|
||||
return max + min;
|
||||
}
|
||||
}
|
||||
|
||||
3. **行为状态机**:
|
||||
|
||||
csharp
|
||||
|
||||
复制
|
||||
|
||||
下载
|
||||
|
||||
public class InputButtonProcessor {
|
||||
// 状态记录
|
||||
public bool WasPressed; // 上一帧状态
|
||||
public bool IsPressed; // 当前帧状态
|
||||
|
||||
// 状态查询属性
|
||||
public bool OnPressed => IsPressed && !WasPressed; // 刚按下
|
||||
public bool OnReleased => !IsPressed && WasPressed; // 刚释放
|
||||
|
||||
// 状态更新
|
||||
public void Update(bool isPressed) {
|
||||
WasPressed = IsPressed;
|
||||
IsPressed = isPressed;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#### **系统工作流程**
|
||||
|
||||
1. **初始化绑定**(PlayerInput):
|
||||
|
||||
csharp
|
||||
|
||||
复制
|
||||
|
||||
下载
|
||||
|
||||
public void AddKeyboardControls() {
|
||||
// 水平轴:A/D/左右箭头
|
||||
HorizontalDigiPad.Add(new ButtonAxisInput(
|
||||
new KeyCodeButtonInput(KeyCode.A),
|
||||
ButtonAxisInput.Mode.Negative
|
||||
));
|
||||
|
||||
// 跳跃:空格/Z/Y
|
||||
Jump.Add(new KeyCodeButtonInput(KeyCode.Space));
|
||||
}
|
||||
|
||||
2. **状态更新**(每帧):
|
||||
|
||||
csharp
|
||||
|
||||
复制
|
||||
|
||||
下载
|
||||
|
||||
void RefreshControls() {
|
||||
// 1. 更新轴值输入
|
||||
Input.HorizontalValue = HorizontalDigiPad.AxisValue();
|
||||
|
||||
// 2. 更新按钮状态机
|
||||
for(int i=0; i<buttonInputs.Count; i++) {
|
||||
bool pressed = buttonInputs[i].GetButton();
|
||||
buttonProcessors[i].Update(pressed);
|
||||
}
|
||||
}
|
||||
|
||||
3. **游戏逻辑使用**:
|
||||
|
||||
csharp
|
||||
|
||||
复制
|
||||
|
||||
下载
|
||||
|
||||
void Update() {
|
||||
if(Input.Jump.OnPressed) {
|
||||
// 处理跳跃触发
|
||||
}
|
||||
|
||||
if(Input.Right.Pressed) {
|
||||
// 处理持续右移
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#### **设计优势**
|
||||
|
||||
1. **多键位绑定**:一个行为支持多个触发键(如跳跃可用空格/Z/Y)
|
||||
|
||||
2. **输入抽象**:统一处理键盘/鼠标/手柄等输入设备
|
||||
|
||||
3. **状态封装**:提供精细的输入状态检测(按下/持续/释放)
|
||||
|
||||
4. **动态配置**:运行时切换控制方案(`RefreshControlScheme()`)
|
||||
|
||||
5. **行为解耦**:游戏逻辑只依赖抽象行为而非具体按键
|
||||
|
||||
|
||||
#### **扩展建议**
|
||||
|
||||
1. **输入重映射**:添加键位配置保存/加载功能
|
||||
|
||||
2. **输入缓冲**:实现指令缓冲窗口提升操作手感
|
||||
|
||||
3. **设备扩展**:集成手柄输入(`GamepadButtonInput`)
|
||||
|
||||
4. **组合键**:支持Ctrl+Jump等组合键检测
|
||||
|
||||
5. **输入事件**:改用事件驱动减少每帧状态查询
|
||||
|
||||
|
||||
> 该设计通过分层抽象解决了多键位绑定问题,核心价值在于将**物理输入**到**游戏行为**的映射关系标准化,为复杂输入需求提供了可扩展框架。
|
||||
Reference in New Issue
Block a user