【Unity 插件推薦】Input System 輸入大師,讓開發者重新定義控制邏輯!

一、前言
在遊戲開發中,良好的輸入系統是確保遊戲玩家與遊戲世界互動流暢的關鍵之一。長期以來,Unity 的舊版輸入系統InputManager 在處理輸入方面發揮了重要作用。然而,隨著遊戲開發技術的不斷發展和用戶需求的日益增加,Unity 推出了全新的輸入系統:Input System。

Unity 的Input System 是Unity 提供的新的輸入系統,相較於舊版的InputManager,它有以下優點:

靈活性和可設定性: Input System 提供了更靈活且可設定的輸入管理方案。你可以透過程式碼或透過視覺化工具來配置輸入,而不是像舊版的InputManager 那樣需要在編輯器中手動新增和管理輸入。

跨平台支援: Input System 提供了更好的跨平台支持,可以在不同平台上統一處理輸入,減少了針對不同平台的輸入處理程式碼的編寫。

輸入處理效能最佳化: Input System 的設計更有效率,能夠更好地管理輸入事件的處理,並降低了輸入處理的效能開銷,特別是在大量輸入事件的情況下。

多種輸入裝置支援: Input System 對多種輸入裝置(如鍵盤、滑鼠、手把、觸控螢幕等)提供了更好的支持,可以更方便地處理不同輸入裝置的輸入。

可擴充性: Input System 的設計更模組化且可擴展,可輕鬆擴展新的輸入裝置或自訂輸入處理邏輯,滿足不同專案的需求。

總的來說,Input System 是Unity 提供的更先進、更靈活、更有效率的輸入管理方案,能夠幫助開發者更方便地處理輸入,並提升遊戲的效能和跨平台相容性。

二、新舊版的鍵盤按鍵監聽對比
1.以監聽"A"鍵按下,抬起,按住為例
舊版:
Input.GetKeyDown(KeyCode.A);
 
Input.GetKeyUp(KeyCode.A);

Input.GetKey(KeyCode.A);
1
2
3
4
5
新版:
Keyboard.current.aKey.wasPressedThisFrame;
  
Keyboard.current.anyKey.wasReleasedThisFrame;

Keyboard.current.anyKey.isPressed;
1
2
3
4
5
2.新舊版的滑鼠左鍵監聽比較:
舊版:
Input.GetMouseButtonDown(0);

Input.GetMouseButtonUp(0);

Input.GetMouseButton(0);
1
2
3
4
5
新版:
Mouse.current.leftButton.wasPressedThisFrame;

Mouse.current.leftButton.wasReleasedThisFrame;

Mouse.current.leftButton.isPressed; 
1
2
3
4
5
3.滑鼠位置和滾輪的數據獲取
滑鼠位置對比
旧版:Input.mousePosition;

新版:Mouse.current.position;
1
2
3
滾輪對比
旧版: Input.GetAxis("Mouse ScrollWheel");

新版:Mouse.current.scroll.ReadValue(); 
1
2
3
三、安裝
導覽列-> Window -> Package Manager,選擇Unity Registry 在清單中找到Input System 點選Install 安裝


四、新舊輸入系統切換
Unity 預設會同時啟用舊版和新版輸入系統,你可以在Player settings 中(Edit -> Project Settings -> Player ->Active Input Handling) 找到對應的設定。可以隨時修改這裡的設置,這樣做還是會重新啟動編輯器。


五、使用視覺化編輯器來建立Input System映射
Project -> Create -> Input Actions

 

1、Action Map:行為映射表
一個Input Actions可以有多個Map。每個Map下面又有許多Action,可以批次控制Action啟用與停用。例如有一個UI Map,他包含選項的上,下,左,右,確定等功能,我們將這些功能綁定在方向鍵。另一個Car Map,他控制賽車的移動,綁定的同樣是方向鍵。為了避免功能衝突,我們可以再拉起UI面板的時候,整體禁用Car Map,關閉UI面的時候禁用UI Map,啟用Car Map。以及其他類似的操作。

切換不同的輸入系統
遊戲時候可以用gameplay系統
而退出遊戲時我們可以用UI輸入系統
就例如我們進遊戲選擇選單的時候用UI系統
我們玩遊戲的時候就用gameplay系統

代碼切換不同輸入系統

# 切换操作映射
public void SwitchActionMap(InputActionMap actionMap)
{
   parameter.inputSystem.Disable(); // 禁用当前的输入映射
   actionMap.Enable(); // 启用新的输入映射
}

# 调用
SwitchActionMap(parameter.inputSystem.Player); // 切换到游戏操作的输入映射
SwitchActionMap(parameter.inputSystem.UI);//切换为UI输入
1
2
3
4
5
6
7
8
9
10
2、Action:輸入行為資產
一個具體的輸入動作,例如按鍵按下、搖桿移動等。可以理解成自訂的輸入行為(動作)的集合。一個輸入動作可以由一種或多種輸入訊號組成。例如「前進」這個動作,可以被「W」鍵觸發,也可以被「↑」方向鍵觸發,甚至可以被手把的「↑」鍵觸發。

產生結束點選Edit asset 建立第一個Action Map 並將其命名為Player 並將Actions 清單產生的Action 重新命名為Fire 。


也可以綁定多個按鍵對應不同的操作設備,我這裡映射的第二個按鍵為滑鼠左鍵


3、Action Properties:操作屬性
3.1、Action Type:動作類型

動作可分為三種類型

Value(值):這是用來處理可以變化的數值,例如手把上的搖桿。它可以傳回連續的數值,範圍內的任意值都可以,例如從-1到1。這類動作適用於需要取得和處理變化的數位資料的場景。

Button(按鈕):這種類型的動作很簡單,只在乎按鈕是否被按下。它通常會傳回兩個值:按下(1)或抬起(0)。適用於處理單一的按鈕事件。

Pass Through(透傳):這種類型的動作是用來將輸入直接傳遞給另一個地方,不對其進行處理。它用於持續變化的輸入數據,例如滑桿的即時值。

3.2、Control Type:設定按鍵返回值的類型

以下是這些控制類型的簡要解釋:

Any(任意):

定義:表示控制器傳回任何類型的資料。
用途:用於處理不確定類型的數據,可根據實際情況解析為其他特定類型。
Analog(模擬):

定義:通常用於表示一個範圍內的連續數值。
用途:適合處理類比輸入設備的數據,如搖桿或滑塊,通常會傳回一個浮點數。
Axis(軸):

定義:表示一個連續的數值範圍,通常用來表示方向或力度。
用途:適合需要表示方向或位置的輸入設備,如遊戲手把的搖桿。
Bone(骨骼):

定義:用於表示骨骼動畫系統中的骨骼資料。
用途:常用於角色動畫中,表示骨骼的狀態或位置。
Delta(增量):

定義:表示與前一個影格相比的變化量。
用途:用於處理需要追蹤增量變化的輸入數據,如滑鼠的移動量。
Digital(數位):

定義:表示離散的狀態,通常是0和1。
用途:用於處理簡單的開關狀態,例如按鈕按下或釋放的狀態。
Double(雙精確度浮點數):

定義:表示一個雙精確度浮點數,精確度比普通浮點數更高。
用途:用於需要高精度數值的輸入數據,如精確的位置或速度數據。
Dpad(方向鍵):

定義:表示方向鍵的狀態,通常為一個離散的方向(上、下、左、右)。
用途:用於處理方向控制輸入,如遊戲手把上的方向鍵。
Eyes(眼睛):

定義:表示眼睛位置或方向的資料。
用途:用於眼動追蹤或虛擬實境中的眼睛追蹤。
Integer(整數):

定義:表示一個整數值。
用途:用於處理離散的、可計數的輸入數據,例如選擇的選項編號。
Pose(姿勢):

定義:表示物件的姿態或位置。
用途:常用於虛擬實境或擴增實境中,表示使用者或物件的姿態資料。
Quaternion(四元數):

定義:用於表示旋轉的四元數資料。
用途:常用於3D空間的物體旋轉,避免了歐拉角的萬向節死鎖問題。
Stick(搖桿):

定義:表示搖桿的輸入數據,通常為二維或三維向量。
用途:用於取得搖桿的位移數據,可以表示方向和力度。
Touch(觸摸):

定義:表示觸控輸入的資料。
用途:用於處理觸控螢幕或觸控板上的輸入,通常包括觸控點的位置和壓力。
Vector2(二維向量):

定義:表示一個二維座標的向量。
用途:用於處理需要兩個維度資料的輸入,例如2D遊戲中的位置或方向。
Vector3(三維向量):

定義:表示一個三維座標的向量。
用途:用於處理需要三個維度資料的輸入,例如3D空間中的位置或方向。
3.3、Initial State Check:初始狀態檢查

啟用Action時,Action綁定的Control可能已經具有非預設狀態,系統依序檢查所有被綁定到此Action的Control,並立即回應處於非預設狀態下的控制項。

補充:輸入系統將不同種類的輸入抽象化為Control。 Control表示輸入值的來源,例如,某個float值來自鍵盤上的某個按鍵,某個Vector2值來自滑鼠單幀的位移,某個Vector2值來自於手把上的搖桿。

3.4、Interactions:互動方式, 點擊,長按,雙擊等
所有的方式都會預設有三個事件Started、Performed、Canceled。舉一個明顯的例子,長按(手指按住1秒以上認為是長按):在按下去的瞬間觸發Started,在任意時間鬆開觸發Canceled,如果連續按壓時間達到1秒觸發Performed。

Hold:長按
需要保持按壓一段時間才算完成這個動作。就像上方舉得例子。

加完Hold 後,看一下它的兩個變數。如果預設值無法滿足你的需求,取消勾選Default 可自訂變數值。修改Hold Time 變數一般即可滿足需求

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。
1
2
3
4
5
6
7


Press:類似按鈕,
Press Only:在按下的时候触发Started和 Performed,在抬起的时候触发Canceled。              
Release Only:在按下的时候Started,在抬起的时候触发Canceled和Performed。
Press And Release:在按下的时候触发Started和 Performed,抬起的时候触发Canceled和Performed。 
1
2
3


Slow Tap:緩慢點擊
他與Hold的差異是,在達到最短按壓時間後不會立刻觸發Performed,而是在鬆開的瞬間觸發Performed。

Min Tap Duration按壓的最短時間。

 

Tap:點擊
可以看做只點擊一次的Multi Tap。選項在Multi Tap中也有講述


3.5、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。

4、Binding Properties:結合特性
4.1、Binding
選取目前未綁定的,在右側面板會有Binding、Interactions、Processors三個選項。

其中Interactions和Processor是針對目前Binding的特別設置,與Action功能一致。如果此處未進行設置,請使用上級的Interactions/Processor設定;如果進行了設置,以此處Interactions/Processor的設定為準。

Binding是此處的核心,它的作用是用來對輸入訊號進行綁定。輸入系統將Action與Control之間的連結抽象化為Binding。 Binding包含一條指向Control的控制項路徑,多個Binding可以指向同一個Control,一個Action可以包含多個Binding。當系統收到某個控制項輸入的資料時,會驅動所有綁定了該控制項的Action進行回應。

path
選取< No Binding > 給Fire Action 映射對應的按鍵(按鍵可以自訂,例如這裡映射的按鍵為滑鼠左鍵)


4.2、Composite 用於組合多個輸入綁定的方法
添加


Composite Type


2D Vector:複合輸入用於將兩個輸入軸(例如水平和垂直軸)組合成一個Vector2。這是常用的輸入類型,例如用來處理方向控制。它通常用於需要二維方向輸入的場景,例如控制角色移動或視角。
One Modifier:複合輸入允許你將一個主要輸入與一個修飾輸入組合起來。修飾輸入會影響主要輸入的行為。例如,你可以用它來實作一個動作需要按住某個修飾鍵的功能。例如實現按住滑鼠右鍵再移動才能控制相機視野旋轉功能
Two Modifiers:跟前面類似,不過可以多加1個綁定,用於需要兩個修飾鍵來影響主要輸入的場景。
1D Axis:複合輸入用於處理單一軸的輸入,通常是Single 類型的值。它可以用於簡單的軸輸入,例如遊戲中的一個方向鍵。
Button With One Modifier:複合輸入用於將一個主要按鈕輸入與一個修飾按鈕組合。這個複合輸入需要兩個按鈕的狀態:一個主按鈕和一個修飾按鈕。用法:用於需要組合兩個按鈕輸入的場景,例如在按下某個按鈕的同時按下另一個按鈕以觸發特殊動作。
Button With Two Modifiers:複合輸入類似Button With One Modifier,但需要兩個修飾按鈕配合一個主要按鈕。這意味著你需要同時按下三個按鈕(一個主要按鈕和兩個修飾按鈕)來觸發動作。用法:用於需要同時按下三個按鈕的複雜場景,例如執行複雜的操作或技能組合。

Mode 如何處理輸入數據
將輸入視為數位控制還是類比控制。

Analog: 處理類比輸入訊號,如遊戲控制器的搖桿或模擬觸控輸入。輸入值通常是浮點數,範圍在-1 到1 之間。可實現按手柄搖桿的力道控制移動速度,類似加速減速過程的效果。
Digital Normalized:處理數位輸入,但以歸一化形式輸出。這意味著輸入值會被標準化到-1、0 和1 之間。它用於處理需要歸一化的數位輸入,常見於輸入映射中的狀態表示。
Digital:處理數位輸入訊號,如按鈕按下或釋放。輸出值通常是布林值(按下為true,未按下為false),但在某些實作中,輸出可以表示為0 或1。

5、保存
完成上述操作後點選Save Asset 儲存目前映射表,這樣做可以綁定多個實體輸入得到的輸入值也只會影響同引用的Action 物件。


六、透過代碼監聽映射表中的按鍵
快速建立Input Actions映射
給玩家新增Player Input元件,點選建立新的輸入系統,產生之後就可以刪除Player Input元件了

會自動為我們建立好一些必備輸入參數,例如移動 程式

碼調用,點選自動產生程式碼


程式碼控制
建立測試腳本PlayerInput (命名可隨意),我們需要使用先前的InputActions映射
透過監聽started 和canceled 實現按鍵按下抬起操作。具體可參考下述代碼

using UnityEngine;
using UnityEngine.InputSystem;

/// <summary>
/// 玩家输入
/// </summary>
public class PlayerInput : MonoBehaviour
{
   public Vector2 MoveInput { get; private set; }// 用于存储移动输入的向量
   public Vector2 LookInput { get; private set; }// 用于存储视角输入的向量
   public bool RunIsPressed { get; private set; }
   public bool JumpIsPressed { get; private set; }
   private InputActions _input;

   private void OnEnable()
   {
       _input = new InputActions();
       _input.Player.Enable();

       _input.Player.Move.performed += SetMove;
       _input.Player.Move.canceled += SetMove;
       _input.Player.Look.performed += SetLook;
       _input.Player.Look.canceled += SetLook;
       _input.Player.Run.started += SetRun;
       _input.Player.Run.canceled += SetRun;
       _input.Player.Jump.started += SetJump;
       _input.Player.Jump.canceled += SetJump;
       _input.Player.Roller.performed += SetRoller;
       _input.Player.Roller.canceled += SetRoller;
   }

   private void OnDisable()
   {
       _input.Player.Move.performed -= SetMove;
       _input.Player.Move.canceled -= SetMove;
       _input.Player.Look.performed -= SetLook;
       _input.Player.Look.canceled -= SetLook;
       _input.Player.Run.started -= SetRun;
       _input.Player.Run.canceled -= SetRun;
       _input.Player.Jump.started -= SetJump;
       _input.Player.Jump.canceled -= SetJump;
       _input.Player.Roller.performed -= SetRoller;
       _input.Player.Roller.canceled -= SetRoller;
       _input.Player.Disable();  
   }

   
   private void SetMove(InputAction.CallbackContext context)
   {
       MoveInput = context.ReadValue<Vector2>();
   }

   private void SetLook(InputAction.CallbackContext context)
   {
       LookInput = context.ReadValue<Vector2>();
   }

   private void SetRun(InputAction.CallbackContext context)
   {
       RunIsPressed = context.started;
       // if (context.started)// 当用户按下键时触发
       // {
               // ChangeCameraWasPressedThisFrame = true;
       // } else if (context.performed) {// 按键持续按下
               // float holdDuration = (float)context.duration;
               // Debug.Log("按键持续时间: " + holdDuration);
       //}else if(context.canceled){// 当用户释放键时触发
               // ChangeCameraWasPressedThisFrame = false;
       // }
   }

   private void SetJump(InputAction.CallbackContext context)
   {
       JumpIsPressed = context.started;
   }

   private void SetRoller(InputAction.CallbackContext context)
   {
       Debug.Log(context.ReadValue<float>());
       
   }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
七、Input Debug
Input Debug視窗是一個非常好用的東西,開啟方式:

“Window→Analysis→Input Debugger” 
1


在這個視窗中,所有可以被辨識的輸入裝置都會被顯示在這。之前我們在綁定輸入按鈕的時候會不會有這麼一個疑惑,我怎麼知道這個按鈕對應哪個訊號。還有每個訊號的輸入值類型又是什麼樣子呢?

我們就以我的手柄為例,上圖中我已經選中了手柄,雙擊,打開詳細介面。

我們可以看到設備的詳細資訊。 Name就是在Unity InputSystem中對應的名稱;DisplayName是我手把上的文字,B就對應我手把的B;後邊還有訊號類型方便我們設定Type。此時按動手把還能透過value看到即時輸入值,螢幕下方還會即時列印,方便我們調試。爆贊!

例如我此時正在按B鍵,掰動搖桿,所有的輸入資訊都會在面板中展示出來,建議各位自己試試看。


八、重新綁定控制按鍵
參考:【unity小技巧】新輸入系統InputSystem重新綁定控制按鍵(最全最完美解決方案)

九、移動端支持
更好用的虛擬搖桿插件:待續

1.虛擬搖桿

虛擬搖桿input system已經幫我們做好了一個非常好的工具,模擬左側操作桿,只需要掛載On-Screen Stick腳本即可

運行效果,沒錯就是這麼簡單,甚至你都不需要修改程式碼


2、虛擬按鈕
繪製按鈕UI

模擬不同的按鈕

效果


區分不同設備的配置表(2024/07/02補充)
PC的按鍵勾選分類

手把的按鍵勾選分類

將不同的裝置按鍵綁定區分開

UI交互
InputSystem在UI上的應用
在創建canvas的同時
又創建了一個EventSystem
它原本是老版的輸入系統
但是我們升級完InputSystem
新版的輸入系統之後,它就會報錯

我們把它別級為新版的輸入系統
Actions Asset裡面
默認給我們創建一個DefaultInputActions,綁定的按鍵和UI事件是對應的

UI的輸入時間我們就用預設的就好了,原來的UI就不需要再增加任何東西


常見的輸入綁定
1、移動


2、跳躍輸入

綁定鍵盤按鈕

綁定手柄,如果有的話


3.滑鼠滾輪輸入
監聽滑鼠XY軸滾輪


獲取值

inputSystem.Player.Roller.ReadValue<Vector2>();
1
僅監聽滑鼠Y軸滾輪


獲取值

inputSystem.Player.Roller.ReadValue<float>();
1
結合Player Input控制輸入(2024/07/23補充)
這種方法因為在Update一直監聽輸入,性能肯定沒有前面的好,但是單單是輸入影響應該也不大,而且這種獲取輸入的方式真的很優雅,所以這裡還是分享一下,大家酌情選擇即可

 

也可以使用下面的方式來取得輸入

public class UserInput : MonoBehaviour
{
   // Singleton instance
   public static UserInput instance;

   // 移动输入向量
   public Vector2 MoveInput { get; private set; }
   // 跳跃输入标志位
   public bool JumpJustPressed { get; private set; }
   public bool JumpBeingHeld { get; private set; }
   public bool JumpReleased { get; private set; }
   // 攻击输入标志位
   public bool AttackInput { get; private set; }
   // 冲刺输入标志位
   public bool DashInput { get; private set; }
   // 菜单打开/关闭输入标志位
   public bool MenuopencloseInput { get; private set; }

   private PlayerInput _playerInput;
   private InputAction _moveAction;
   private InputAction _jumpAction;
   private InputAction _attackAction;
   private InputAction _dashAction;
   private InputAction _menuopenCloseAction;

   private void Awake()
   {
       // 单例模式实例化
       if (instance == null)
       {
           instance = this;
       }

       _playerInput = GetComponent<PlayerInput>();
       SetupInputActions();
   }

   private void Update()
   {
       // 每帧更新输入状态
       UpdateInputs();
   }

   private void SetupInputActions()
   {
       // 从PlayerInput组件初始化输入动作
       _moveAction = _playerInput.actions["Move"];
       _jumpAction = _playerInput.actions["Jump"];
       _attackAction = _playerInput.actions["Attack"];
       _dashAction = _playerInput.actions["Dash"];
       _menuopenCloseAction = _playerInput.actions["Menuopenclose"];
   }

   private void UpdateInputs()
   {
       // 更新特定的输入数值
       MoveInput = _moveAction.ReadValue<Vector2>(); // 读取移动输入值
       JumpJustPressed = _jumpAction.WasPressedThisFrame(); // 检测跳跃是否刚按下
       JumpBeingHeld = _jumpAction.IsPressed(); // 检测跳跃是否正在按住
       JumpReleased = _jumpAction.WasReleasedThisFrame(); // 检测跳跃是否刚释放
       AttackInput = _attackAction.WasPressedThisFrame(); // 检测攻击是否刚按下
       DashInput = _dashAction.WasPressedThisFrame(); // 检测冲刺是否刚按下
       MenuopencloseInput = _menuopenCloseAction.WasPressedThisFrame(); // 检测菜单打开/关闭是否刚按下
   }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
全域配置Default Deadzone Min死區(2024/08/28補充)
“Input System Default Deadzone Min” 通常指的是輸入系統中的預設死區最小值。它用於設定輸入設備(如游戲控制器)的最小響應閾值,即在這個範圍內的微小輸入變化不會被系統識別,以避免過於敏感的反應。這有助於提供更平滑的輸入體驗。跟前面的Stick Deadzone


監聽鈕按下並抬起,並取得按鍵的長按時間
public class NewBehaviourScript : MonoBehaviour
{
   private InputSystem _input;
   private float _holdStartTime; // 按键开始按下的时间
   
    private void OnEnable()
   {
       _input = new InputSystem();
       _input.Player.Enable();

       _input.Player.Fire.started  += SetFire;
       _input.Player.Fire.canceled += SetFire;
   }

   private void OnDisable()
   {
       _input.Player.Fire.started  -= SetFire;
       _input.Player.Fire.canceled -= SetFire;
       _input.Player.Disable();  
   }

    private void SetFire(InputAction.CallbackContext context)
   {
       if (context.started)
       {
           // 按键开始按下
           _holdStartTime = Time.time; // 记录开始时间
           Debug.Log("按键开始: " + _holdStartTime);
       }
       else if(context.canceled)
       {
           // 按键松开
           float holdDuration = Time.time - _holdStartTime; // 计算持续时间
           Debug.Log("按键释放: " + Time.time + ", 持续时间: " + holdDuration);
       }
   }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
透過介面的方式監聽按鈕(2024/10/15補充)
using UnityEngine;
using UnityEngine.InputSystem;

public class NewBehaviourScript : MonoBehaviour, InputSystem.IPlayerActions
{
   private InputSystem _input;

   private void OnEnable()
   {
       _input = new InputSystem();
       _input.Player.Enable();
       _input.Player.SetCallbacks(this);
   }

   private void OnDisable()
   {
       _input.Player.Disable();  
   }

   public void OnMove(InputAction.CallbackContext context)
   {
       //一般只用到后三个
       switch (context.phase)
       {
           case InputActionPhase.Disabled://被禁用
               Debug.Log("按键被禁用");
               break;
           case InputActionPhase.Waiting://处于等待
               Debug.Log("按键处于等待");
               break;
           case InputActionPhase.Started://按键开始按下的那一刻
               Debug.Log("按键开始按下" );
               break;
           case InputActionPhase.Performed://按键持续按下
               Debug.Log("按键持续按下" );
               break;
           case InputActionPhase.Canceled://按键松开
               Debug.Log("按键松开");
               break;
       }

   }

   public void OnLook(InputAction.CallbackContext context)
   {

   }

   public void OnFire(InputAction.CallbackContext context)
   {

   }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
注意,如果按鈕一直按住一個方向,Performed和Started效果其實是一樣的,但如果你在持續的移動過程中變換方向,Performed在輸入操作期間就會持續觸發。這個算是知識補充,之前沒有說過。

參考
【文件】https://docs.unity3d.com/ Packages /[email protected]/manual/Actions.html
【文章】https://developer.unity.cn/projects/6602debfedbc2a001dcd1a82
【文章】https:/cn /www.bilibili.com/read/cv22947460/
————————————————

                           版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                       
原文链接:https://blog.csdn.net/qq_36303853/article/details/138794797

 

 

 

本文原創(或整理)於亞洲電玩通,未經作者與本站同意不得隨意引用、轉載、改編或截錄。

特約作家簡介

X
A
Y
B
JamXu的頭像
JamXu
10年遊戲研發
20年遊戲玩家
30年遊戲人生

經中華網龍遊戲 企劃進入遊戲圈,然後被雷打到去學 程式前後端又學了點 設計再 帶帶幾個研發團隊,見證了 3D 渲染技術及遊戲引擎互相進步,也見證了研發代理的更迭與博弈遊戲的興起,再毅然研究起 SEO 網路行銷與 社群廣告投放,深信自研自賣才是最大贏家,期望能為台灣研發重回輝煌時光貢獻一點力量。如果你也有 遊戲夢,歡迎交流認識。


支持贊助 / DONATE

 

亞洲電玩通只是很小的力量,但仍希望為復甦台灣遊戲研發貢獻一點動能,如果您喜歡亞洲電玩通的文章,或是覺得它們對您有幫助,歡迎給予一些支持鼓勵,不論是按讚追蹤或是贊助,讓亞洲電玩通持續產出,感謝。

亞洲電玩通AsiaGameMaster - Steam 遊戲鑑賞家
亞洲電玩通AsiaGameMaster - FB 粉絲專頁
亞洲電玩通AsiaGameMaster - IG 粉絲專頁
亞洲電玩通AsiaGameMaster - Twitter
亞洲電玩通AsiaGameMaster - Yoytube 粉絲專頁
亞洲電玩通AsiaGameMaster - Tiktok

BTC

亞洲電玩通AsiaGameMaster - BTC 鏈贊助地址

bc1psp8nnerlepv56nyfha6mqwnp3yr7qqjdw44c6qt5lx5r2urma7fqykxvwj

 

ETH

亞洲電玩通AsiaGameMaster - ETH 鏈贊助地址

0xB2231557bc418201922DD7C2673ec97E67E35F83

 

TRON

tron-qrcode亞洲電玩通AsiaGameMaster - TRON 鏈贊助地址

TAomNj4L6vMJuaJmbWUdmT1uAWYPf9vDjp

延伸閱讀