一、前言
在遊戲開發中,良好的輸入系統是確保遊戲玩家與遊戲世界互動流暢的關鍵之一。長期以來,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
本文原創(或整理)於亞洲電玩通,未經作者與本站同意不得隨意引用、轉載、改編或截錄。
特約作家簡介
支持贊助 / DONATE
亞洲電玩通只是很小的力量,但仍希望為復甦台灣遊戲研發貢獻一點動能,如果您喜歡亞洲電玩通的文章,或是覺得它們對您有幫助,歡迎給予一些支持鼓勵,不論是按讚追蹤或是贊助,讓亞洲電玩通持續產出,感謝。
BTC |
![]() |
bc1psp8nnerlepv56nyfha6mqwnp3yr7qqjdw44c6qt5lx5r2urma7fqykxvwj |
|
ETH |
![]() |
0xB2231557bc418201922DD7C2673ec97E67E35F83 |
|
TRON |
![]() |
TAomNj4L6vMJuaJmbWUdmT1uAWYPf9vDjp |








