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組件。

 

簡單入門

環境配置好後,我們就可以在腳本中直接通過獲取輸入設備來獲取輸入,比如

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的內容和後續的內容詳解後續繼續補充。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章