Unity 新的输入系统Input System(一)

最近看见Unity出了新的输入系统Input System,本着喜新厌旧的原则,就让我们来学习学习这个新系统。

官方文档:https://docs.unity3d.com/Packages/[email protected]/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组件。

Unity 新的输入系统Input System(一)_第1张图片

 

简单入门

环境配置好后,我们就可以在脚本中直接通过获取输入设备来获取输入,比如

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文件路径。创建成功后就会弹出下面这样的编辑界面,先保持默认即可。

Unity 新的输入系统Input System(一)_第2张图片

Unity 新的输入系统Input System(一)_第3张图片

通过这个界面,我们可以看出,假如我们有个角色移动的操作要处理,即图中的Move Action,看Move的内部可以知道,触发该Action的方式有手柄的左遥感,或者键盘的wasd按键等等。这样相比之前的直接获取输入设备而言可以更好的控制触发条件,并且后期添加新的设备触发条件的话,只需要更改这个Asset文件即可。

我们先来简单的看下里面的一些参数。

右键一个Action我们可以看见有如下这些选项,都可以用于为Action添加绑定。

Unity 新的输入系统Input System(一)_第4张图片

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设置响应,如图:

Unity 新的输入系统Input System(一)_第5张图片

通过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();
}

 

大致了解了之后,我们再来看看几个官方的Demo,从Package Manager中导入demo

Unity 新的输入系统Input System(一)_第6张图片

我们先来看看Simple Demo,打开SimpleDemo_UsingPlayerInput.unity运行,我们可以用wasd来移动,鼠标指针来控制朝向,点击鼠标左键来发射(其他几个例子的效果也是一样的,实现的方式不同)。

点击Player查看其Player Input组件,实现的方法就和我们上面所介绍的一样,如果我们想要添加一个方式,利用Q键来发射。只需要在Actions的编辑界面中,fire出点击右边的小加号选择Add Binding,然后关联上KeyBoard的Q键即可。

Unity 新的输入系统Input System(一)_第7张图片Unity 新的输入系统Input System(一)_第8张图片

大家自行理解下即可,这样就是一个最简单的利用新的Input System的例子。

其他几个demo的内容和后续的内容详解后续继续补充。

 

你可能感兴趣的:(Unity,Input,System)