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

embedded/2025/1/18 17:16:08/

目录

前言:

一、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);elsekeyName = 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_EDITORDebug.Log("成功绑定按键:" + inputBindling + ": from " + binding.path + " to " + binding.overridePath);
#endifif (!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");}}
}

 


http://www.ppmy.cn/embedded/155000.html

相关文章

【golang学习之旅】使用VScode安装配置Go开发环境

1. 下载并安装Go 1.1 下载地址1.2 选择版本并下载1.3 安装目录1.4 验证是否安装成功 2. 配置环境变量 2.1 配置步骤2.2 GO部分环境变量说明 3. 下载或更新 Vscode 3.1 下载地址3.2 安装步骤 4. 为Go开发配置VScode 1. 下载并安装Go 1.1 下载地址 https://studygolang.com/dl…

Ubuntu、Windows系统网络设置(ping通内外网)

一、 虚拟机VMware和Ubuntu系统的网络配置说明 1、虚拟机的网络适配器的模式有三种&#xff1a; 桥接模式NAT模式主机模式 2、虚拟机VMware的网卡配置(如何进行配置界面(虚拟机->设置)) 注意&#xff1a; 1、以上桥接模式(ubuntu有独立IP)、NAT模式(没有独立IP)都可以联…

pnpm介绍

pnpm 是一个快速、节省磁盘空间的 JavaScript 包管理工具&#xff0c;它与 npm 和 yarn 类似&#xff0c;但具有一些独特的优势。以下是 pnpm 的一些特点&#xff1a; 1. 高效的磁盘空间管理 pnpm 使用一种去重机制来存储依赖包。它将所有项目共享的依赖包保存在全局存储区&a…

OpenAI Whisper:语音识别技术的革新者—深入架构与参数

当下语音识别技术正以前所未有的速度发展&#xff0c;极大地推动了人机交互的便利性和效率。OpenAI的Whisper系统无疑是这一领域的佼佼者&#xff0c;它凭借其卓越的性能、广泛的适用性和创新的技术架构&#xff0c;正在重新定义语音转文本技术的规则。今天我们一起了解一下Whi…

基于单片机的智能火灾报警系统设计

【文章摘要】火灾报警器是当前社会经济生产生活中较为常用的火灾预警装置,对国民经济及人员生命财产安全起到了重要的保障作用。随着现代科学技术快速发展,智能控制芯片的应用使得火灾报警器反应灵敏度大幅提升,对早期火情发现与控制起到了重要的推动作用。为此,本文以 AT8…

linux nginx 安装后,发现SSL模块未安装,如何处理?

&#x1f468;‍⚕ 主页&#xff1a; gis分享者 &#x1f468;‍⚕ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕ 收录于专栏&#xff1a;运维工程师 文章目录 前言SSL模块安装 前言 nginx 安装后&#xff0c;发现SSL模块未安装&…

蓝桥杯刷题第二天——背包问题

题目描述 有N件物品和一个容量是V的背包。每件物品只能使用一次。第i件物品的体积是Vi价值是Wi。 求解将哪些物品装入背包&#xff0c;可使这些物品的总体积不超过背包容量&#xff0c;且总价值最大。 输出最大价值。 输入格式 第一行两个整数&#xff0c;N&#xff0c;V&am…

effective-Objective-C 第二章阅读笔记

对象&#xff0c;消息&#xff0c;运行期 文章目录 对象&#xff0c;消息&#xff0c;运行期前言理解“属性”这一概念属性修饰符原子性nonatimicatomic 读/写权限内存管理语义方法名 自定义初始化方法小结 在对象内部尽量直接访问实例变量小结 对象等同性特定类的isEqual执行深…