自学内容网 自学内容网

Unity新版InputSystem短按与长按,改键的实现

目录

前言:

一、InputSystem简介

1.安装InputSystem包

2.创建配置文件

3.创建自定义的Actions

二、自定义输入类

三、改键

四、全代码


前言:

新版inputsystem是Unity推出的一种新的输入方式,它将设备与行为进行分离,通过配置文件,更利于用户直接进行按键修改与配置。

一、InputSystem简介

这一部分主要是对InputSystem的简单介绍,我会通过代码形式来进行按键逻辑的编写,因为代码更加灵活。当然,如果是不复杂的项目,使用InputSystem内置的组件进行配置也是ok的,但这里就不会去介绍这一部分的操作了。就简单放张图吧

1.安装InputSystem包

首先到PackageManager里去安装包,然后会有提示框,进行重启就行。

到Edit=ProjectSetting里的Player中设置输入,当然可以使用Both,我这里用的是InputSystemPackage,Both就是会包括旧版的InputManager,既然是讲InputSystem的,我就只用它了。

2.创建配置文件

鼠标右键Create-InputAction,就会创建一个配置文件,给它重命名都行。

在InputAction文件中,可以生成C#类,它的路径,类命,命名空间都可以自定义,因为要使用脚本来处理短按长按逻辑,所以需要勾上生成C#类。

3.配置InputAction

点击InputAction文件中的Editasset按钮,就会进入下面的设置界面

其中

ActionMaps显示当前定义的 Action Maps 的列表。每个操作映射都是一组操作,您可以作为一个组一起启用或禁用这些操作。
Actions显示在当前选定的 Action Map 中定义的所有操作,以及与每个 Action 关联的绑定。
ActionProperties显示 Actions 面板中当前选定的 Action 或 Binding 的属性。此面板的标题会根据您在 Actions 面板中选择的是 Action 还是 Binding而发生变化。

有些不好理解是吧,实际呢,ActionMaps就像是一张表,这张表里有我们需要的一些操作,而且每个操作都有其对应的属性,这些属性可以是一个按钮,一个值。

3.创建自定义的Actions

稍微解释一下,这里呢我创建了一个名为Game的ActionMap,其中有一个叫做Tap的Action,它的行为类型是按钮。

Value提供一种连续状态变化事件,如果设置了多个输入,就会切换到最主要的一个。用它进行模拟控制,比如移动。
Button默认设置,包括按钮或者按键触发的一次性动作
Pass Through和Value很相似,但它不会像Value一样(如果有多个输入时,不会只选择最主要的那个,而把其他的输入忽略)

在使用Value或者Pass Through Types时,你会看到一个额外的选项 Control Type为该Value的返回值类型

在Interactions一栏添加了一个Hold类型(长按类型)

Hold按下并按住至少设定的持续时间(默认为defaultHoldTime),则执行动作。(长按执行操作)
 MultiTap需要多次轻击(在tapTime内按下并释放),每次轻击之间的间隔不超过tapDelay秒(双击或多击)
Press根据按钮的按下和释放顺序来触发特定的操作(例如:在按下按钮后执行某个动作或在释放按钮时执行某个操作)
SlowTap按下并按住控件一段时间后释放时执行操作(长按释放后执行操作)
Tap按下并按住小段时间内释放执行操作(点击)

而添加的绑定则是1DAxis,即如果输入的是负,则返回-1,输入的正则返回1,不输入则无,这样的绑定可以处理两个按键的逻辑。

当点击键盘A的时候返回-1,当点击键盘D的时候返回1。

配置好后,就可以保存文件,Unity会开始生成C#类。

二、自定义输入类

inputControls就是生成的C#类,而Input则会是我们自定义得输入类。

短按很好处理,就只要在用户点击按钮的那一刻判断为点击就可

而长按则需要用户进入到特定的时间点才能触发,而且它的逻辑也需要单独处理。

在按键检测过程中若是进入了长按交互,就开始进行判断是否是对应的按键。

编写测试脚本来测试一下

测试结果:

 

三、改键

InputSystem在配置输入时可以看到有绑定按键的操作,我们改键的操作就是通过代码来修改这个路径。点击旁边的T可以看到路径是什么。

打开生成的C#类可以在开头看到一段Json格式的代码,我们可以将其保存为Json文件,这样就可以做成持久的改键设置。思路是如此,这里我就不做操作了,下面实现的将是直接修改按键的代码。

先上代码

原理很简单,就是通过输入的按键,获取其路径,然后将绑定的path修改为新的改键路径。

ApplyBindingOverride函数中的index就是层级顺序,下面标注出来顺序

写个测试脚本:

测试结果如下:

四、全代码

using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Interactions;

public enum InputBindlingEnum
{
    Left,
    Right
}

public class Input
{
    private InputControls actions;

    public bool tap_left { get { return actions.Game.Tap.WasPressedThisFrame() && actions.Game.Tap.ReadValue<float>() == -1; } }
    public bool tap_right { get { return actions.Game.Tap.WasPressedThisFrame() && actions.Game.Tap.ReadValue<float>() == 1; } }
    public bool hold_left { get; private set; }
    public bool hold_right { get; private set; }

    public Input()
    {
        actions = new InputControls();
        actions.Game.Tap.started += ctx =>
        {
            hold_left = false;
            hold_right = false;
        };
        actions.Game.Tap.performed += ctx =>
        {
            if (ctx.interaction is HoldInteraction)
            {
                hold_left = actions.Game.Tap.ReadValue<float>() == -1;
                hold_right = actions.Game.Tap.ReadValue<float>() == 1;
            }
        };
        actions.Game.Tap.canceled += ctx =>
        {
            hold_left = false;
            hold_right = false;
        };
        actions.Game.Enable();
    }

    public void ChangeBinding(InputBindlingEnum inputBindling, KeyCode key)
    {
        if (actions == null)
            return;
        if (actions.Game.enabled)
            actions.Game.Disable();

        InputBinding binding = new InputBinding();
        switch (inputBindling)
        {
            case InputBindlingEnum.Left:
                binding = actions.Game.Tap.bindings[1];
                break;
            case InputBindlingEnum.Right:
                binding = actions.Game.Tap.bindings[2];
                break;
        }

        string keyName = System.Enum.GetName(typeof(KeyCode), key);
        if (keyName.Contains("Alpha"))
            keyName = keyName.Substring(5);
        else if (keyName.Contains("Keypad"))
            keyName = keyName.Substring(6);
        else if (keyName.Length > 1)
            keyName = keyName.Substring(0, 1).ToLower() + keyName.Substring(1);
        else
            keyName = keyName.ToLower();

        binding.overridePath = $"<Keyboard>/{keyName}";

        switch (inputBindling)
        {
            case InputBindlingEnum.Left:
                actions.Game.Tap.ApplyBindingOverride(1, binding);
                break;
            case InputBindlingEnum.Right:
                actions.Game.Tap.ApplyBindingOverride(2, binding);
                break;
        }

#if UNITY_EDITOR
        Debug.Log("成功绑定按键:" + inputBindling + ": from " + binding.path + " to " + binding.overridePath);
#endif

        if (!actions.Game.enabled)
            actions.Game.Enable();
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test : MonoBehaviour
{
    private Input input;
    private void Awake()
    {
        if (input == null)
            input = new Input();
        input.ChangeBinding(InputBindlingEnum.Left, KeyCode.LeftArrow);
    }

    private void Update()
    {
        if (input.tap_left)
        {
            Debug.Log("tap_left");
        }
        if (input.tap_right)
        {
            Debug.Log("tap_right");
        }
        if (input.hold_left)
        {
            Debug.Log("hold_left");
        }
        if (input.hold_right)
        {
            Debug.Log("hold_right");
        }


    }
}

 


原文地址:https://blog.csdn.net/m0_68267247/article/details/145211599

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!