推薦使用的Unity插件(InputSystem)

本文將提供更簡潔的步驟和常見問題解決。

一、極簡入門步驟:

  1. 安裝:Package Manager中安裝Input System(確保Unity版本在2019.4+)

  2. 創建Input Actions

  • 在Project窗口右鍵 -> Create -> Input Actions

  • 雙擊打開編輯器,添加Action Map(例如"Player")

  • 在Action Map中添加Action(例如"Move"、“Jump”)

  • 為每個Action添加綁定,例如:

  • “Move”:綁定到/leftStick 和 /wasd

  • “Jump”:綁定到/space 和 /buttonSouth

  1. 生成C#類
  • 在Input Actions資源的Inspector中,勾選"Generate C# Class"

  • 點擊"Apply",生成一個與資源同名的C#腳本

  1. 在代碼中使用

using UnityEngine;using UnityEngine.InputSystem;public class Example : MonoBehaviour{private PlayerInputActions inputActions;void Awake(){inputActions = new PlayerInputActions();inputActions.Player.Enable();}void Update(){Vector2 move = inputActions.Player.Move.ReadValue<Vector2>();// 使用move移動角色}void OnJumpPerformed(InputAction.CallbackContext context){// 跳躍}void OnEnable(){inputActions.Player.Jump.performed += OnJumpPerformed;}void OnDisable(){inputActions.Player.Jump.performed -= OnJumpPerformed;}}
  1. 使用PlayerInput組件(可選)
  • 將Input Actions資源拖到PlayerInput組件的"Actions"屬性

  • 選擇行為模式(如"Invoke Unity Events")并配置事件

常見問題及解決:

  1. 輸入不生效
  • 檢查是否啟用了Action Map:inputActions.Player.Enable();

  • 檢查Project Settings中Active Input Handling是否選擇了"Input System Package"

  • 重啟Unity(有時安裝后需要重啟)

  1. 如何在多個腳本中使用同一個輸入
  • 推薦創建一個單例管理輸入,或者將Input Actions實例作為參數傳遞給其他腳本
  1. 如何實現雙人游戲
  • 使用PlayerInputManager組件

  • 在場景中添加一個空物體,掛載PlayerInputManager

  • 設置玩家預制體(Prefab),在預制體上添加PlayerInput組件并配置Input Actions

  • 通過PlayerInputManager動態創建玩家實例

  1. 如何實現按鍵重綁定

// 找到要重綁定的Actionvar action = inputActions.FindAction("Player/Jump");// 開始重綁定var rebindOperation = action.PerformInteractiveRebinding().WithControlsExcluding("<Mouse>/press").OnMatchWaitForAnother(0.1f).Start();
  1. 如何切換操作方案(如行走和駕駛)
  • 使用不同的Action Map

  • 切換時禁用當前Action Map,啟用另一個:


inputActions.Player.Disable();inputActions.Vehicle.Enable();
  1. 如何獲取當前設備類型(判斷是手柄還是鍵盤)

// 通過PlayerInput組件PlayerInput playerInput = GetComponent<PlayerInput>();string deviceType = playerInput.currentControlScheme;// 或者監聽設備變化playerInput.onControlsChanged += (PlayerInput input) =>{Debug.Log(input.currentControlScheme);};

調試技巧:

  • 打開菜單:Window -> Analysis -> Input Debugger,查看實時輸入

  • 在代碼中監聽輸入事件,打印日志

希望這個快速指南能解決你的問題!如果遇到特定問題,請提供更多細節。

二、Unity Input System 全面使用指南

Unity 的新輸入系統提供了更強大、靈活的輸入處理方式,下面我將通過一個完整的示例項目展示如何使用它。

安裝與設置

  1. 安裝 Input System

    • 打開 Package Manager (Window > Package Manager)
    • 選擇 “Unity Registry”
    • 找到 “Input System” 并安裝
  2. 啟用新輸入系統

    • 前往 Edit > Project Settings > Player
    • 在 “Other Settings” 部分:
      • Active Input Handling: 選擇 “Input System Package (New)”

創建輸入配置

步驟 1:創建 Input Actions Asset

  1. 在 Project 窗口右鍵 > Create > Input Actions
  2. 命名為 “PlayerControls”

步驟 2:配置輸入動作

雙擊打開 PlayerControls 進行編輯:

Action MapActionBindingControl Path
PlayerMove2D VectorWASD / Left Stick
PlayerJumpButtonSpace / Gamepad South
PlayerLook2D VectorMouse Delta / Right Stick
PlayerFireButtonMouse Left / Gamepad East
UINavigate2D VectorArrow Keys / Left Stick
UISubmitButtonEnter / Gamepad South

代碼實現

基礎移動控制器

using UnityEngine;
using UnityEngine.InputSystem;[RequireComponent(typeof(CharacterController))]
public class PlayerController : MonoBehaviour
{[Header("Movement Settings")][SerializeField] private float moveSpeed = 5f;[SerializeField] private float jumpHeight = 2f;[SerializeField] private float gravity = -9.81f;[SerializeField] private float rotationSpeed = 10f;[Header("Camera")][SerializeField] private Transform cameraTransform;private CharacterController controller;private PlayerInput playerInput;private InputAction moveAction;private InputAction jumpAction;private InputAction lookAction;private Vector3 velocity;private bool isGrounded;private float rotationX = 0f;private void Awake(){controller = GetComponent<CharacterController>();playerInput = GetComponent<PlayerInput>();// 獲取輸入動作moveAction = playerInput.actions["Move"];jumpAction = playerInput.actions["Jump"];lookAction = playerInput.actions["Look"];// 鎖定鼠標Cursor.lockState = CursorLockMode.Locked;}private void Update(){// 地面檢測isGrounded = controller.isGrounded;if (isGrounded && velocity.y < 0){velocity.y = -2f;}// 移動Vector2 moveInput = moveAction.ReadValue<Vector2>();Vector3 moveDirection = new Vector3(moveInput.x, 0, moveInput.y);moveDirection = Quaternion.Euler(0, cameraTransform.eulerAngles.y, 0) * moveDirection;controller.Move(moveDirection * moveSpeed * Time.deltaTime);// 跳躍if (jumpAction.triggered && isGrounded){velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);}// 重力velocity.y += gravity * Time.deltaTime;controller.Move(velocity * Time.deltaTime);// 視角旋轉Vector2 lookInput = lookAction.ReadValue<Vector2>();float mouseX = lookInput.x * rotationSpeed * Time.deltaTime;float mouseY = lookInput.y * rotationSpeed * Time.deltaTime;rotationX -= mouseY;rotationX = Mathf.Clamp(rotationX, -90f, 90f);cameraTransform.localRotation = Quaternion.Euler(rotationX, 0, 0);transform.Rotate(Vector3.up * mouseX);}
}

UI 輸入處理

using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;public class UIController : MonoBehaviour
{[SerializeField] private Button startButton;[SerializeField] private Slider volumeSlider;private PlayerInput playerInput;private InputAction navigateAction;private InputAction submitAction;private void Awake(){playerInput = GetComponent<PlayerInput>();// 切換到UI輸入映射playerInput.SwitchCurrentActionMap("UI");// 獲取輸入動作navigateAction = playerInput.actions["Navigate"];submitAction = playerInput.actions["Submit"];// 注冊輸入事件navigateAction.performed += OnNavigate;submitAction.performed += OnSubmit;}private void OnNavigate(InputAction.CallbackContext context){Vector2 direction = context.ReadValue<Vector2>();// 簡單的UI導航邏輯if (Mathf.Abs(direction.y) > 0.5f){if (direction.y > 0) volumeSlider.Select();else startButton.Select();}}private void OnSubmit(InputAction.CallbackContext context){// 模擬按鈕點擊if (startButton.gameObject == UnityEngine.EventSystems.EventSystem.current.currentSelectedGameObject){startButton.onClick.Invoke();}}private void OnDestroy(){navigateAction.performed -= OnNavigate;submitAction.performed -= OnSubmit;}
}

高級功能實現

輸入重綁定系統

using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;public class RebindManager : MonoBehaviour
{[SerializeField] private InputActionReference targetAction;[SerializeField] private Text bindingText;[SerializeField] private GameObject waitingPanel;private InputActionRebindingExtensions.RebindingOperation rebindingOperation;public void StartRebinding(){waitingPanel.SetActive(true);bindingText.text = "Press any key...";// 取消當前綁定targetAction.action.Disable();// 開始重綁定rebindingOperation = targetAction.action.PerformInteractiveRebinding().WithControlsExcluding("<Mouse>/position").WithControlsExcluding("<Mouse>/delta").WithControlsExcluding("<Gamepad>/Start").OnMatchWaitForAnother(0.1f).OnComplete(operation => RebindComplete()).Start();}private void RebindComplete(){// 保存新綁定string rebinds = rebindingOperation.action.SaveBindingOverridesAsJson();PlayerPrefs.SetString("rebinds", rebinds);// 更新UI顯示bindingText.text = InputControlPath.ToHumanReadableString(targetAction.action.bindings[0].effectivePath,InputControlPath.HumanReadableStringOptions.OmitDevice);// 清理操作rebindingOperation.Dispose();waitingPanel.SetActive(false);targetAction.action.Enable();}private void OnEnable(){// 加載保存的重綁定if (PlayerPrefs.HasKey("rebinds")){string rebinds = PlayerPrefs.GetString("rebinds");targetAction.action.LoadBindingOverridesFromJson(rebinds);}// 初始化顯示bindingText.text = InputControlPath.ToHumanReadableString(targetAction.action.bindings[0].effectivePath,InputControlPath.HumanReadableStringOptions.OmitDevice);}
}

設備檢測與切換

using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;public class DeviceDisplay : MonoBehaviour
{[SerializeField] private Text deviceText;[SerializeField] private Image keyboardIcon;[SerializeField] private Image gamepadIcon;private PlayerInput playerInput;private void Awake(){playerInput = FindObjectOfType<PlayerInput>();playerInput.onControlsChanged += OnControlsChanged;UpdateDeviceDisplay();}private void OnControlsChanged(PlayerInput input){UpdateDeviceDisplay();}private void UpdateDeviceDisplay(){string deviceName = "Unknown";if (playerInput.currentControlScheme == "KeyboardMouse"){deviceName = "Keyboard & Mouse";keyboardIcon.gameObject.SetActive(true);gamepadIcon.gameObject.SetActive(false);}else if (playerInput.currentControlScheme == "Gamepad"){deviceName = "Gamepad";keyboardIcon.gameObject.SetActive(false);gamepadIcon.gameObject.SetActive(true);}deviceText.text = $"Current Device: {deviceName}";}private void OnDestroy(){if (playerInput != null){playerInput.onControlsChanged -= OnControlsChanged;}}
}

最佳實踐與技巧

  1. 輸入處理模式選擇

    • 對于簡單項目:使用 Invoke Unity Events 模式
    • 對于復雜項目:使用 Invoke C# Events 或直接訪問輸入動作
  2. 輸入動作組織

    • 按功能分組(Player、UI、Vehicle等)
    • 為常用操作設置復合綁定(如WASD綁定為2D向量)
  3. 多玩家輸入

    // 在玩家加入時
    public void OnPlayerJoined(PlayerInput playerInput)
    {// 為每個玩家設置不同的輸入設備if (playerInput.playerIndex == 0){playerInput.SwitchCurrentControlScheme("KeyboardMouse", Keyboard.current);}else{playerInput.SwitchCurrentControlScheme("Gamepad", Gamepad.current);}
    }
    
  4. 輸入處理優化

    • 使用 InputAction.CallbackContext 代替每幀檢查
    • 在不需要時禁用輸入動作以節省資源
  5. 移動設備支持

    • 使用 Touchscreen 輸入
    • 添加虛擬搖桿和按鈕
    // 在Input Actions中創建觸摸輸入
    public void SetupTouchControls()
    {// 添加觸摸輸入動作var touchAction = new InputAction("TouchPosition", binding: "<Touchscreen>/position");touchAction.Enable();// 添加點擊動作var tapAction = new InputAction("PrimaryTouch", binding: "<Touchscreen>/primaryTouch/tap");tapAction.Enable();
    }
    

調試技巧

  1. 使用 Input Debugger:

    • Window > Analysis > Input Debugger
    • 實時查看所有輸入設備狀態
  2. 在編輯器中模擬設備:

    • 打開 Input Debugger
    • 點擊 “Add Device” 添加虛擬設備
    • 使用虛擬設備測試輸入
  3. 記錄輸入事件:

    private void OnEnable()
    {InputSystem.onEvent += OnInputEvent;
    }private void OnDisable()
    {InputSystem.onEvent -= OnInputEvent;
    }private void OnInputEvent(InputEventPtr eventPtr, InputDevice device)
    {// 記錄輸入事件Debug.Log($"Input event from {device.name}");
    }
    

這個全面的指南覆蓋了Unity Input System的核心功能和使用方法。根據你的項目需求選擇合適的實現方式,并記得在復雜項目中合理組織輸入動作和綁定。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/909824.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/909824.shtml
英文地址,請注明出處:http://en.pswp.cn/news/909824.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

清理 Docker 容器日志文件方法

操作總結與問題解析 一、操作目的與背景 用戶旨在清理 Docker 容器日志文件以釋放服務器存儲空間,主要通過以下命令組合完成操作: 查看容器日志空間占用清空指定容器的日志文件驗證容器運行狀態與日志清理效果二、關鍵命令與輸出解析 1. 查看 Docker 容器日志空間占用 du…

圖片壓縮工具 | 按指定高度垂直切割圖片

OPEN-IMAGE-TINY&#xff0c;一個基于 Electron VUE3 的圖片壓縮工具&#xff0c;項目開源地址&#xff1a;https://github.com/0604hx/open-image-tiny ?? 需求描述 在上一篇文章一段代碼利用 snapdom 將 CSDN 博文轉化為長圖片&#xff08;PNG/JPG/PDF&#xff09;中&…

山東大學軟件學院創新項目實訓開發日志——第十七周(二)

目錄 1.優化前端日歷頁面顯示&#xff0c;增加鼠標懸停顯示當日會議基本信息的效果。 2.優化會議計劃生成與會議PPT生成功能&#xff0c;使得能夠加載多頁docx文件與PDF文件 3.優化了會議PPT生成功能&#xff0c;使得可以上傳多個文件并根據多個文件生成會議PPT 4.修改了識…

Ubuntu 使用kubeadm部署k8s系統組件反復重啟的問題

系統&#xff1a;Ubuntu 24.04 LTS 問題現象&#xff1a;kubeadm init 后系統組件proxy、apiserver、etcd等頻繁掛掉重啟 問題原因&#xff1a;cgroup配置問題 解決方法&#xff1a; 編輯系統cgroup默認配置文件 sudo nano /etc/default/grub 將GRUB_CMDLINE_LINUX_DEFAU…

Oracle獲取執行計劃之EXPLAIN PLAN 技術詳解

#Oracle #執行計劃 #EXPLAIN PLAN 一、引言 在Oracle數據庫性能優化中&#xff0c;?執行計劃&#xff08;Execution Plan&#xff09;?是理解SQL語句如何被數據庫處理的關鍵工具。EXPLAIN PLAN是Oracle提供的一種靜態分析SQL執行路徑的方法&#xff0c;它通過生成邏輯執行…

【論文閱讀】Qwen2.5-VL Technical Report

Arxiv:https://arxiv.org/abs/2502.13923 Source code:https://github.com/QwenLM/Qwen2.5-VL Author’s Institution&#xff1a;Alibaba 背景 多模態大模型 多模態大模型MultiModal Large Language Models (MM-LLMs) 的發展可以通過一篇綜述了解&#xff1a;MM-LLMs: Re…

vue中computed和watch區別

在 Vue 中&#xff0c;computed 和 watch 都是用來響應式地處理數據變化的工具&#xff0c;但它們的用途和行為有明顯區別。 &#x1f50d; 一句話總結 computed&#xff1a;用于聲明式計算屬性&#xff0c;有緩存。 watch&#xff1a;用于監聽響應式數據的變化并執行副作用邏…

大語言模型:提示詞決定自我反思效果: “檢查回答是否錯誤” “驗證回答是否正確”

大語言模型(LLMs)自我反思的結果很容易受提示詞構造的影響 大型語言模型(LLMs)展現出令人印象深刻的零樣本和少樣本推理能力。有人提出,這些能力可以通過自我反思來提升,即讓大型語言模型反思自己的輸出,以識別和糾正初始回答中的錯誤。然而,盡管有一些證據表明自我反…

【iReport】實際開發中,解決iReport中打印圖片不顯示問題

ireport 中增加圖片&#xff0c;添加上屬性&#xff0c;但是運行時報錯如下&#xff0c;是屬性logoPath沒有聲明到map中 1. Parameter not found : logoPath net.sf.jasperreports.engine.design.JRValidationException: Report design not valid : 1. Parameter not fo…

【MySQL進階】常用MySQL程序

目錄 一. mysqlcheck——表維護程序 1.1.作用 1.2 注意事項 1.3 使用方法 1.4 常用選項 1.5 mysqlcheck的特殊使用 二. mysqldump——數據庫備份程序 2.1.作用 2.2 注意事項 2.3 使用方法 2.4 常用選項 三. mysqladmin——MySQL 服務器管理程序 3.1.作用 3.2 使用…

EMQX高效存儲消息到MySQL指南

配置 EMQX 存儲消息到 MySQL EMQX 可以通過規則引擎和數據橋接功能將消息和事件存儲到 MySQL 數據庫。以下是具體實現方法&#xff1a; 創建 MySQL 數據表 在 MySQL 中創建用于存儲消息的表結構&#xff1a; CREATE TABLE mqtt_messages (id int(11) NOT NULL AUTO_INCREME…

springboot項目,利用docker打包部署

Windows WSL2 Docker Desktop 部署 SpringBoot 項目指南 &#xff08;沒有安裝docker的&#xff0c;如果是windows家庭中文版的&#xff0c;可以看我上一篇帖子&#xff1a;windows家庭版安裝docker和redis-CSDN博客&#xff09; 本教程將說明如何在 Windows 系統 下&#…

MO+內核32位普冉單片機PY32F003開發板

PY32F003開發板是基于普冉半導體PY32F003微控制器設計的低成本入門級開發工具&#xff0c; PY32F003系列微控制器采用高性能的 32 位ARM Cortex-M0內核&#xff0c;寬電壓工作范圍的 MCU。嵌入高達32Kbytes flash 和 4Kbytes SRAM 存儲器&#xff0c;最高工作頻率 32MHz。PY32…

MySql 用存儲過程刪除所有用戶表

用拼接語句總是會出問題 -- 1. 禁用外鍵約束&#xff08;防止級聯刪除失敗&#xff09;[1]() SET SESSION FOREIGN_KEY_CHECKS 0; -- 2. 生成并執行刪除語句&#xff08;替換 your_database_name&#xff09; SELECT CONCAT(DROP TABLE IF EXISTS , TABLE_NAME, ;) -- 預覽語…

Java八股文——MySQL「鎖篇」

講一下MySQL里有哪些鎖&#xff1f; 面試官您好&#xff0c;MySQL中的鎖機制非常豐富&#xff0c;它是保證數據一致性和并發安全的核心。我通常會從鎖的粒度&#xff08;加鎖范圍&#xff09; 和鎖的模式&#xff08;功能&#xff09; 這兩個維度來理解它們。 第一維度&#…

B站精品課程

【Python并發編程】線程&#xff0c;進程&#xff0c;協程&#xff0c;線程安全&#xff0c;多線程&#xff0c;死鎖&#xff0c;線程池等與案例解析&#xff0c;從入門到精通 https://www.bilibili.com/video/BV1EfdcYmEff/?spm_id_from333.337.search-card.all.click&v…

# ubuntu中安裝使用五筆輸入法

先 清理舊輸入法并重新安裝 fcitx5 五筆輸入法&#x1f447; &#x1f4e6; 第一步&#xff1a;清理舊的 Fcitx5 及相關輸入法組件 sudo apt purge fcitx* mozc* ibus* -y sudo apt autoremove --purge -y&#x1f4dd; 說明&#xff1a; fcitx* 會清除舊版本 Fcitx/Fcitx5。…

LSM樹與B+樹優缺點分析

1. LSM樹優化了順序寫&#xff0c;因此寫性能很好&#xff0c;但在查詢上&#xff1a; 需要從Level 0到Level n一直順序查下去。極端情況是LSM樹中不存在該數據&#xff0c;則需要遍歷L0->Ln&#xff0c;最后返回空集。 解決方法是用布隆過濾器優化查詢。 2. B樹范圍查詢性…

【成都魚住未來身份證】 身份證讀取與解析———未來之窗行業應用跨平臺架構——智能編程——仙盟創夢IDE

讀取身份證開發配置 function readerid魚住未來科技(){const webUrl http:// "127.0.0.1:30004" /api/info$.ajax({url: webUrl,type: GET,dataType: json,success: function (result) {// processContent.text(web api接口&#xff1a; webUrl 讀取身份證信息…

開啟并連接redis以及端口占用問題

開啟命令行 redis-server.exe redis.windows.conf 端口占用問題 查看端口&#xff1a; 輸入命令行&#xff1a; netstat -ano | findstr :6379 找到并停止pid號&#xff1a; 這個要用到cmd管理員身份打開 taskkill /f /pid 你的端口號 重新開啟就行了 再用另一個cmd進行連…