本文将提供更简洁的步骤和常见问题解决。

一、极简入门步骤:

  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进行连…