Unity New Input System

news2024/11/15 18:07:11

安装

Input System是新的输入系统,用来取代旧的Input Manager,方便接收不同的输入设备
在这里插入图片描述
在Package Manager里安装
在这里插入图片描述
安装后可以选择只使用新的Input System,或选Both两者都使用,考虑很多插件还在使用旧的Input Manager,推荐选择Both

映射

右键 -> Create -> Input Actions,就可以创建一个名为xxx.inputactions的资源,它管理输入事件和输入设备之间的映射关系
在这里插入图片描述
主要有两种方式来接受用户的输入,一种是在角色身上挂Player Input脚本,通过事件来触发逻辑
在这里插入图片描述
另一种是勾选Generate C# Class,生成对应类的脚本,通过类对象来添加逻辑,这种方式可以更好的解耦,推荐使用这种方式
在这里插入图片描述
点击Edit asset编辑映射关系,左边的Action Maps(动作表)定义了一系列InputAction(输入事件)集合,每个集合可以看作是一套输入方案,开发中可能需要设计不同的输入方案,它们的映射关系不同,例如这里定义两个输入方案Gamepad1和Gamepad2,可以根据使用场景激活其中一个输入方案

public class SimpleInput : MonoBehaviour
{
    public enum InputPlan
    {
        Gamepad1,
        Gamepad2,
    }
    
    private GameInput _gameInput;
    private InputPlan _inputPlan;
    
    public void Awake()
    {
        _gameInput = new GameInput();
    }

    public void OnEnable()
    {
        _gameInput.Enable();
        switch (_inputPlan)
        {
            case InputPlan.Gamepad1:
                _gameInput.Gamepad1.Enable();
                _gameInput.Gamepad2.Disable();
                break;
            case InputPlan.Gamepad2:
                _gameInput.Gamepad1.Disable();
                _gameInput.Gamepad2.Enable();
                break;
        }
    }

    public void OnDisable()
    {
        _gameInput.Disable();
    }
}

GameInput 是通过asset文件生成的类,这里使用枚举来切换当前使用的输入方案,注意_gameInput.Enable() 会把所有的Action Maps都激活,所以需要根据当前使用的方案单独激活对应的Action Map

在这里插入图片描述
中间的Actions定义InputAction(输入事件),右边的Action Properties定义相关属性,一个InputAction可以绑定多个设备,这里Move这个InputAction绑定了键盘的WASD键,上下左右方向键和左摇杆,两个设备的输入都会触发Move这个输入事件

在这里插入图片描述
点击加号绑定设备

类型描述
Add Binding普通绑定,可以绑定一个按钮,光标,摇杆
Add Positive/Negative Binding两个按钮组合,一个按钮代表正,一个按钮代表负,返回值为float,例如左右键
Add Up/Down/Left/Right四个按钮组合,或者摇杆,返回值为Vector2
Add Binding With One Modifier两个按钮组合键,如Ctrl + b
Add Binding With Two Modifiers三个按钮组合键,如Shift + Ctrl + b

在这里插入图片描述
新建一个Input Action,点击Path进行设备绑定,点击Listen监听当前的输入设备,进行快速选择

在这里插入图片描述
Action Type有三种类型

Action Type描述
Value各种连续变化的输入,如鼠标移动,键盘的WASD,手柄的摇杆,它会监听所有的输入设备,选择输入值最大的作为输入源
Button按钮输入,键盘,鼠标,手柄按钮,在按下,按住,抬起时会调用输入事件
Pass Through和Value基本相同,但它会获取所有设备的输入

比如,当Action Type 为Value时,左摇杆向右稍微移动产生一个输入值,假设为(0.3,0),输入源是手柄,此时按下键盘的w键,产生输入值(0,1),因为(0,1)向量模长更大,输入源就切换到键盘
当Action Type 为Pass Through时,会优先考虑最近的输入值,而不管它有多大

在这里插入图片描述
操作类型(Control Type)是输入值的类型,一般移动或改视角都用Vector2

对于Value这种连续变化的值,需要在Update中读取值,然后再做相应的逻辑

    public void Update()
    {
        Vector2 move = _gameInput.Gamepad1.Move.ReadValue<Vector2>();
        Move(move);
    }
    
    private void Move(Vector2 direction)
    {
        if (direction.sqrMagnitude < 0.01)
            return;
        //DoSomething
        Debug.LogError(direction);
    }

对于按钮类型的事件,它有三个阶段

阶段描述
wasPressedThisFrame按下,触发一次
isPressed按住,按住时一直触发,即触发多次
wasReleasedThisFrame抬起,触发一次

键盘操作

// old
if (Input.GetKeyDown(KeyCode.A)) //按下A兼
	DoSomething();
if (Input.GetKeyUp(KeyCode.A))   //抬起
	DoSomething();
if (Input.GetKey(KeyCode.A))     //按住
	DoSomething();

// new
if (Keyboard.current.aKey.wasPressedThisFrame) 	//按下A键
	DoSomething();
if (Keyboard.current.aKey.wasReleasedThisFrame) //抬起
	DoSomething();
if (Keyboard.current.aKey.isPressed)     		//按住
	DoSomething();

鼠标操作

// old
Vector2 mousePos = Input.mousePosition; //鼠标位置
if (Input.GetMouseButtonDown(0)) 	    //按下鼠标左键
	DoSomething();
if (Input.GetMouseButtonUp(1))   		//抬起右键
	DoSomething();
if (Input.GetMouseButton(2))     		//按住中键
	DoSomething();

// new
Vector2 mousePos = Mouse.current.position.value;
if (Mouse.current.leftButton.wasPressedThisFrame) 	//按下鼠标左键
	DoSomething();
if (Mouse.current.rightButton.wasReleasedThisFrame) //抬起右键
	DoSomething();
if (Mouse.current.middleButton.isPressed)     		//按住中键
	DoSomething();

手柄操作

if (Gamepad.current.leftShoulder.wasPressedThisFrame) 	//按下左肩键
    DoSomething();
if (Gamepad.current.rightTrigger.wasReleasedThisFrame)  //抬起右扳机键
    DoSomething();
if (Gamepad.current.buttonNorth.isPressed)     		    //按住右侧上方的按键
    DoSomething();

对于每个InputAction,它有三个阶段

阶段描述
started开始阶段,类似按钮按下,触发一次
performed执行阶段,类似按钮按住,但只会触发一次
canceled取消阶段,类似按钮抬起,触发一次

在这里插入图片描述
以这个名为Attack的InputAction为例

    public void Awake()
    {
        _gameInput = new GameInput();
        
        _gameInput.Gamepad1.Attack.started += context =>
        {
            Debug.LogError("started--" + Time.time);
        };
        _gameInput.Gamepad1.Attack.performed += context =>
        {
            Debug.LogError("performed--" + Time.time);
        };
        _gameInput.Gamepad1.Attack.canceled += context =>
        {
            Debug.LogError("canceled--" + Time.time);
        };
    }

在这里插入图片描述
可以看到,默认情况下,started 和 performed 是在同一时间
在这里插入图片描述

Interactions 交互操作

在这里插入图片描述
Hold,长按,按住时间到达Hodl Time才会触发performed阶段。Press Point指按钮按下幅度阈值,0未按下,1按下,超过0.5就表示按下,使用默认值就行,也可以取消Default前面的勾选,自己设定值
在这里插入图片描述
Tap,快速按下并抬起,当按住时间 <= Max Tap Duration,抬起时会触发 performed 阶段,但是不会触发 canceled 阶段,当按住时间 > Max Tap Duration,会触发 canceled 阶段
在这里插入图片描述
Slow Tap,按下至少一段时间后抬起,当按住时间 < Min Tap Duration,抬起时会触发 canceled 阶段,,当按住时间 > Min Tap Duration,抬起时会触发 performed 阶段
在这里插入图片描述
Multi Tap,连点,短时间内连点Tap Count次,两次点击的间隔不能超过Max Tap Spacing,单次点击按下的时间不能超过Max Tap Duration
在这里插入图片描述
Press,按下或抬起时触发事件,选择Press Only,按下时触发started 和 performed 阶段,选择Release Only,抬起时触发 performed 和 canceled 阶段,选择Press And Release,按下时触发started 和 performed 阶段,抬起时触发 performed 和 canceled 阶段

一个按钮上可以绑定多个Interactions,根据类型执行不同的逻辑

    _gameInput.Gamepad1.Attack.performed += context =>
    {
        if (context.interaction is HoldInteraction)
        {
            //长按逻辑
        }
        else if (context.interaction is TapInteraction)
        {
            //快点按下并抬起
        }
    };

Processors 输入值处理

在这里插入图片描述
在这里插入图片描述
Stick Deadzone,输入向量的模长小于Min,输入向量会变成(0,0),输入向量模长大于Max,输入向量会归一化到1,这个主要是处理摇杆漂移的问题
在这里插入图片描述
Axis Deadzone,输入值小于min的为0,输入值大于max的为1或-1,和Stick Deadzone类似,只是处理一维的值

Normalize Vector2 归一化处理,这与调用Vector2.normalized相同

在这里插入图片描述
Scale Vector2 对输入向量的x,y进行缩放处理

Invert Vector2 对输入值取反

UI 输入操作

在这里插入图片描述
EventSystem 默认使用Standalone Input Module,它是用旧的Input Manager驱动的,点击Replace with Input System UI Input Module
在这里插入图片描述
一般不需要修改,使用默认值就行
在这里插入图片描述
也可以定义UI上的点击操作,比如左键攻击,右键释放技能
在这里插入图片描述
UI上的摇杆,只要在Image挂上On Screen Stick脚本,Control Path 选择摇杆,那么它会创建一个虚拟摇杆作为输入,Movement Range是摇杆可移动范围
游戏中一般是左摇杆移动,屏幕右侧拖动改变视角,这个屏幕拖动的逻辑就得在UI中写逻辑实现

在这里插入图片描述
屏幕上的按钮添加On Screen Button脚本,也会创建一个虚拟按键作为输入

组合键和单独按键冲突

比如,b键定义了方法1,ctrl + b定义了方法2,按下ctrl后再按b键,方法1和方法2会同时触发,针对这种冲突的情况需要在代码中处理

     if (Keyboard.current.bKey.wasPressedThisFrame)
     {
         if(Keyboard.current.ctrlKey.isPressed)
             //执行 ctrl + b 操作
         else
             //执行 b键 操作
     }

手柄按键冲突也一样

    if (Gamepad.current.buttonNorth.wasPressedThisFrame)
    {
        if(Gamepad.current.leftShoulder.isPressed)
            //执行 leftShoulder + buttonNorth 操作
        else
            //执行 buttonNorth 操作
    }

Switch Pro 连接问题

目前Package Manager中,默认Input System最新版本是1.3.0
这个版本蓝牙连接 Switch Pro 手柄有问题,左摇杆没有移动但是一直有输入值,导致移动没法用,下面的代码有随机输入值

Vector2 move = _playerInput.Player.Move.ReadValue<Vector2>();

升级到1.5.0版本可以解决这个问题
在这里插入图片描述
通过url添加1.5.0版本,com.unity.inputsystem
在这里插入图片描述

参考

带你了解Unity的New Input System

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/355257.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

nacos discovery和config

微服务和nacos版本都在2.x及之后。1、discovery用于服务注册&#xff0c;将想要注册的服务注册到nacos中&#xff0c;被naocs发现。pom引入的依赖是&#xff1a;yml配置文件中&#xff1a;2、config用于获取nacos配置管理->配置列表下配置文件中的内容pom引入的依赖是&#…

Android问题解决方案(一):Android 打空包后提示没有”android:exported“的属性设置

Android 打空包后提示没有”android:exported“的属性设置Android 打空包后提示没有”android:exported“的属性设置1、问题&#xff1a;2、文档3、参考链接&#xff1a;4、解决方案&#xff1a;Android 打空包后提示没有”android:exported“的属性设置 1、问题&#xff1a; …

SpringMVC——基础知识

基本概念 SpringMVC是基于servlet api构造的原始web框架&#xff0c;全称是Spring Web MVC 而MVC的全称是Model View Controller&#xff0c;翻译成中文分别是“模型”&#xff0c;“视图”&#xff0c;“控制器”&#xff0c;这是一种软件的架构模式 Model&#xff1a;用来…

JavaScript:简单理解防抖和节流,如何定义防抖和节流函数?

防抖 防抖函数&#xff0c;就是防止抖动&#xff0c;避免事件重复触发。比如监听输入框的输入&#xff0c;不应该在用户每输入一个字符就触发监听&#xff0c;而是在用户输入结束后再来监听。 流程为&#xff1a; 1、事件触发&#xff1b; 2、开启定时器&#xff1b; 3、当事…

致远OAA6版安装

准备工作&#xff0c;操作系统winserver2019&#xff0c;sqlserver2019。致远OA安装包0.SeeyonInstall.zip相关下载&#xff1a;winserver2019下载地址&#xff1a;cn_windows_server_2019_updated_july_2020_x64_dvd_2c9b67da.iso magnet:?xturn:btih:22A410DEA1B0886354A34D…

实用版ChatBing论文阅读助手教程+新测评

实用版ChatBing论文阅读助手新测评 AI进化&#xff08;更新&#xff09;的速度太快了&#xff01;距离我上次的【Chat嘴硬&#xff01;基于NewBing的论文调研评测报告】&#xff0c;才四天&#xff0c;它已经进化到快能用的地步了&#xff01; 这次是我刷B站看到热门推荐&…

美团 PK 抖音,内容与商业化之间的较量谁能赢?

□ 最近事件&#xff1a;根据Tech星球报道&#xff0c;近期美团升级短视频、直播等内容建设&#xff1b;并且宣称调整战略&#xff0c;发力短视频和直播 1、美团外卖APP商家信息流中&#xff0c;会出现约30秒的短视频内容&#xff0c;视频偏向于种草&#xff0c;主要是向消费者…

明美新能在创业板IPO过会:计划募资4.5亿元,2022年营收约39亿元

2月17日&#xff0c;深圳证券交易所披露的信息显示&#xff0c;广州明美新能源股份有限公司&#xff08;下称“明美新能”&#xff09;获得上市委会议审议通过。本次冲刺上市&#xff0c;明美新能计划募资4.50亿元&#xff0c;德邦证券为其保荐机构。 据介绍&#xff0c;明美新…

响应式编程(Reactive Programming)介绍

什么是响应式编程? 在互联网上有着一大堆糟糕的解释与定义。Wikipedia 一如既往的空泛与理论化。Stackoverflow 的权威答案明显不适合初学者。Reactive Manifesto 看起来是你展示给你公司的项目经理或者老板们看的东西。微软的 Rx terminology"Rx Observables LINQ S…

WebGPU学习(1)---在WebGPU上绘制三角形

在本文中&#xff0c;我们将使用 WebGPU 绘制一个简单的三角形。示例地址 初始化 WebGPU WebGPU 初始化的流程比 WebGL 要更复杂。 在 WebGL 中&#xff0c;我们只需从 Canvas 元素获取 WebGL 渲染上下文&#xff0c;如 getContext(“webgl” 或者 “webgl2”)。 const gl …

浙江工业大学关于2023年MBA考试初试成绩查询及复试阶段说明

根据往年的情况&#xff0c;2023浙江工业大学MBA考试初试成绩可能将于2月21日公布&#xff0c;为了广大考生可以及时查询到自己的分数&#xff0c;杭州达立易考教育为大家汇总了信息。 1、初试成绩查询&#xff1a;考生可登录中国研究生招生信息网“全国硕士研究生招生考…

Redis学习【9】之Redis RDB持久化

文章目录一 AOF(Append Only File) 持久化二 AOF 基础配置2.1 AOF的开启2.2 文件名配置2.3 混合式持久化开启2.4 AOF 文件目录配置三 AOF 文件格式3.1 Redis 协议3.2 查看 AOF 文件3.3 清单文件3.4 Rewrite 机制3.4.1 rewrite简介3.4.2 rewrite 计算策略3.4.3 手动开启 rewrite…

极客时间左耳听风-高效学习

左耳听风——高效学习篇 P95 | 高效学习&#xff1a;端正学习态度 本人真实⬇️⬇️⬇️⬇️ “ 大部分人都认为自己爱学习&#xff0c;但是&#xff1a; 他们都是只有意识没有行动&#xff0c;他们是动力不足的人。 他们都不知道自己该学什么&#xff0c;他们缺乏方向和目标。…

基于RK3588的嵌入式linux系统开发(四)——uboot镜像下载(基于RKDevTool工具)

官方提供的SDK中包含RKDevTool工具&#xff08;RKDevTool_Release_v2.92&#xff09;和相应的驱动&#xff08;DriverAssitant_v5.1.1&#xff09;。本节主要介绍在windows操作系统环境下利用RKDevTool下载以上生成的uboot镜像和bootloader镜像。注意&#xff1a;本节使用的板卡…

什么是Type-c口?Type-c口有什么优势?

什么是Type-C接口 Type-C接口有哪些好处坏处 说起“Type-C”&#xff0c;相信大家都不会陌生&#xff0c;因为最近拿它大做文章的厂商着实不少&#xff0c;但要具体说清楚Type-C是什么&#xff0c;估计不少人只能说出“可以正反插”“USB的一种”之类的大概。其实&#xff0c;T…

JavaEE|网络编程基础与Socket套接字

文章目录一、为什么需要网络编程二、什么是网络编程三、网络编程中的基本概念1.发送端和接收端2.请求和响应3.客户端和服务端4.常见的客户端服务端模型四、Socket套接字概念及分类1.概念2.分类1&#xff09;流套接字&#xff1a;使用传输层TCP协议2&#xff09;数据报套接字&am…

LeetCode 430. 扁平化多级双向链表

原题链接 难度&#xff1a;middle\color{orange}{middle}middle 题目描述 你会得到一个双链表&#xff0c;其中包含的节点有一个下一个指针、一个前一个指针和一个额外的 子指针 。这个子指针可能指向一个单独的双向链表&#xff0c;也包含这些特殊的节点。这些子列表可以有一…

2023年前端面试知识点总结(JavaScript篇)

近期整理了一下高频的前端面试题&#xff0c;分享给大家一起来学习。如有问题&#xff0c;欢迎指正&#xff01; 1. JavaScript有哪些数据类型 总共有8种数据类型&#xff0c;分别是Undefined、Null、Boolean、Number、String、Object、Symbol、BigInt Null 代表的含义是空对象…

蓝图通讯之事件分发器用法

在事件分发器点 加号添加一个分发器 image.png在蓝图开始运行就进行绑定这个事件, image.png他会创建一个以分发器开头_事件的东西. 而绑定类似,只是没有创建和连接 image.pngimage.png然后 我们设置一个键触发这个逻辑. image.png最后验证多次输入多次触发,类似编程中的事件订…

【博客626】不同类型的ARP报文作用以及ARP老化机制

不同类型的ARP报文作用以及ARP老化机制 1、ARP协议及报文 2、不同类型的ARP报文作用 3、ARP工作原理 4、ARP老化机制 5、Linux ARP老化机制 ARP状态机&#xff1a; 在上图中&#xff0c;我们看到只有arp缓存项的reachable状态对于外发包是可用的&#xff0c;对于stale状态的…