首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

【推荐100个unity插件之18】Unity 新版输入系统Input System的基础使用

  • 25-03-02 10:22
  • 3787
  • 10530
blog.csdn.net

文章目录

  • 前言
  • 安装
  • 新旧输入系统切换
  • 基础使用
    • 快速监听某个按键按下抬起操作
    • 使用可视化编辑器来建立映射
      • Action Map
      • Action
    • 通过代码监听映射表中的按键
      • 测试效果
  • 实战
    • 快速创建Input Actions映射
    • 移动
    • 跳跃
  • 移动端支持
    • 虚拟摇杆
    • 虚拟按钮
  • 区分不同设备的配置表(2024/07/02补充)
  • 不同的输入系统
  • UI交互
    • InputSystem在UI上的应用
  • 鼠标滚轮滚动事件
  • 参考
  • 完结

注意: 新的输入法系统需要 Unity 2019.4+ 和 .NET 4 运行时。它不适用于 .NET 3.5 的项目。

前言

在游戏开发中,良好的输入系统是确保游戏玩家与游戏世界交互流畅的关键之一。长期以来,Unity 的老版输入系统 InputManager 在处理输入方面发挥了重要作用。然而,随着游戏开发技术的不断发展和用户需求的日益增加,Unity 推出了一种全新的输入系统:Input System。

Unity 的 Input System 是 Unity 提供的一种新的输入系统,相较于旧版的 InputManager,它具有以下优点:

  1. 灵活性和可配置性: Input System 提供了更灵活和可配置的输入管理方案。你可以通过代码或者通过可视化工具来配置输入,而不是像旧版的 InputManager 那样需要在编辑器中手动添加和管理输入。

  2. 跨平台支持: Input System 提供了更好的跨平台支持,可以在不同平台上统一处理输入,减少了针对不同平台的输入处理代码的编写。

  3. 输入处理性能优化: Input System 的设计更加高效,能够更好地管理输入事件的处理,降低了输入处理的性能开销,特别是在大量输入事件的情况下。

  4. 多种输入设备支持: Input System 对多种输入设备(如键盘、鼠标、手柄、触摸屏等)提供了更好的支持,可以更方便地处理不同输入设备的输入。

  5. 可扩展性: Input System 的设计更加模块化和可扩展,可以方便地扩展新的输入设备或者自定义输入处理逻辑,满足不同项目的需求。

总的来说,Input System 是 Unity 提供的一种更先进、更灵活、更高效的输入管理方案,能够帮助开发者更方便地处理输入,并提升游戏的性能和跨平台兼容性。

安装

导航栏 -> Window -> Package Manager,选择 Unity Registry 在列表中找到 Input System 点击 Install 安装
在这里插入图片描述

新旧输入系统切换

Unity 默认会同时启用旧版和新版输入系统,你可以在 Player settings 中(Edit -> Project Settings -> Player ->Active Input Handling) 找到相应的设置。可以随时修改这里的设置,这样做依然会重启编辑器。
在这里插入图片描述

基础使用

快速监听某个按键按下抬起操作

void Update()  
{  
    // 检查空格键是否在这个帧被按下  
    if (Keyboard.current.spaceKey.wasPressedThisFrame)  
    {        
        Debug.Log("Space key was pressed");  
    }   
    // 检查空格键是否在这个帧被释放  
    if (Keyboard.current.spaceKey.wasReleasedThisFrame)  
    {        
        Debug.Log("Space key was released");  
    }   
    // 检查左鼠标键是否在这个帧被按下  
    if (Mouse.current.leftButton.wasPressedThisFrame)  
    {        
        Debug.Log("Left mouse button was pressed");  
    }  
    // 检查左鼠标键是否在这个帧被释放  
    if (Mouse.current.leftButton.wasReleasedThisFrame)  
    {        
        Debug.Log("Left mouse button was released");  
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

使用可视化编辑器来建立映射

Project -> Create -> Input Actions
在这里插入图片描述
新建 Input Actions 给其命名(名称无所谓),我这里命名为 Test Input Controls 完成后,选中该文件勾选 Generate C# Class点击 Apply 后 Unity 会为我们生成一个 Action 的包装类,方便后续在代码中引用。
在这里插入图片描述

Action Map

可以理解为一个组织和管理输入动作的一种方式。通过将相关的输入动作放在同一个Action Map中,可以更好地管理输入逻辑。例如,可以将所有与玩家移动相关的输入动作放在一个叫做"Movement"的Action Map中。

Action

一个具体的输入动作,比如按键按下、摇杆移动等。

生成结束点击 Edit asset 创建第一个 Action Map 并将其命名为 Player 并将 Actions 列表生成的 Action 重命名为 Fire 。
在这里插入图片描述
选中 < No Binding > 给 Fire Action 映射对应的按键(按键可以自定义,笔者映射的按键为键盘的 K 键)
在这里插入图片描述
也可以绑定多个按键对应不同的操作设备,我这里映射的第二个按键为鼠标左键
在这里插入图片描述
在这里插入图片描述
完成上述操作后点击 Save Asset 保存当前映射表,这样做可以绑定多个物理输入得到的输入值也只会影响同引用的 Action 对象。
在这里插入图片描述

通过代码监听映射表中的按键

创建测试脚本 TestInputSystem (命名可随意),我们需要使用之前的 TestInputControls ,通过监听 started 和 canceled 实现按键按下抬起操作。具体可参考下述代码

// 输入控制类的实例  
private TestInputControls InputControls;  

void OnEnable()  
{  
    InputControls = new TestInputControls(); // 创建输入控制实例  
    InputControls.Player.Fire.started += OnFireDown; // 注册开火开始动作的回调  
    InputControls.Player.Fire.canceled += OnFireUp; // 注册开火结束动作的回调  
    InputControls.Enable(); // 启用输入控制  
}  

//当开火动作被触发时调用此方法。  
private void OnFireDown(InputAction.CallbackContext Obj)  
{  
	Debug.Log("Jump!" + Obj.phase);//输出按下类型 started canceled performed
    Debug.Log($"Fire Down | KeyName:{Obj.control.name}"); // 输出"Fire Down"到控制台 
}

//当开火动作释放时调用此方法。  
private void OnFireUp(InputAction.CallbackContext Obj)  
{  
    Debug.Log($"Fire Up | KeyName:{Obj.control.name}"); // 输出"Fire Up"到控制台 
}

//主要用于移除输入动作的回调函数,并禁用输入控制。  
private void OnDisable()  
{  
    InputControls.Player.Fire.started -= OnFireDown; // 移除开火开始事件的监听  
    InputControls.Player.Fire.canceled -= OnFireUp; // 移除开火结束事件的监听 
    InputControls.Disable(); // 禁用输入控制  
}
  • 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

测试效果

可以看到,我们使用一套代码就可以同时监听键盘和鼠标的输入
在这里插入图片描述
按下抬起有了,要想实现长按也很简单。选中 TestInputControls 点击 Edit asset 在 Action Properties 一栏点击 Interactions 后方的+号添加 Hold

Hold:按下并按住至少设定的持续时间(默认为defaultHoldTime),则执行动作。(长按执行操作)
MultiTap:需要多次轻击(在tapTime内按下并释放),每次轻击之间的间隔不超过tapDelay秒(双击或多击)

Press:根据按钮的按下和释放顺序来触发特定的操作(例如:在按下按钮后执行某个动作或在释放按钮时执行某个操作)

SlowTap:按下并按住控件一段时间后释放时执行操作(长按释放后执行操作) Tap:按下并按住小段时间内释放执行操作(点击)

在这里插入图片描述
添加完 Hold 后,看一下它的两个变量。如果默认值不能满足你的需求,取消勾选 Default 可自定义变量值。修改 Hold Time 变量一般即可满足需求

Press Point:按下按键这个阈值才能被认为是按下(笔者理解的是按压力度)

Hold Time:按下并按住按键保持的时间(以秒为单位)。

在这里插入图片描述
还是之前的代码在此基础上增加了长按监听的代码,具体参考下述代码

// 输入控制类的实例  
private TestInputControls InputControls;  

void OnEnable()  
{  
    InputControls = new TestInputControls(); // 创建输入控制实例  
    InputControls.Player.Fire.started += OnFireDown; // 注册开火开始动作的回调  
    InputControls.Player.Fire.performed  += OnLongPress; // 注册长按动作的回调  
    InputControls.Player.Fire.canceled += OnFireUp; // 注册开火结束动作的回调  
    InputControls.Enable(); // 启用输入控制  
}  

//当开火动作被触发时调用此方法。  
private void OnFireDown(InputAction.CallbackContext Obj)  
{  
    Debug.Log($"Fire Down | KeyName:{Obj.control.name}"); // 输出"Fire Down"到控制台 
}  

//当开火动作持续时调用的方法。  
private void OnLongPress(InputAction.CallbackContext Obj)  
{  
    Debug.Log($"Fire Long Press | KeyName:{Obj.control.name},持续时间{Obj.duration}"); // 输出动作持续时间  
}  

//当开火动作释放时调用此方法。  
private void OnFireUp(InputAction.CallbackContext Obj)  
{  
    Debug.Log($"Fire Up | KeyName:{Obj.control.name}"); // 输出"Fire Up"到控制台  
}  

//主要用于移除输入动作的回调函数,并禁用输入控制。  
private void OnDisable()  
{  
    InputControls.Player.Fire.started -= OnFireDown; // 移除开火开始事件的监听  
    InputControls.Player.Fire.performed  -= OnLongPress; // 移除长按事件的监听 
    InputControls.Player.Fire.canceled -= OnFireUp; // 移除开火结束事件的监听 
    InputControls.Disable(); // 禁用输入控制  
}
  • 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

经过上述步骤,我们学习到了新版 InputSystem 中的三个最基本的按键触发(按下、抬起、长按)。

实战

快速创建Input Actions映射

新增Player Input组件,点击创建新的输入系统,生成之后就可以删除Player Input组件了
在这里插入图片描述
会自动给我们创建好一些必备输入参数,比如移动
在这里插入图片描述
代码调用,点击自动生成代码
在这里插入图片描述

移动

新增PlayerController ,代码调用

public class PlayerController : MonoBehaviour
{
    public PlayerInputControl inputSystem;
    public Vector2 inputDirection;
    public float speed;
    private Rigidbody2D rb;
    private void Awake()
    {
        // 初始化输入控制
        inputSystem = new PlayerInputControl();
        rb = GetComponent<Rigidbody2D>();
    }

    private void OnEnable()
    {
        // 启用输入控制
        inputSystem.Enable();
    }

    private void OnDisable()
    {
        // 禁用输入控制
        inputSystem.Disable();
    }

    private void Update()
    {
        // 获取输入方向
        inputDirection = inputSystem.Player.Move.ReadValue<Vector2>();
    }

    private void FixedUpdate()
    {
        Move();
    }

    //移动角色
    private void Move()
    {
        // 根据输入方向移动角色
        rb.velocity = new Vector2(inputDirection.x * speed * Time.deltaTime, rb.velocity.y);
        // 根据输入方向翻转角色
        if (inputDirection.x < 0)
        {
            transform.localScale = new Vector3(-Mathf.Abs(transform.localScale.x), transform.localScale.y, transform.localScale.z);
        }
        else if (inputDirection.x > 0)
        {
            transform.localScale = new Vector3(Mathf.Abs(transform.localScale.x), transform.localScale.y, transform.localScale.z);
        }
    }
}
  • 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

配置
在这里插入图片描述
效果
在这里插入图片描述

跳跃

在这里插入图片描述
键盘
在这里插入图片描述
手柄,如果有的话
在这里插入图片描述
修改PlayerController

using UnityEngine.InputSystem;

public float jumpForce;

private void Awake()
{
    // 初始化输入控制
    inputSystem = new PlayerInputControl();
    rb = GetComponent<Rigidbody2D>();

    inputSystem.Player.Jump.started += Jump;
}
    
//跳跃
private void Jump(InputAction.CallbackContext context){
    rb.AddForce(transform.up * jumpForce, ForceMode2D.Impulse);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

在这里插入图片描述
效果
在这里插入图片描述

移动端支持

虚拟摇杆

在这里插入图片描述
虚拟摇杆input system已经帮我们做好了一个非常好的工具,模拟左侧操作杆,只需要挂载On-Screen Stick脚本即可
在这里插入图片描述
运行效果,没错就是这么简单,甚至你都不需要修改代码
在这里插入图片描述

虚拟按钮

绘制按钮UI
在这里插入图片描述
模拟不同的按钮
在这里插入图片描述
配置默认隐藏,开始游戏再显示
在这里插入图片描述

效果
在这里插入图片描述

区分不同设备的配置表(2024/07/02补充)

PC的按键勾选分类
在这里插入图片描述
手柄的按键勾选分类
在这里插入图片描述
把不同的设备按键绑定区分开

不同的输入系统

游戏时候可以用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

UI交互

InputSystem在UI上的应用

在创建canvas的同时
又创建了一个EventSystem
它原本是老版的输入系统
但是我们升级完InputSystem
新版的输入系统之后,它就会报错
在这里插入图片描述
我们把它别级为新版的输入系统
Actions Asset里面
默认给我们创建一个DefaultInputActions,绑定的按键和UI事件是对应的
在这里插入图片描述
UI的输入时间我们就用默认的就好了,原来的UI就不需要添加任何东西
在这里插入图片描述

鼠标滚轮滚动事件

在这里插入图片描述

参考

【文章】https://developer.unity.cn/projects/6602debfedbc2a001dcd1a82

完结

赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,以便我第一时间收到反馈,你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章中存在错误或者有更好的解决方法,也欢迎评论私信告诉我哦!

好了,我是向宇,https://xiangyu.blog.csdn.net

一位在小公司默默奋斗的开发者,出于兴趣爱好,最近开始自学unity,闲暇之余,边学习边记录分享,站在巨人的肩膀上,通过学习前辈们的经验总是会给我很多帮助和启发!php是工作,unity是生活!如果你遇到任何问题,也欢迎你评论私信找我, 虽然有些问题我也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~

在这里插入图片描述

向宇的客栈
QQ群名片
注:本文转载自blog.csdn.net的向宇it的文章"https://blog.csdn.net/qq_36303853/article/details/138794797"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2024 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top