时讯:Unity InputSystem使用教程
前言:
本篇主要为大家讲解InputSystem输入系统的基础使用方式以及各选项的功能。
如果您对老版输入系统有过使用经验,那么上手将会非常的顺畅。如果您是刚开始学习Unity的新同学也没有关系,本篇会从基础开始讲述,每一个步骤都尽可能配有操作截图和代码,看完相信您也能轻松学会。
【资料图】
想要使用InputSystem,建议使用Unity 2019.x及以后的版本,因为2018版本的InputSystem还是一个preview版本。本着听人劝吃饱饭的优良传统,作者果断选择了新版本。
我这里采用的是Unity 2021版。
准备工作
第一步我们需要安装InputSystem。
在菜单栏中选择“Window→Package Manager”在弹出的 Package Manager面板中选中“Input System”,单击右下角的Install安装,如果列表中显示的内容较少并找不到Input System时,可以将窗口顶部的“Packages”切换为“Unity Registry”即可。
安装后选择“Yes”,会重启Unity,重启后安装完毕。
安装结束后,我们在顶部菜单栏选择“Edit→Project Settings”点击“Player”我们可以看到Active Input Handling已经切换为“Both”,
这个地方有三个选项:
Input Manger(Old):只采用旧版的Input输入,新版的Input System将不起作用。
Input System Package(New):只采用新版的Input System方式,旧版的Input将不再起作用。
Both:两种方式同时起作用
我们选用“Input System Package(New)”或者“Both”都可以。
Input System的使用方式大致分为两种,一种是通过InputSysten Package提供的组件,在编辑器通过拖拽,选择,挂载等方式,进行函数与输入动作的绑定;另一种是使用代码对函数与输入动作进行绑定。
本文主要侧重于在代码中如何使用Input System,对于编辑器组件面板就适当省略或者开一篇新文章专门讲解。
常用功能对比
安装完毕后我们来对比一下,新老版本的使用差别,下面提供一个官方的文档连接,如果有需要可以查看https://docs.unity3d.com/Packages/com.unity.inputsystem@1.1/manual/Migration.html#unityengineinputanykeydownhttpsdocsunity3dcomscriptreferenceinput-anykeydownhtml
新旧版的键盘按键监听对比:
以监听"A"键按下,抬起,按住为例
旧版:Input.GetKeyDown(KeyCode.A);
Input.GetKeyUp(KeyCode.A);
Input.GetKey(KeyCode.A);
新版:Keyboard.current.aKey.wasPressedThisFrame;
Keyboard.current.anyKey.wasReleasedThisFrame;
Keyboard.current.anyKey.isPressed;
其余键盘按键与“A”并无差别,将“aKey”更换为“bKey”、“cKey”......即可
新旧版的鼠标左键监听对比:
旧版:Input.GetMouseButtonDown(0);
Input.GetMouseButtonUp(0);
Input.GetMouseButton(0);
新版:Mouse.current.leftButton.wasPressedThisFrame;
Mouse.current.leftButton.wasReleasedThisFrame;
Mouse.current.leftButton.isPressed;
鼠标中键、右键使用方法并无差别,将“leftButton”更换为“middleButton”/“rightButton”。
这里的isPressed要稍微提一下,我们按住Ctrl点击isPressed会发现,按住的判断是通过ReadValue()与一个默认值pressPointOrDefault进行对比返回的结果。所以也可以用
Keyboard.current.aKey.ReadValue()>=N
自己指定一个数值N来进行判断,一般来说按下与抬起只会返回0/1,考虑到浮点数的精度问题,建议不要直接使用0或者1来进行判断,避免出现一些精度问题。关于这个地方我们在后边InputActions部分还会做讲解,这个地方就不再说了。
最后就是鼠标位置和滚轮的数据获取。
鼠标位置对比
旧版:Input.mousePosition;
新版:Mouse.current.position;
滚轮对比
旧版: Input.GetAxis("Mouse ScrollWheel");
新版:Mouse.current.scroll.ReadValue();
滚轮这个地方要稍微注意一点,旧版的会直接返回一个float的值,而新版本则会返回Vector2,如果想返回float请使用Mouse.current.scroll.ReadValue().y,值得注意的是,新版返回的Y值一般都较大,我这边根据滚动的速度不同大概都在0,120,240,360左右,希望各位有所了解。
更多的使用区别请参考一开始给出的官方文档,这里就不再一一列举了。
Input Actions
Input Actions是新版输入系统的重点!此处篇幅较长并且与编辑器面板操作较多。
新建Input Actions:
方法一:在Project面板下右键单击,在弹出的菜单中找到“Input Actions”,修改新建“Input Actions”的名称。
方法二:在顶部菜单栏选择“Assets-Create-Input Actions”
选中新建的Input Actions,将"Generate C# Class"勾选,这样可以为我们生成代码,后续要是用,很重要。
其余三个选项
C# Class File:生成的C#代码存放位置。默认与Input Actions同级
C# Class Name:生成C#代码的类名。默认与Input Actions同名
C# Class Namespace:生成代码所处的命名空间。
修改完以后点击Apply保存。
双击新建的Input Actions或者在Inspector面板选择Edit asset,打开Input Actions编辑面板,在此面板我们可以创建一些自己的行为。
点击Action Maps旁边的“+”创建一个“行为映射表”,新建的Map下会带有一个空action和一个未绑定Control的Binding。下边会解释。
现在我们细说一下上述步骤出现的几个概念以及Input Actions配置界面的一些选项。
InputAction Assets,输入行为资产,可以理解成自定义的输入行为(动作)的集合。一个输入动作可以由一种或者多种输入信号组成。比如“前进”这个动作,可以被“W”键触发,也可以被“↑”方向键触发,甚至可以被手柄的“↑”键触发。
Action Map:行为映射表,一个Input Actions可以有多个Map。每个Map下面又有许多Action,可以批量控制Action启用与禁用。比如有一个UI Map,他包含选项的上,下,左,右,确定等功能,我们将这些功能绑定在方向键。另一个Car Map,他控制赛车的移动,绑定的同样是方向键。为了避免功能冲突,我们可以再拉起UI面板的时候,整体禁用Car Map,关闭UI面的时候禁用UI Map,启用Car Map。以及其他类似的操作。
Input System将动作分为三种类型
Button:按钮类型,相对简单只处理按下与抬起,并返回对应数值,可以看做离散型非0 即1。使用ReadValue<float>() 来获取会获得0/1。
Value:值类型,与Button相比,它可以返回连续的数值,比如接入手柄以后,摇杆可以 返回范围内的任何值。返回值的类型可以在Control Type中设置,下方会详细说明。
PassT hrough:直通类型,与Value几乎一致,但是它可以返回所有设备的输入,而Value只会返回当前最优先的设备输入。
Control Type:设置按键返回值的类型。之后会根据当前选择内容筛选输入设备。
Any:任何值 Axis:一维轴浮点数 Bone:骨骼
Digital:数字 Dpad:手柄四向按钮 Eyes:VR相关数值
Integer:整数 Quaternion:四元数 Stick:摇杆
Touch:触控屏 Vector2:二维向量 Vector3:三维向量
Button:按钮
Initial State Check:启用 Action时,Action绑定的Control可能已经具有非默认状态,系统依次检查所有被绑定到此Action的Control,并立即响应处于非默认状态下的控件。
补充:输入系统将不同种类的输入抽象为Control。Control表示输入值的来源,例如,某个float值来源于键盘上的某个按键,某个Vector2值来源于鼠标单帧的位移,某个Vector2值来源于手柄上的摇杆。
参考自:https://blog.csdn.net/qq_39915907/article/details/125630907 本文部分参考自这篇文章,后续将不再写明,建议阅读。
Interactions:交互方式,可以理解为这个动作的触发方式,比如:点击,长按,双击等。
所有的方式都会默认有三个事件Started、Performed、Canceled。
举一个明显的例子,长按(手指按住1秒以上认为是长按):在按下去的瞬间触发Started,在任意时间松开触发Canceled,如果连续按压时间达到1秒触发Performed。
Hold:长按,需要保持按压一段时间才算完成这个动作。就像上方举得例子。
Press Point:表示一个临界点,只有过了这个值才算按下。如果Button则只有0和1。如果是摇杆类的按钮,则需要推动幅度大于PressPoint才行。
Hold Time:长按时间,按下时间达到Hold Time后会立刻触发Performed。
Default如果勾选则会采用Unity提供的默认值,如果想要自定时间和临界值,请取消勾选。
Open Input Settings:默认值可以点击Open Input Settings进行查看并修改,也可以“Edit→Project Settings→Input System Package”打开查看并修改。这两项后续不再讲述。
Multi Tap:连击,在规定时间间隔内点击指定的次数。
Tap Count:连击次数。
Max Tap Spacing:两次点击之间的时间间隔。
Max Tap Duration:单次点击 按下与抬起之间的最大持续时间。
只有每次点击都满足上述两个条件,才会触发Performed。
Press:类似按钮,
Press Only:在按下的时候触发Started和 Performed,在抬起的时候触发Canceled。 Release Only:在按下的时候Started,在抬起的时候触发Canceled和Performed。
Press And Release:在按下的时候触发Started和 Performed,抬起的时候触发Canceled和Performed。
Slow Tap:缓慢点击,他与Hold的区别是,在达到最短按压时间后不会立刻触发Performed,而是在松开的瞬间触发Performed。
Min Tap Duration按压的最短时间。
Tap:单击。可以看做只点击一次的Multi Tap。选项在Multi Tap中也有讲述
Processors:输入值处理,对返回的Value作出指定处理,如取反,限定范围等等。这个地方会因为上边选择的Control Type不同从而导致出现的选项也不同。部分功能类似的选项就会合并讲解。
Clamp:将输入值限制在[min,max]之间,值类型为Float。
Invert:将输入值取反(乘以-1)。应用场景,如果某方向控制键,左输入1右输入-1,我们日常的坐标系都是左为负数,右为正数,为了符合习惯可以取反。
Invert Vector2:同上。可以单独选择取反哪个轴。
Invert Vector3:同上。略。
Normalize:如果最小值>=0,则将[min,max]范围内的输入值规格化为无符号规格化形式[0,1],如果最小值<0,则将输入值规格化为有符号规格化形式[-1,1]。
Normalize Vector2:将输入值归一化,模长为1。比如使用摇杆控制人物移动时,我们往右前方移动,如果值为(1,1)那么就会比单纯前进(1,0)速度要快。这不是我们想要的,所以就要将输入值的模长限制为1。设置后可能会返回(0.71,0.71)其他角度类似。
Normalize Vector3:同上。
Scale:输入值乘以Factor
Scale Vector2:将X轴与x相乘,Y轴与y相乘。
Scale Vector3:类似同上。
Stick Deadzone:摇杆死区处理。摇杆或者其他设备可能存在轻微误触或者其他原因造成的信号问题,在边缘地区不准确。比如将摇杆右滑到底切换下一页,因为某些原因输入值永远在0.99f等等情况。所以只要小于Min值的信号都将变为0,大于Max值的信号都将变为1。
Axis Deadzone:axis死区处理。绝对值小于最小值的任何值为 0,绝对值大于最大值的任何值为 1 或 -1。
选中当前未绑定的<No Binding>,在右侧面板会有Binding、Interactions、Processors三个选项。
其中Interactions和Processor是针对当前Binding的特别设置,与Action功能一致。如果此处未进行设置,就使用上级的Interactions/Processor设置;如果进行了设置,以此处Interactions/Processor的设置为准。
Binding是此处的核心,它的作用是用来对输入信号进行绑定。输入系统将Action与Control之间的连接抽象为Binding。Binding包含一条指向Control的控件路径,多个Binding可以指向同一个Control,一个Action可包含多个Binding。系统收到某个控件输入的数据时,会驱动所有绑定了该控件的Action进行响应。
Binding绑定
在Action Maps栏单击“+”新建Map后,双击新建的Map可以修改其名称“Player”,在Actions栏双击新建的Action修改名称“Jump”,选中<No Binding>,点击右侧的Path旁边的下拉菜单。
比如我们想用键盘“空格”触发跳跃,绑定的方法有三种:
方法1:选择“Keyboard”-"By location of key"-"Space",即可绑定。
方法2:在搜索框中直接搜索目标“Space”,点击即可绑定
关于每个按钮对应的选项以及外接手柄的对应,我会在后续的"Input Debugger"中讲述。
方法3(推荐):通过Listen绑定,点击Listen后就会开始监听输入,我们敲击“空格”,就会现在是在面板中,只要点击即可绑定。
这就是绑定的三种方法。
在实际情况中一个动作可能会被多个按键触发,继续用Jump举例子,在部分小游戏中跳跃可以被“空格”,“↑”甚至数字区的“8”来触发,对于这种情况,InputSystem给我们提供了一个非常简单的解决办法。
单机Jump旁边的“+”,选择“Add Binding”,会在Jump下添加一个新的Binding,我们只需要仿照上面的方法,挨个进行绑定,就可以让多个按钮触发同一个Action.
接下来我们来一起看看Action下的几个绑定选项
Add Binding:普通的绑定,可以绑定一个信号。
Add Positive\Negative Binding:由两个信号组成的绑定,返回一维向量。比如2d游戏中的左移/右移动。
选中“Negative ”与“Positive”后续绑定方法与Binding一致,此处的几个选项
Composite Type:没有查到相关资料,如果选择后两项会变成“Add Binging With One Modifier”和“Add Binding With Tow Modifiers”样式,此处不再展开讲解,如果有读者了解可以在评论区帮忙完善,感谢。
Min Value:Negative 绑定键的值
Max Value:Positive 绑定键的值
Which Side Wins:当同时按下两个键的处理方式,Neither,两个键都停止输入,Negative 和Positive返回指定输入值。
Add Up\Down\Left\Right Composite:返回二维数据,由四个信号组成,可以用于WASD,↑↓←→等。绑定与Binding一样。
Add Up\Down\Left\Right\Forward\Backward Composite:返回三维数据,由六个信号组成,类似Unity的WASDQE,控制前后左右上下等。绑定与Binding一样。
Add Binging With One Modifier:组合键,例如Ctrl+S,Ctrl+Z等
Add Binding With Tow Modifiers:组合键,例如组合键Ctrl+K+C,Ctrl+K+U等等
在使用组合键的时候,注意热键冲突。类似“Alt+F4”这样的组合键,只能说劝君慎重!!!
Input Debug
Input Debug窗口是一个非常好用的东西,打开方式:
“Window→Analysis→Input Debugger”
这个窗口中,所有可以被识别的输入设备都会被显示在这。之前我们在绑定输入按钮的时候会不会有这么一个疑惑,我怎么知道这个按钮对应哪个信号。还有每个信号的输入值类型又是什么样子呢?
我们就以我的手柄为例,上图中我已经选中了手柄,双击,打开详细界面。
我们可以看到设备的详细信息。Name就是在Unity InputSystem中对应的名称;DisplayName是我手柄上的文字,B就对应我手柄的B;后边还有信号类型方便我们设置Type。此时按动手柄还能通过value看到实时输入值,并且屏幕下方还会实时打印,方便我们调试。爆赞!
比如我此时正在按B键,掰动摇杆,所有的输入信息都会在面板中展示出来,建议各位自己尝试一下。
Input Actions配置界面的内容大部分就已经讲完了还有一个ControlSchemes,这部分我们等到接入手柄以后再讲解。下面我们正式在代码中使用我们自定的Input Actions。
对我来说,使用代码更加直观,也更易于理解一点。
先来看一下我的Input Actions是长什么样子的。以免下面代码中出现一些名字让人产生疑惑。
我的InputActions我改名为“MyInputSystem”,他有一个Map名字是“Player”,下面有两个行为“Jump”跳跃绑定的是键盘的空格键,“Movement”移动绑定的是WASD。
点击上方的"Save Asset",保存我们的设置,并且生成对应的代码。代码保存路径就在我们一开始提过的,如果遗忘,请向上翻找。
为了保持各位的阅读连贯性,就不分上下篇。
直接二合一!
使用Input System,我们的脚本需要引用using UnityEngine.InputSystem
生成的代码各位可以自行查看,这里就不详讲,要不然篇幅太长了。
新建一个脚本。引入命名空间。
声明自定义的InputActions并实例化,我这边的类名是MyInputSystem。
注意:使用之前一定要执行Enable();否则不起作用。每一个Map以及Action都可以单独设置Enable和Disable;
现在输入监听就已经开启了。
我们让跳跃函数与Jump绑定。
绑定Movement
使用ReadValue<T>()来获取数值,这个T尽可能与在面板中设置的Control Type保持一致,以免发生一些预料之外的错误。
上面讲过,每个Action默认有started,performed,canceled事件。所以我们扩展成以下形式。
您可以尝试将自己的定义的Action与函数进行绑定。这种写法,会在监听到绑定的信号输入时调用对应事件。属于按一下执行一次,不会一直回调。
目前可能并不太能直观的体现出三种事件的区别。
我们现在把Jump改一下,变成performed要蓄力1秒才会触发。这样大家就能看出来明显的区别。修改完以后记得保存。
inputActions.Player.Jump.started += ctx=>Debug.Log("按下空格");
inputActions.Player.Jump.performed += ctx => Debug.Log("蓄力完成");
inputActions.Player.Jump.canceled += ctx => Debug.Log("松开空格");
38秒按下空格触发started ,1秒(39秒)后触发performed ,40秒抬起空格触发canceled 。
可以看到,现在三个事件已经出现了明显的区别。
这个地方大家一定要自己多多实践,与上半部分那些设置组合起来多多尝试,才能更好的使用。我这篇文章也不能给大家把所有的组合全部展示出来,那样也没有意义。
接入手柄
在开发中,移动并不是单纯靠键盘输入,可能还有靠手柄,现在很多手柄配有摇杆,输入的值也并不是非0即1,这样可以通过摇杆控制角色移动的同时并控制速度。
我们继续在Movement下添加手柄摇杆。此处要将Mode改成Analog,否则还是会和按键一样,只能返回0/1。下方的Processors进行归一化设置,上边讲过是为了限制模长为1。
接入代码看看最后的效果。
private void Update()
{
//因为要每帧都获取数据,所以需要在Update中
if (inputActions.Player.Movement.IsPressed())
{
Debug.Log(inputActions.Player.Movement.ReadValue<Vector2>());
}
}
现在已经可以看到,摇杆已经被成功接入,并且可以获取摇杆推动的幅度。
手柄的其他按键与摇杆也可以通过类似的方法进行设置。
补充——手柄震动
对于部分支持震动的手柄来说,我们可以用代码控制它震动。方式获取要震动的手柄,设置最低震动频率与最高震动频率。上代码!
注意,实际应用时应该增加一步判空检查,避免报错。
private void OnEnable()
{
//手柄可以直接指定当前手柄,也可以通过InputAction.CallbackContext回调获取
//开启震动.
Gamepad.current.SetMotorSpeeds(0.2f, 0.5f);
}
private void OnDisable()
{
//结束震动
Gamepad.current.SetMotorSpeeds(0, 0);
}
Control Scheme——控制方案
随着我们接入手柄,我们现在已经有了键盘,手柄两套输入,随着以后项目的完善可能还会接入其他外设,比如方向盘模拟器,某专用手柄等等。定义的行为也会越来越多,显示的内容可能会很多,Control Scheme 可以帮我们更好的管理定义的行为,方便切换平台等。
点击左上角菜单 → AddControl Scheme
Add Control Scheme:添加一个方案。
Edit Control Scheme :编辑一个方案。
Duplicate Control Scheme :复制一个方案。
Delete Control Scheme :删除一个方案。
Requirements: 列表中的每种类型设备可以选择为Optional或Required
Optional: 可选的(官方未给出说明)
Required: 必要的(官方未给出说明)
这里我们新建一个“Player”和“Gamepad”
现在每一个binding都会出现选“Use in control Scheme”选项。勾选相应的选项。
Control Schemes可以进行过滤显示,点击上方选项,选择一个Control Scheme或者All Control Schemes全部显示。
点击后边的Device,可以通过Device进行过滤显示。
删除Control Schemes的时候要注意,切换到自定义Schemes,选择删除后, 首先会询问是否确定删除。选择确定后会弹出,是否删除所有勾选为指定Schemes的Binding,以当前为项目例,如果选择“yes”,所有勾选"Player"的Binding都会被删除,如果选择“No”则Binding会被保留只删除Control Schemes。
补充:使用inputSystem后,UI的EventSystem根据选择模式不同可能会失效。使用UI前请点击“Replace with InputSystemUIInputModule”。
到这里InputSystem的基础使用方法基本就介绍完毕。
到这篇幅也已经不短了再接着写下去也不合适。 还有一些其他内容在这里就不展开讲解,比如Input System支持输入记录,多手柄等等,还有一些选项的具体使用方法,以及Player Input的使用,编辑器上点击配置一些函数的调用等等。
如果有较多的人想看或者需要这方面的演示,我可以专门出一期视频来展示,那些内容用文章的方式不是非常合适,也不直观。
如果本文对您有所帮助,请支持一下作者。
求赞,求赞,求赞
我们下期再见
关键词:
相关新闻
- 时讯:Unity InputSystem使用教程
- 超2250万台(套)各型装备投入春耕——农机化支撑粮食稳产增产
- 10大无花果排名?
- 勇士最新伤病名单:明日VS开拓者 库里库明加大概率出战 环球速递
- 天天实时:彭世坤拦网发威,张景胤替补得3分!皮内罗洛保级,缪伊雯未得分
- 天天热议:社区英语复数 社区英语
- 济南市国土资源局_国土资源局改名后叫什么|天天看点
- 他在西湖白堤上跑出一条生命通道!“最美了奔跑哥”找到了
- 上市银行去年房地产及信用卡贷款不良上升,预计今年资产质量将逐步改善
- 《文心雕龙》里的17句话,让人拍案叫绝!|今头条
- 岳阳楼区举行退役军人适应性培训 天天动态
- 我等候你歌词(徐志摩:我等候你歌手:Pn) 全球微速讯
- 《神奇的探险之旅》读后感500字 全球快资讯
- 环球速讯:帝王绿手镯_帝王受
- 绍兴市创新推进“车辆注销一件事”改革
- 世界快播:你平时买的藤椒,可能并不是藤椒
- 惟吾德馨的德馨是什么意思_惟吾德馨什么意思|世界实时
- 全球观察:多彩贵州·从万桥飞架看中国奋斗|乌江镇:在“五桥”边上读懂乌江 发展乌江
- time怎么读视频_time怎么读_世界动态
- 动态:官方:国足亚运队球员叶力江-什那尔加盟南通支云
- 触手森林里的王子殿下笔趣阁_触手森林里的王子殿下书包网
- 每GB不足1美元Intel330系列新增240GB型号
- 教育部开展第二批全国学校急救教育试点工作-天天最新
- 美德匈牙利反对就乌克兰加入北约给出路线图 乌克兰空军敦促西方援助F-16比米格-29好四到五倍