Unity新版InputSystem短按与长按,改键的实现
目录
前言:
新版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)!