当前位置:   article > 正文

untiy 新输入系统 InputSytem_input system 核心思想

input system 核心思想

一 前言

新输入系统的名字就叫InputSystem,新是相对于旧的InputManager来说的

核心思想是添加一个动作(action)的概念,代码只监听动作的触发,由动作去绑定物理输入,这样无论什么平台,无论如何重新指定物理输入,我们都不需要修改代码
同时也可以将同一个物理输入同时绑定到不同的输入动作集中,随时切换输入动作集,例如上车后,从走路的动作集切换到开车的动作集。

此外还提供了一些方便的功能,例如使用代码重新绑定按键、屏幕按键等、检测设备接入拔出、组合键、次要绑定等。

二 安装

InputSystem不是默认安装的,我们需要使用packagemanager来安装他。
建议使用2019之后的版本
打开packageManager,在unityRegistery里搜索,然后安装即可,安装过程中你的编辑器会需要重启一次。
如果你打开包管理器不显示包,那么你需要退出编辑器,刷新一下通行证,重新打开即可。
在这里插入图片描述

新建一个输入资产

有两种方法可以创建输入
1 通过Project面板右键菜单Create/InputAction创建一个新的输入资产,这将创建一个全新的资产。
2 为一个物体添加一个PlayerInput组件,点击create按钮,这会创建一个带有默认输入的资产。
在这里插入图片描述
创建新的输入资产的时候必须小心的命名,不要随便起个名字,因为之后创建的带有输入动作的c#脚本会叫这个名字,瞎起名字是给自己找麻烦

三 InputActions面板

这个面板的作用是管理一个InputActionAssets的action和对应的映射。
双击一个输入资产即可打开这个面板。
在这里插入图片描述
以下是详细解释

区域1 工具栏

controlSchemes 控制方案

在这里插入图片描述
默认是只有AllControlSchemes的,可以使用AddControlScheme创建新的输入方案,随后可以为action的一个物理输入指定自己的输入方法,当我们切换输入方案时,就可过滤这个方案下的action了,注意方案只是一个名字,没有任何实际意义,你完全可以起一个名字叫gamepad的方案,但是为keyboard action指定这个方案。

删除控制方案时,如果由物理输入会让我们选择是否要连同绑定的物理输入一同删除,选yes会删除所有指定为当前方案的物理输入绑定,选no只会删除这个控制方案,而保留绑定的物理输入
在这里插入图片描述

saveAsset和Auto-Save

不建议使用Auto-Save,因为我们需要为aciton创建一个c#文件才能在脚本中调用,使用了Auto-Save时,如果我们已经创建了这个脚本,每当我们做出改变,都会重新编译脚本,这将非常痛苦

区域2 actionMaps 动作映射集

我们可以在这里定义不同的映射集,走路动作映射集、开车动作映射集、UI动作集等
点击+号即可创建新的动作集

区域3 actions 区域4 属性面板

这两个要一起看
actions: 一个actionMaps里的所有action,用于创建action并为action绑定物理按键
Properties: action或binding的属性

1 action与bingding的创建与删除

点击atcions的加号即可创建一个新的action(绿色),新action默认自带一个绑定(蓝色),只不过目前这个绑定还没有绑定任何物理按键
在这里插入图片描述
右键action即可删除action
点击action后的+号并选择一个绑定类型即可创建一个新的bingding(蓝色)
右键bindging即可选择删除

2 action的属性

Action 这是action属性栏里第一个属性
创建好aciton后,我们第一步要确定action的类型,选中一个action(绿色),右侧属性面板会显示这个action的选项
有value和button和Pass Through三种类型

  • value:可以将输入转化为值,可以在ControlType属性中选择具体的类型,通常使用Axis(一维)、Vector2、Vector3,通常用来制作移动、视角旋转、读取摇杆输入值等。
  • button:按下触发,没什么好说的
  • Pass Through: 例如你插了多个手柄,那么所有的手柄都会同时影响这个action,上面两种方式是只有当前有输入传入的手柄会影响这个action,除非你希望你的action同时被多个物理设备控制,否则不要使用这个选项

注意修改了aciton的类型后,会影响action可以创建的物理输入的选项
在这里插入图片描述
Interactions 如何交互
可以指定这个action如何交互
点击+号添加一个新的交互方式
常用的交互有Hold按住一段时间后触发,MultiTop,多次点击等,见名知意,不多废话。
如果什么都不加,则为默认的交互方式。
Processors 定义如何处理获取到的值
可选项有

  • Axis Deadzone:轴死区 当摇杆输入小于Min,不会触发摇杆,通常用于防止摇杆漂移问题。如果输入大于Max,认为都是1。在Min和Max之间插值
  • Clamp:钳制输入的值,不能小于Min,不能大于Max
  • Invert: 翻转输入的值,例如输入的值为1,则实际得到的值为-1
  • Normalize: 归一化值,你总能得到1 0 -1,通常用于摇杆
  • Scale:缩放输入的值
3 Bindin属性

创建绑定的注意事项
点击一个action后的+号,然后选择一个具体类型,即可创建一个绑定
根据action的类型不同,可以选择的binding类型是不同的
当action的ActionType为Button时,我们可以创建的类型有

  • Binding:普通按钮,只能绑定一个按键
  • Positive/Negative:,需要分别为Positive和Negative绑定两个按键
  • Binding With Modifier: 组合键

当action为Value类型时,我们可以创建的类型通常有Binding和Up/Down/Left/Right,显然这是用来用键盘控制方向的
在这里插入图片描述
这里绑定类型过多,无法全部列举,但我们最常用的就是Button和键盘摇杆的轴输入
绑定一个物理输入
新创建的binding是没有按键绑定的,需要我们手动绑定。
选中一个binding,点击他的属性栏里的Binding分类,然后点击Path/Listen,然后按下按键或移动摇杆,再从监听到的列表里点选我们需要的输入即可
在这里插入图片描述在这里插入图片描述
例如我按下了space键,我就在列表里选择space键,注意你可以按下多个按键。

对于摇杆,例如你坚挺了XBOX的摇杆,你可选择这个动作是仅用于Xbox还是通用的,如果是通用的,使用其他品牌的摇杆按下对应的键同样可以起作用,否则只会相应Xbox摇杆,如下图,第一选项是通用输入,第二选项是仅相应Xbox摇杆。
在这里插入图片描述
为绑定选择一个ControlSchemes
如果我们之前建立了一个控制方案,我们可以为这个Binding指定属于的控制方案,这方便我们过滤。
如何新建控制方案可以参考本章“区域一”部分。
Interactions和Processors
和action相同,只不过banding的这两个选项会覆盖action的。

4 实例演示,创建一个跳跃action

请添加图片描述

四 C#调用InputsSystem

这里介绍三中监听输入的方式,但是只有第三种是重要的,前两种知道就行。

方法1 传统高耦合方式调用

虽然inputSystem提供了acion这个概念,但我们同样可以直接去访问键盘按键
首先引入nameSpace

using UnityEngine.InputSystem;
  • 1
//键盘
if (Keyboard.current.aKey.wasPressedThisFrame)
{
     print("A键按下");
}
//鼠标输入
print(Mouse.current.delta.ReadValue());
//鼠标按下
if(Mouse.current.leftButton.wasPressedThisFrame)
{

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

这种用法最好只用来做测试,不要真的用它做项目,因为他还没InputManager好用,至少InputManagerAPI更好找。

方法2 使用PlayerInput组件

为一个物体挂载一个PlayerInput组件,然后选择一个InputAcionsAssets。
在这里插入图片描述
使用DefaultMap选择一个acitonMaps。
使用Behavior来选择一个消息传递方式,这里推荐用第3,4个,以下分别介绍这两种模式
InokeUnityEvnets:
这个模式的优点在于可以直接拖拽事件
在这里插入图片描述
切换到Behavior的第三个模式后,会出现Events选项,其中Player和UI是我创建的两个actionMaps,其中Jump和 Movement是Player这个acionMaps里的两个action,我们需要如何只需像给UIButton绑定事件一样,为action拖拽事件即可。
我们可以这样声明事件:

//有参
 public void Jump(InputAction.CallbackContext context)
    {
        //Debug.Log(context);
        //context.performed||context.started||context.canceled 按下 开始按 松开
        if (context.performed)//只在按下时触发
        {
            rig.AddForce(Vector3.up * 5f, ForceMode.Impulse);
        }
    }
    //无参
    public void Jump()
    {
        rig.AddForce(Vector3.up * 5f, ForceMode.Impulse);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

需要注意的是,一个按钮被按下时,会触发3次事件,因为一个按钮包含三个阶段,开始按/按下/松开,所以我们最好用带参的方法绑定事件,并自行在方法中判断阶段

Inoke CSharp Evnets
在这里插入图片描述
这种方式需要我们在脚本里查找inputManager组件,并绑定委托,类似于用脚本为UIButton绑定事件

 private Rigidbody rig;
    private PlayerInput playerInput;
    private void Start()
    {
        playerInput = GetComponent<PlayerInput>();
        //查找组件的方式切换输入控制集
        playerInput.SwitchCurrentActionMap("Player");
        playerInput.onActionTriggered += PlayerInput_onActionTriggered;
    }
    private void PlayerInput_onActionTriggered(InputAction.CallbackContext obj)//使用InvokeCSharpEvents模式监听事件
    {
        Debug.Log(obj);
    }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

方法3 创建C#脚本

这是唯一推荐使用的方式
首先我们要生成c#文件
找到InputActionAssets,勾选生成C#类,即可自动生成c#类,此时最好关闭InputAcionts面板的Auto-Save选项,否则每次我调整输入,都会立刻重新生成这个类
在这里插入图片描述

生成的c#类名字和InputAcionsAssets名字相同,这就是为什么不要乱起名字。

在代码中监听action按键输入,获取value类型的值
目前的输入资产
在这里插入图片描述

编写脚本

 	PlayerInputActions playerInputActions;
    private void Start()
    {
        playerInputActions = new PlayerInputActions();注意是new 一个对象,不是查找组件
        playerInputActions.Player.Enable();//激活一个控制集 注意必须要激活一个acitonMaps
        playerInputActions.Player.Jump.performed += Jump;//绑定事件
        playerInputActions.Player.Movement.performed += Movement_performed;//按一下动一下,做移动输入应该按下方FixedUpdate里的方式,这里只是演示如何做值类型的输入监听
    }
    private void FixedUpdate()
    {
    	//直接监听value类型的action的输入
        Vector2 inputVector = playerInputActions.Player.Movement.ReadValue<Vector2>();
     	Debug.Log(inputVector);
    }

	//注册跳跃的方法
    public void Jump(InputAction.CallbackContext context)
    {
        Debug.Log(context);
    }
    //注册移动的方法
    public void Movement_performed(InputAction.CallbackContext context) 
    {
        Vector2 inputVector = context.ReadValue<Vector2>();//读取value类型的action,注意泛型要用和输入匹配的类型
        float speed = 5f;
        rig.AddForce(new Vector3(inputVector.x, 0, inputVector.y) * speed, ForceMode.Force);
    }


  • 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

非常简单

切换输入控制集

        playerInputActions = new PlayerInputActions();
        //C#方式切换输入控制集
        playerInputActions.UI.Disable();//禁用一个actionMaps
        playerInputActions.Player.Enable();//启用一个actionMaps
  • 1
  • 2
  • 3
  • 4

重新绑定按键 恢复默认按键

为action重新指定按键
//重新绑定按键,重新绑定按键前,需要确保已经关闭了所有的输入动作集,否则一旦开启监听,就会立刻绑定当前输入的值,这里边肯定有我们不想要的值,例如鼠标位置,滑移的摇杆等
            playerInputActions.Player.Disable();
            playerInputActions.UI.Disable();
            playerInputActions.Player.Jump.PerformInteractiveRebinding(0)//参数0 修改首要绑定 1 修改次要绑定 默认为0
                .WithCancelingThrough(Keyboard.current.escapeKey)//指定一个按键用于取消重新绑定
                .OnCancel(callBack =>
                {
                    print("取消绑定");
                    callBack.Dispose();//取消绑定要释放资源
                    playerInputActions.Player.Enable();//重新激活输入动作
                })
                .WithControlsExcluding("Mouse")//禁止绑定鼠标按键 参数的值可以从绑定界面看一下都有什么输入分类
                .OnComplete(callback =>
                {
                    Debug.Log("结束绑定");
                    callback.Dispose();//完成重新绑定后需要释放对象
                    playerInputActions.Player.Enable();//重新激活输入动作
                })
                .Start();//开始监听重新绑定的按键
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
保存并加载修改后的按键绑定

如果我们不手动保存重新绑定的按键,那么下次启动时,还是会使用最开始的按键
我们手动保存了按键后,每次启动,都需要读取,并且重新赋值给inputsystem
在绑定的OnComplete()里添加保存

.OnComplete(callback =>
                {
                    Debug.Log("结束绑定");
                    Debug.Log(callback);
                    
                    //inputSystem1.1版本以后的保存重新绑定方式
                    string rebinds = callback.action.SaveBindingOverridesAsJson();
                    PlayerPrefs.SetString("rebinds", rebinds);//静态方法,参数1 固定字符串,表示重新绑定
                    print("重新绑定的内容" + rebinds);

                    callback.Dispose();//完成重新绑定后需要释放对象
                    playerInputActions.Player.Enable();//重新激活输入动作
                })
``
在游戏启动时读取上次保存的重新绑定json

```csharp
        playerInputActions = new PlayerInputActions();
        //C#方式切换输入控制集
        playerInputActions.Player.Enable();
        string rebinds = PlayerPrefs.GetString("rebinds");
        playerInputActions.LoadBindingOverridesFromJson(rebinds);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
恢复默认按键
playerInputActions.Player.Jump.RemoveBindingOverride();
  • 1

获取action和名字和action绑定的按键

        playerInputActions = new PlayerInputActions();
        playerInputActions.Player.Enable();

        print(playerInputActions.Player.Jump.name);//action的名字
        print(playerInputActions.Player.Jump.GetBindingDisplayString(1));//列出次要绑定  参数为0是首要绑定
        print(playerInputActions.Player.Jump.GetBindingDisplayString());//列出action的首要和次要绑定
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号