Unity InputSystem使用

InputSystem 是Unity新推出的输入管理系统。

相比传统的输入系统,InputSystem 支持对设备拔插状态监听和自定义按键映射。

以代码的方式运行

简单使用

以下为获取使用游戏手柄的方式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//获取最后使用的游戏手柄
var gamePad = Gamepad.current;

// print(gamePad.name);

//持续判断按键按下
if (gamePad.dpad.up.isPressed)
{
print("按下 上");
}

//按下一次执行一次
if (gamePad.dpad.up.wasPressedThisFrame)
{
print("按 上");
}

//获取左摇杆的值
move = gamePad.leftStick.ReadValue();

同理可以获取键盘和鼠标的输入:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//获取当前的键盘
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("攻击");
}

获取连接设备

1
2
3
//所有连接的游戏手柄
var all = Gamepad.all;
var allGamepad = InputSystem.devices.Select(x => x is Gamepad);

监听设备改变事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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来指定该动作表可以使用的游戏控制器

image-20220517021443591

使用多个动作表可以分离输入和动作,即使在动作表中存在一致的输入也不会冲突。

Ps:玩家控制时使用PlayerController动作表、控制UI时使用UI动作表

image-20220517015113956

ActionType

其中Value指代各种连续变化的输入,比如鼠标移动,摇杆偏移,手柄扳机等,但这个选项只会获取当前受控制的一个设备输入。

Button则表示按钮输入,无论是鼠标按钮或是手柄按钮,其输入结果为布尔型。

PassThrough和Value基本相同,但它可以获取所有可用输入设备的输入。

image-20220517015834087

ControlType

image-20220517020054781

生成C#类:

image-20220517021932810

全代码控制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
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);
}

image-20220517044539871

在移动设备中使用

在移动设备中,我们希望能处理操作轴和按钮两种输入事件。

在unity官方demo中,提出了相关的解决方案。

在UI中使用

经过测试在Ui中和之前的使用没啥区别,唯一就是要把EventSystem的组件更改一下。

同时之前的Ipoint系列接口也能够正常使用。

image-20220517052201158