InputSystem 是 Unity 新推出的输入管理系统。
相比传统的输入系统,
InputSystem
支持对设备拔插状态监听和自定义按键映射。
# 以代码的方式运行
# 简单使用
以下为获取使用游戏手柄的方式。
// 获取最后使用的游戏手柄 | |
var gamePad = Gamepad.current; | |
// print(gamePad.name); | |
// 持续判断按键按下 | |
if (gamePad.dpad.up.isPressed) | |
{ | |
print("按下 上"); | |
} | |
// 按下一次执行一次 | |
if (gamePad.dpad.up.wasPressedThisFrame) | |
{ | |
print("按 上"); | |
} | |
// 获取左摇杆的值 | |
move = gamePad.leftStick.ReadValue(); |
同理可以获取键盘和鼠标的输入:
// 获取当前的键盘 | |
var keyboard = Keyboard.current; | |
print("键盘:" + keyboard.name); | |
if (keyboard.kKey.wasPressedThisFrame) | |
{ | |
print("按下K"); | |
} | |
// 获取当前的鼠标 | |
var mouse = Mouse.current; | |
if (mouse.leftButton.wasPressedThisFrame) | |
{ | |
print("点击鼠标左键"); | |
} | |
// 兼容多个输入 | |
if (gamepad.aButton.wasPressedThisFrame || keyboard.jKey.wasPressedThisFrame) | |
{ | |
print("攻击"); | |
} |
# 获取连接设备
// 所有连接的游戏手柄 | |
var all = Gamepad.all; | |
var allGamepad = InputSystem.devices.Select(x => x is Gamepad); |
# 监听设备改变事件
InputSystem.onDeviceChange += (a, change) => | |
{ | |
switch (change) | |
{ | |
case InputDeviceChange.Added: | |
print("新设备加入" + a.name); | |
break; | |
case InputDeviceChange.Disconnected: | |
print(a.name + "设备断开"); | |
break; | |
case InputDeviceChange.Reconnected: | |
print("重新连接"); | |
break; | |
} | |
}; |
# InputActionAsset 映射
通过输入信号指定 -> 输入行为
可以通过不同的输入信号 比如鼠标左右键 键盘 WASD 键 而这些输入信号又可以来自于不同的输入设备 比如鼠标 键盘 通过 InputSystem 各种输入设备可以无缝切换。
也就是说 输入设备绑定了各种输入信号 而输入信号触发了输入动作
# ActionMaps (动作表)
动作表表示一套输入动作,可以同时拥有多个动作表,并切换使用
注:指定动作表的 Scheme
来指定该动作表可以使用的游戏控制器
使用多个动作表可以分离输入和动作,即使在动作表中存在一致的输入也不会冲突。
Ps:玩家控制时使用 PlayerController 动作表、控制 UI 时使用 UI 动作表
# ActionType
其中 Value 指代各种连续变化的输入,比如鼠标移动,摇杆偏移,手柄扳机等,但这个选项只会获取当前受控制的一个设备输入。
Button 则表示按钮输入,无论是鼠标按钮或是手柄按钮,其输入结果为布尔型。
PassThrough 和 Value 基本相同,但它可以获取所有可用输入设备的输入。
# ControlType
生成 C# 类:
using UnityEngine; | |
public class GameInput : MonoBehaviour | |
{ | |
private PlayerControls playerControls; | |
private Rigidbody rigidbody; | |
private void OnEnable() | |
{ | |
playerControls?.Enable(); | |
} | |
private void OnDisable() | |
{ | |
playerControls?.Disable(); | |
playerControls?.Dispose(); | |
} | |
private void Awake() | |
{ | |
playerControls = new PlayerControls(); | |
rigidbody = GetComponent<Rigidbody>(); | |
} | |
private Vector2 moveDir; | |
private void Start() | |
{ | |
playerControls.PlayerMap.Jump.performed += (x) => | |
{ | |
print("跃动"); | |
rigidbody.AddForce(Vector3.up * 200); | |
}; | |
playerControls.PlayerMap.Attack1.performed += (x) => { print("攻击"); }; | |
playerControls.PlayerMap.Dpd.performed += (x) => { print("按下上键"); }; | |
playerControls.PlayerMap.Start.performed += x => { print("按下start"); }; | |
playerControls.PlayerMap.Select.performed += x => { print("按下Select"); }; | |
playerControls.PlayerMap.L.performed += x => { print("按下L"); }; | |
playerControls.PlayerMap.LShouder.performed += x => { print("按下左肩键"); }; | |
playerControls.PlayerMap.Spell.performed += x => { print("连按触发"); }; | |
playerControls.PlayerMap.Spell2.performed += x => { print("触发组合键"); }; | |
} | |
private void Update() | |
{ | |
moveDir = playerControls.PlayerMap.Move.ReadValue<Vector2>() * Time.deltaTime * 5; | |
transform.Translate(moveDir.x, 0, moveDir.y); | |
} |
# 在移动设备中使用
在移动设备中,我们希望能处理操作轴和按钮两种输入事件。
在 unity 官方 demo 中,提出了相关的解决方案。
# 在 UI 中使用
经过测试在 Ui 中和之前的使用没啥区别,唯一就是要把 EventSystem 的组件更改一下。
同时之前的 Ipoint 系列接口也能够正常使用。