本文轉(zhuǎn)自Unity Connect博主 凍蔥Tewi
有關(guān) Unity 新輸入系統(tǒng) Input System 的一些簡(jiǎn)單介紹和基礎(chǔ)總結(jié)托慨。目前關(guān)于新輸入系統(tǒng)的中文資料略少,在 Unity 官方文檔中學(xué)習(xí)了一番之后杯瞻,我將一些基本的知識(shí)記錄了下來(lái)。
新輸入系統(tǒng) (Input System) 概述
在 Unity 設(shè)計(jì)之初惨好,并沒(méi)有預(yù)見(jiàn)到現(xiàn)在如此豐富的平臺(tái)和設(shè)備支持規(guī)模疚膊,所以一開(kāi)始設(shè)計(jì)的輸入系統(tǒng) UnityEngine.Input 使用起來(lái)并不舒適,在多設(shè)備和多平臺(tái)輸入處理時(shí)顯得力不從心且不夠優(yōu)雅历谍,甚至連游戲中熱插拔手柄這種操作都顯得十分臃腫和復(fù)雜现拒。Unity Tec 從 2016 年起開(kāi)始逐步開(kāi)發(fā)新一代輸入系統(tǒng) UnityEngine.InputSystem ,到今天(Unity 2019.3.0f6)望侈,已經(jīng)迭代到了 1.0.0-preview.4 版本印蔬。官方表示大概在 Unity 2020 版本推出新輸入系統(tǒng)的正式版,但是舊輸入系統(tǒng)的下架時(shí)間并沒(méi)有被明確脱衙。
新輸入系統(tǒng)基于事件侥猬,輸入設(shè)備和動(dòng)作邏輯互相分離,通過(guò)配置映射來(lái)處理輸入信息捐韩。具有易用退唠,多設(shè)備多平臺(tái)協(xié)調(diào)一致的特點(diǎn)。現(xiàn)在已經(jīng)可以在 Package Manager 中安裝使用了荤胁。
Input System 安裝
在 Unity 2019.1 之后的版本中瞧预,打開(kāi)包管理器(Windows -> Package Manager),在 Advanced 菜單中勾選預(yù)覽版支持(Show Preview Packages)寨蹋,接著就可以在 All Packages 列表中找到 Input System 了松蒜,點(diǎn)擊 Install 安裝即可扔茅。
導(dǎo)入過(guò)程中會(huì)跳出警告窗口告知需要激活新輸入系統(tǒng)的后端已旧,點(diǎn)擊是會(huì)重啟編輯器,此時(shí)便啟用了新輸入系統(tǒng)召娜。
接著打開(kāi) Edit -> Project Settings运褪,在 Player 選項(xiàng)頁(yè)中的 Other Settings -> Configuration 中設(shè)置 Active Input Handling 為 Input System 以禁用舊輸入系統(tǒng),以防止兩個(gè)輸入系統(tǒng)的沖突和杜絕隱患玖瘸。
此時(shí)秸讹,你的工程中已經(jīng)成功安裝了新輸入系統(tǒng)。
Input System 簡(jiǎn)單介紹
有關(guān)新輸入系統(tǒng)的內(nèi)容幾乎都在 UnityEngine.InputSystem 命名空間下雅倒,使用時(shí)不要忘記 using UnityEngine.InputSystem璃诀。一些特殊的對(duì)象可能在子命名空間下,具體請(qǐng)查閱文檔蔑匣。
Class InputAction
這個(gè)類(lèi)表示的是一種響應(yīng)動(dòng)作邏輯劣欢,可以綁定到多個(gè)物理輸入上,這些綁定的物理輸入和得到的輸入值將影響同一個(gè) InputAction 對(duì)象裁良。該類(lèi)只代表一種動(dòng)作“邏輯”而不代表任何物理輸入凿将。
每個(gè)動(dòng)作邏輯在每一時(shí)刻都有現(xiàn)在的狀態(tài)階段(Phase),通過(guò) Enum InputActionPhase 表示价脾,有五種階段牧抵。分別為:Canceled, Disabled, Performed, Started, Waiting。在 Start, Performed, Canceled 階段會(huì)分別觸發(fā)三個(gè)對(duì)應(yīng)的 C# 事件(類(lèi)型為event Action<InputAction.CallbackContext>)。
每次動(dòng)作邏輯被觸發(fā)時(shí)犀变,可以通過(guò)ReadValue<TValue>()成員來(lái)獲取本次觸發(fā)的具體值妹孙。
聲明: [Serializable] public sealed class InputAction : ICloneable, IDisposable
Struct InputAction.CallbackContext
這個(gè)結(jié)構(gòu)體將作為動(dòng)作邏輯被觸發(fā)時(shí)事件的參數(shù)使用,內(nèi)部含有關(guān)于本次觸發(fā)情況的所有參數(shù)获枝。
InputBindings
表示動(dòng)作邏輯和輸入設(shè)備之間的綁定關(guān)系涕蜂。每個(gè) Binding 需要有源輸入設(shè)備(Path)和綁定的動(dòng)作邏輯(InputAction),可以有輸入條件限制(Interactions)限制設(shè)備的觸發(fā)條件和后處理器(Processors)來(lái)進(jìn)行輸入源數(shù)據(jù)的后處理映琳。
一個(gè)綁定可能有以下幾種合成類(lèi)型(Composite Type):1D Axis, 2D Vector, Button, Button with modifier, Custom composite机隙,分別表示單軸輸入,雙軸向量輸入萨西,按鈕輸入有鹿,帶有條件的按鈕輸入和自定義輸入數(shù)據(jù)類(lèi)型。
Asset InputActionAssets
Input Action Assets 是一種存儲(chǔ)動(dòng)作綁定關(guān)系的資源文件谎脯,擴(kuò)展名為.InputActions葱跋,數(shù)據(jù)格式為 JSON≡此螅可以通過(guò) Project 頁(yè)面中 Create -> Input Actions 來(lái)創(chuàng)建一個(gè)新的 Input Action Assets娱俺。
每個(gè)資源文件可以存儲(chǔ)多個(gè)映射列表,最左側(cè)一欄黃色標(biāo)簽代表不同的映射列表废麻。中間一欄表示當(dāng)前映射列表中存儲(chǔ)的 Input Action(綠色標(biāo)簽)荠卷,每個(gè)Input Action可以有多個(gè)Input Bindings(藍(lán)色標(biāo)簽),每個(gè)Input Binding 視類(lèi)型可以有多個(gè)合成分量(Composite Bindings)(粉色標(biāo)簽)烛愧。右側(cè)一欄表示當(dāng)前對(duì)象的屬性油宜,可以進(jìn)行調(diào)整。
Input Action Assets 可以生成指定格式的 C# 類(lèi)怜姿,可以通過(guò)操作該類(lèi)來(lái)進(jìn)行相同的操作慎冤。可以根據(jù)喜好選擇生成與否沧卢。
Class PlayerInput
新輸入系統(tǒng)提供的類(lèi)蚁堤,可以通過(guò)添加到 Game Object 上作為組件使用。本文只介紹其 Inspector 可配置內(nèi)容但狭。
其中:
Actions 表示其使用的 Input Action Assets 資源文件披诗,Default Map 表示其使用資源文件中的哪個(gè)映射列表。
UI Input Module 項(xiàng)可以通過(guò)指定一個(gè) InputSystemUIInputModule 對(duì)象來(lái)與 UI 協(xié)作熟空。
Camera 項(xiàng)用于分屏游戲時(shí)指定該 Player Input 對(duì)應(yīng)的攝像機(jī)對(duì)象藤巢。
Behavior 項(xiàng)表示當(dāng)有動(dòng)作邏輯觸發(fā)時(shí)的相應(yīng)方式,有Send Messages, Broadcast Messages, Unity Events, CSharp Events四種觸發(fā)模式息罗。分別有著慢掂咒,更慢,可視化,快的特點(diǎn)绍刮。但是前兩個(gè)實(shí)現(xiàn)方式比較無(wú)腦簡(jiǎn)單温圆,在游戲?qū)ο髢?nèi)實(shí)現(xiàn)命名為對(duì)應(yīng)的 On{ActionName}()函數(shù)即可接受對(duì)應(yīng)觸發(fā)效果,Unity Events 方式需要在 Inspector 中分配各種函數(shù)孩革,雖然可視化岁歉,但是在函數(shù)和動(dòng)作邏輯較多時(shí)比較麻煩。C# Events 一如既往的優(yōu)雅而又有效率膝蜈,但是唯一的不足是所有自定義觸發(fā)都共享同一個(gè)事件event Action<InputAction.CallbackContext> onActionTriggerd锅移,需要在訂閱事件之后自行比較觸發(fā)的動(dòng)作邏輯是否是該訂閱者需要的,這種方式可以說(shuō)是有利有弊饱搏。
Input System 四種基本使用方式
官方給出的 Sample 給出了四種使用新輸入系統(tǒng)的基本方式:
使用輸入 State
直接使用當(dāng)前輸入設(shè)備的狀態(tài)來(lái)控制對(duì)象非剃,沒(méi)什么特別的。大概相當(dāng)于用舊輸入系統(tǒng)的思想使用新輸入系統(tǒng)推沸,唯一的進(jìn)步大概是輸入設(shè)備變得標(biāo)準(zhǔn)化了备绽。
示例(都是英文句子就不注釋了):
public void Update()
{
var gp = Gamepad.current;
if (gp == null) return;
Vector2 leftStick = gp.leftStick.ReadValue(),
rightStick = gp.rightStick.ReadValue();
if (gp.buttonSouth.wasPressedThisFrame) Debug.Log("Pressed");
if (gp.buttonSouth.wasReleasedThisFrame) Debug.Log("Released");
//...
}
</pre>
</pre>
使用 Player Input 控件
通過(guò)添加 Player Input 控件來(lái)管理輸入,這種方式絕大部分綁定操作需要在 Inspector 中完成鬓催,代碼只需要寫(xiě)出每個(gè)事件觸發(fā)時(shí)的訂閱者(命名必須為On{ActionName}()肺素,C# 事件方式除外)即可。
下面是兩種類(lèi)型的動(dòng)作邏輯值的訂閱者示例(只演示兩種事件類(lèi)型宇驾,我拒絕SendMessage()):
public class Player : MonoBehaviour
{
// Unity Event的情況倍靡,需要在Inspector中進(jìn)行本函數(shù)的訂閱操作
public void OnAttack(InputAction.CallbackContext callback)
{
switch (callback.phase)
{
case InputActionPhase.Performed:
Debug.Log("Attacking!");
}
move = callback.ReadValue<Vector2>();
}
// C# 事件的情況,與上方情況不共存
private PlayerInput input;
private Vector2 move;
private void Awake()
{
// 添加訂閱者函數(shù), 當(dāng)然也可以寫(xiě)成獨(dú)立的函數(shù)
input = GetComponent<PlayerInput>().onActionTriggered +=
callback =>
{
if (callback.action.name == "Move")
{
move = callback.ReadValue<Vector2>();
}
};
// ...
}
}
</pre>
</pre>
使用 Action Assets 生成的 C# 類(lèi)
剛才說(shuō)過(guò) Action Assets 資源文件可以生成一個(gè) C# 類(lèi)飞苇,通過(guò)建立一個(gè)這個(gè)類(lèi)對(duì)象來(lái)進(jìn)行控制可以達(dá)到使用資源文件相同的效果菌瘫。
假設(shè)我們導(dǎo)出了一個(gè)CustomControl類(lèi)蜗顽,則有示例:
public class Player : MonoBehaviour
{
private CustomControl input;
private void Awake()
{
input = new CustomControl(); // 實(shí)例化
// 通過(guò)訂閱事件的方式添加控制方式
// Player是映射列表, Attack是一個(gè)InputAction名字
input.Player.Attack.performed +=
callback =>
{
Debug.Log("Attacking!")
}
}
private void Update()
{
// 通過(guò)主動(dòng)讀取InputAction狀態(tài)獲取輸入
Vector2 move = input.Player.Move.ReadValue<Vector2>();
//...
}
}
</pre>
</pre>
使用自定義的 Input Action 列表
喜聞樂(lè)見(jiàn)的一點(diǎn)布卡,Input Action 對(duì)象是可以在 Inspector 中顯示的(廢話雇盖,不然 Assets 編輯列表顯示什么)忿等。所以可以通過(guò)自定義 Input Action 對(duì)象來(lái)處理輸入。
以下是一種示例:
public class Player : MonoBehaviour
{
public InputAction moveAction;
public void OnEnable()
{
moveAction.Enable();
}
public void OnDisable()
{
moveAction.Disable();
}
// 此時(shí)我們自定義的InputAction即可正常使用
public void Update()
{
var move = moveAction.ReadValue<Vector2>();
//...
}
}
</pre>
</pre>
結(jié)語(yǔ) 當(dāng)前網(wǎng)上關(guān)于新輸入系統(tǒng)的中文資料真的很少崔挖,希望這篇文章能夠幫到你贸街,也希望 Unity 越來(lái)越好。 參考資料
更多干貨分享狸相,歡迎大家戳下面鏈接下載Unity官方技術(shù)社區(qū)app薛匪,在線技術(shù)答疑,學(xué)習(xí)交友兩不誤脓鹃!
原文鏈接:https://connect.unity.com/p/unity-xin-inputsystem-de-jian-yao-shi-yong?app=true