赞
踩
最近看见Unity出了新的输入系统Input System,本着喜新厌旧的原则,就让我们来学习学习这个新系统。
官方文档:https://docs.unity3d.com/Packages/com.unity.inputsystem@1.0/manual/Installation.html
运行环境:Unity 2019.1+ 和 .NET 4 runtime
官方的文档中已经讲得很详细了,我英语这么差都能看懂,大家肯定莫得问题。
简单来说就是在Package Manager中安装Input System,然后在Project Settings中的Player设置里将Active Input Handling设置为Input System即可。
设置好后运行工程,会发现之前的UGUI的界面无法响应点击事件,我们需要将默认场景中的EventSystem中的Standalone Input Module变更为新的Input System UI Input Module组件。
环境配置好后,我们就可以在脚本中直接通过获取输入设备来获取输入,比如
- var gamepad = Gamepad.current;//手柄
- var keyboard = Keyboard.current;//键盘
- var mouse = Mouse.current;//鼠标
- var pointer = Pointer.current;//指针
-
- if (gamepad != null)
- {
- Debug.Log(gamepad.leftStick.ReadValue());//手柄遥感的偏移
- if (gamepad.bButton.wasPressedThisFrame)
- Debug.Log("按下B键");
- }
- if (keyboard != null)
- {
- //执行顺序 isPressed = false -> 按下:wasPressedThisFrame = true -> 中途:isPressed = true -> 松开:wasReleasedThisFrame = true -> isPressed = false
- if (keyboard.wKey.wasPressedThisFrame)
- Debug.Log("w键按下(一直按住w键的话,也只执行一次)");
- if (keyboard.wKey.wasReleasedThisFrame)
- Debug.Log("w键松开");
- Debug.Log("是否按住w键:" + keyboard.wKey.isPressed);
- }
- if (mouse != null)
- {
- Debug.Log(mouse.scroll.ReadValue());//滚轮的滚动值,向前滚Y的值为正,向后滚为负
-
- if (mouse.leftButton.wasPressedThisFrame)
- Debug.Log("按鼠标左键");
- if (mouse.rightButton.wasPressedThisFrame)
- Debug.Log("按鼠标右键");
- if (mouse.middleButton.wasPressedThisFrame)
- Debug.Log("按滚轮键");
- }
- if (pointer != null)
- {
- Debug.Log(pointer.delta.ReadValue());//与上一帧的偏移
- Debug.Log(pointer.position.ReadValue());//在空间中的坐标
- }
更加详细的介绍我们可以在文档中 支持的输入设备 处查阅
通过上面的方法,我们会发现加入我们有些事件可以通过多种输入来触发,比如射击,可以通过鼠标左键、点击屏幕、按键盘,这样就会很麻烦,需要获取很多的设备去设置。或者我们想在后期添加新的输入来控制,比如使用遥感来射击等等,也会很不方便。为了解决这种问题,我们还可以通过Input Action来间接的获取输入。
首先我们给一个GameObject添加PlayerInput组件,每个PlayerInput组件即代表一个玩家。添加好组件后,如果我们要接受到输入,还需要创建Action。我们可以点击组件上的Create Actions按钮来创建,会弹出一个对话框,来选择存放生成的.inputactions文件路径。创建成功后就会弹出下面这样的编辑界面,先保持默认即可。
通过这个界面,我们可以看出,假如我们有个角色移动的操作要处理,即图中的Move Action,看Move的内部可以知道,触发该Action的方式有手柄的左遥感,或者键盘的wasd按键等等。这样相比之前的直接获取输入设备而言可以更好的控制触发条件,并且后期添加新的设备触发条件的话,只需要更改这个Asset文件即可。
我们先来简单的看下里面的一些参数。
右键一个Action我们可以看见有如下这些选项,都可以用于为Action添加绑定。
Add Binding | 普通的绑定,可以绑定一个按钮,光标,遥感等。 |
Add 1D Axis Composite | 两个按钮的组合,一个按钮代表正,一个为负,返回值为float,例如左右键 |
Add 2D Vector Composite | 四个按钮的组合,返回值为vector2,例如WASD |
Add Button With One Modifier Composite | 需要同时按下两个按钮的组合,例如ctrl+1 |
Add Button With Two Modifier Composite | 需要同时按下三个按钮的组合,例如shift+ctrl+1 |
Action Type
Value | 默认,主要用于状态连续更改的输入,例如鼠标的移动,手柄的遥感。如果有多个设备绑定这个Action,只会发送其中一个设备(最受控制的)的输入 |
Button | 用于每次按下时触发的Action |
Pass-Through | 和Value一样,区别在于如果有多个设备绑定这个Action,会发送所有设备的输入 |
Interactions
Interaction(交互)主要用于一些特殊的输入模式,例如其中的Hold模式,要求控件至少保持的时间。
你可以在Action或者Binding下设置它,如果在Action下设置,那么该Action下的每个Binding都会在达成条件下触发这个Interaction。如果在同一个Action或Binding上绑定多个Interaction,则会按照其顺序进行检测。
Unity自带一个可以使用的基本交互(default Interaction),如果用户没有自定义交互的话,系统默认会使用default Interaction。
下面是几种Interaction介绍:
Default:当Action Type为Value或Button时,当输入设备响应会调用started回调(例如按钮按下,或者鼠标开始拖动),当设备响应中时会调用performed回调(在started后触发,调用一次。若为Value的话,当值发生变化会再次触发,例如遥感,按住之后每次偏移位置都会触发一次),当输入设备结束响应会调用canceled回调(例如按钮松开,或者鼠标停止拖动)。当Action Type为PassThrough的时候,只会调用performed回调。
Press:可以实现类似按钮的操作
Trigger Behavior | |
Press Only | 按下的时候触发started和performed。不触发canceled |
Release Only | 按下的时候触发started,松开的时候触发performed。不触发canceled |
Press And Release | 按下的时候触发started和performed,松开的时候会再次触发started和performed。不触发canceled |
Press Point:在Input System中,每个按钮都有对应的浮点值,例如普通的按钮,将会在0(未按下)和1(按下)之间。因此我们可以利用这个值(Press Point)来进行区分,当大于等于这个值则认为按钮按下了。
Hold:适用于需要输入设备保持一段时间的操作。当按钮按下会触发started,若在松开按钮前,按住时间大于等于Hold Time则会触发performed(时间一到就触发),否则触发canceled。
Tap:和Hold相反,需要在一段时间内按下松开来触发。当按钮按下会触发started,若在Max Tap Duriation时间内(小于)松开按钮,触发performed,否则触发canceled。
SlowTap:类似Hold,但是它在按住时间大于等于Max Tap Duriation的时候,并不会立刻触发performed,而是会在松开的时候才触发performed
MultiTap:用作于多次点击,例如双击或者三连击。Tap Count为点击次数,Max Tap Spacing为每次点击之间的间隔(默认值为 2 * Max Tap Duration)。Max Tap Duration为每次点击的持续时间,即按下和松开按钮的这段时间。当每次点击时间小于Max Tap Duration,且点击间隔时间小于Max Tap Spacing,点击Tap Count次,触发performed。
.inputactions文件的介绍大致如上,接着我们要为创建好的Action设置响应,如图:
通过Player Input组件的Behavior属性,来设置Player Input组件通知游戏代码的方式。
Send Messages | 通过在Player Input所属的GameObject上,利用GameObject.SendMessage()来通知 |
Broadcast Messages | 通过在Player Input所属的GameObject上,利用GameObject.BroadcastMessage()来通知 |
Invoke Unity Events | 为每个消息使用单独的UnityEvent,选中的时候会在下面显示Event属性来让我们设置 |
Invoke C Sharp Events | 在脚本中注册事件回调,可用的事件有 onActionTriggered(玩家所以操作的事件集合) onDeviceLose(设备丢失) onDeviceRegaine(设备恢复) |
除了Action的通知外,Player Input还会发送下面两个常规通知
Device Lost Event | 玩家丢失了输入设备,例如设备没电了,或者断开连接等 |
Device Regained Event | 玩家的设备恢复正常使用 |
我们这里先选择Invoke Unity Events的方式来通知事件,在下面的Events折叠栏中,我们可以去关联脚本中的方法。每个事件的方法都需要一个InputAction.CallbackContext参数,我们可以从中获取一些事件信息。
- public void OnMove(InputAction.CallbackContext context)
- {
- Vector2 move = context.ReadValue<Vector2>();
- }
大致了解了之后,我们再来看看几个官方的Demo,从Package Manager中导入demo
我们先来看看Simple Demo,打开SimpleDemo_UsingPlayerInput.unity运行,我们可以用wasd来移动,鼠标指针来控制朝向,点击鼠标左键来发射(其他几个例子的效果也是一样的,实现的方式不同)。
点击Player查看其Player Input组件,实现的方法就和我们上面所介绍的一样,如果我们想要添加一个方式,利用Q键来发射。只需要在Actions的编辑界面中,fire出点击右边的小加号选择Add Binding,然后关联上KeyBoard的Q键即可。
大家自行理解下即可,这样就是一个最简单的利用新的Input System的例子。
其他几个demo的内容和后续的内容详解后续继续补充。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。