Unity 学习使用InputSystem接收键盘的输入
快速实践
配置InputAction
右键点击工程(project)面板空白处,弹出菜单栏,选择Create项,进入二次菜单,选择底下的Input Actions。
将其命名为InputSystemAsset
。双击打开。
创建一个新的Action Maps和Action,将action命名为Move,修改Action Type
为Value
,Control Type
为Vector2
然后点击Move右边的加号,选择第二Add Up\Down\Left\Right Composite
。
最后分别修改绑定路径为WASD。
创建场景
创建一个新的scene,添加Plane和Sphere,对Sphere添加Rigidbody.
编写代码
点击之前创建的InputSystemAsset
,在Inspector面板勾选Generate C# Class
。Project面板里会多出一个InputSystemAsset.cs
文件。
创建C#文件PlayerController.cs
,将其挂载到Sphere上,按下WASD小球可以移动。
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using static InputSystemAsset;
using static UnityEngine.InputSystem.InputAction;
public class PlayerController : MonoBehaviour
{
private InputSystemAsset _inputSystemAsset;
public Vector2 Move;
private new Rigidbody rigidbody;
public float Speed = 5;
public void OnEnable()
{
rigidbody = GetComponent<Rigidbody>();
if(_inputSystemAsset == null)
{
_inputSystemAsset = new InputSystemAsset();
_inputSystemAsset.Player.SetCallbacks(new PlayerActionCallback(this));
_inputSystemAsset.Enable();
}
}
public void OnDisable()
{
_inputSystemAsset.Disable();
}
// Update is called once per frame
void FixedUpdate()
{
rigidbody.velocity = new Vector3(Move.y,0,Move.x)*Speed;
}
}
public class PlayerActionCallback : IPlayerActions
{
public PlayerController playerController;
public PlayerActionCallback(PlayerController playerController)
{
this.playerController = playerController;
}
public void OnMove(CallbackContext context)
{
playerController.Move = context.ReadValue<Vector2>();
Debug.Log($"phase {context.phase } val {playerController.Move}");
}
}
理论学习
Input Actions are designed to separate the logical meaning of an input from the physical means of input (that is, activity on an input device) that generate the input.
Action
Input Action被设计成用于分离输入的逻辑意义和物理输入方式。你的代码只需要关心这个输入是跳跃还是射击,而不需要关心这个输入来自键盘还是手柄。
新的输入系统有三个关键的类:InputActionAsset,InputActionMap,InputAction。
InputAction
就是逻辑行为,代表它是跳跃,还是移动还是射击。比如我们上面创建的资产中的Move。这个逻辑行为可以和多个设备进行绑定。
InputActionMap
是一组InputAction
的集合.
InputActionAsset
是一组InputActionMap
的集合。
观察刚刚生成的InputSystemAsset.cs
可以看到有InputActionAsset
类型的成员变量,并且在构造函数中使用了FromJson
函数生成这个asset。构造结束后,从这个asset中找到Player这个ActionMap以及其中的Move这个action.
private readonly InputActionMap m_Player;
private IPlayerActions m_PlayerActionsCallbackInterface;
private readonly InputAction m_Player_Move;
public @InputSystemAsset()
{
asset = InputActionAsset.FromJson(@"{...}");
// Player
m_Player = asset.FindActionMap("Player", throwIfNotFound: true);
m_Player_Move = m_Player.FindAction("Move", throwIfNotFound: true);
}
Input Action Type
IntputActionType
影响InputAction
的行为表现,InputActionType
可能是PassThrough
,Value
,Button
。
- 其中,最直白容易理解的类型是
PassThrough
。每次输入值发生变化都会触发这个action。 并且passthrough action不会使用Started和Canceled事件。但这种类型的action不会区分输入的来源。 Value Action
当输入从默认值偏移的时候就会触发started
事件,并且在那之后立刻触发performed
事件,并且每次输入发生变化的时候都会触发performed
事件,但有个例外,那就是值变回初始值,会触发canceled
而不是performed
。Button Action
表现的和Value Action
差不多,除了它不执行初始状态检查。
这些Action Type区分输入来源的行为也有些不同,具体可以参考Unity文档