Unity 学习使用InputSystem接收键盘的输入

快速实践

配置InputAction

右键点击工程(project)面板空白处,弹出菜单栏,选择Create项,进入二次菜单,选择底下的Input Actions。
将其命名为InputSystemAsset。双击打开。

创建一个新的Action Maps和Action,将action命名为Move,修改Action TypeValueControl TypeVector2
image

然后点击Move右边的加号,选择第二Add Up\Down\Left\Right Composite
image

最后分别修改绑定路径为WASD。
image

创建场景

创建一个新的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可能是PassThroughValueButton

  1. 其中,最直白容易理解的类型是PassThrough。每次输入值发生变化都会触发这个action。 并且passthrough action不会使用Started和Canceled事件。但这种类型的action不会区分输入的来源。
  2. Value Action当输入从默认值偏移的时候就会触发started事件,并且在那之后立刻触发performed事件,并且每次输入发生变化的时候都会触发performed事件,但有个例外,那就是值变回初始值,会触发canceled而不是performed
  3. Button Action表现的和Value Action差不多,除了它不执行初始状态检查。

这些Action Type区分输入来源的行为也有些不同,具体可以参考Unity文档

InputBinding

posted @ 2023-03-16 23:02  dewxin  阅读(810)  评论(0编辑  收藏  举报