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

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


注意: 新的输入法系统需要 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");  
    }
}

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

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(); // 禁用输入控制  
}

测试效果

可以看到,我们使用一套代码就可以同时监听键盘和鼠标的输入

按下抬起有了,要想实现长按也很简单。选中 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(); // 禁用输入控制  
}

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

实战

快速创建Input Actions映射

新增Player Input组件,点击创建新的输入系统,生成之后就可以删除Player Input组件了

会自动给我们创建好一些必备输入参数,比如移动

代码调用,点击自动生成代码

移动

新增PlayerController ,代码调用

public class PlayerController : MonoBehaviour
{
    public PlayerInputControl inputControl;
    public Vector2 inputDirection;
    public float speed;
    private Rigidbody2D rb;
    private void Awake()
    {
        // 初始化输入控制
        inputControl = new PlayerInputControl();
        rb = GetComponent<Rigidbody2D>();
    }
    private void OnEnable()
    {
        // 启用输入控制
        inputControl.Enable();
    }
    private void OnDisable()
    {
        // 禁用输入控制
        inputControl.Disable();
    }
    private void Update()
    {
        // 获取输入方向
        inputDirection = inputControl.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);
        }
    }
}

配置

效果

跳跃

键盘

手柄,如果有的话

修改PlayerController

using UnityEngine.InputSystem;
public float jumpForce;
private void Awake()
{
    // 初始化输入控制
    inputControl = new PlayerInputControl();
    rb = GetComponent<Rigidbody2D>();
    inputControl.Player.Jump.started += Jump;
}
    
//跳跃
private void Jump(InputAction.CallbackContext context){
    rb.AddForce(transform.up * jumpForce, ForceMode2D.Impulse);
}

效果

移动端支持

虚拟摇杆

虚拟摇杆input system已经帮我们做好了一个非常好的工具,模拟左侧操作杆,只需要挂载On-Screen Stick脚本即可

运行效果,没错就是这么简单,甚至你都不需要修改代码

虚拟按钮

绘制按钮UI

模拟不同的按钮

配置默认隐藏,开始游戏再显示

效果

参考

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

目录
相关文章
|
4月前
|
传感器 开发工具 vr&ar
ManoMotion⭐二、Unity手势识别插件简介,及效果录屏
ManoMotion⭐二、Unity手势识别插件简介,及效果录屏
|
3月前
|
图形学 C++ C#
Unity插件开发全攻略:从零起步教你用C++扩展游戏功能,解锁Unity新玩法的详细步骤与实战技巧大公开
【8月更文挑战第31天】Unity 是一款功能强大的游戏开发引擎,支持多平台发布并拥有丰富的插件生态系统。本文介绍 Unity 插件开发基础,帮助读者从零开始编写自定义插件以扩展其功能。插件通常用 C++ 编写,通过 Mono C# 运行时调用,需在不同平台上编译。文中详细讲解了开发环境搭建、简单插件编写及在 Unity 中调用的方法,包括创建 C# 封装脚本和处理跨平台问题,助力开发者提升游戏开发效率。
246 0
|
3月前
|
图形学 开发者 UED
Unity游戏开发必备技巧:深度解析事件系统运用之道,从生命周期回调到自定义事件,打造高效逻辑与流畅交互的全方位指南
【8月更文挑战第31天】在游戏开发中,事件系统是连接游戏逻辑与用户交互的关键。Unity提供了多种机制处理事件,如MonoBehaviour生命周期回调、事件系统组件及自定义事件。本文介绍如何有效利用这些机制,包括创建自定义事件和使用Unity内置事件系统提升游戏体验。通过合理安排代码执行时机,如在Awake、Start等方法中初始化组件,以及使用委托和事件处理复杂逻辑,可以使游戏更加高效且逻辑清晰。掌握这些技巧有助于开发者更好地应对游戏开发挑战。
138 0
|
4月前
|
图形学 C# 开发者
Unity粒子系统全解析:从基础设置到高级编程技巧,教你轻松玩转绚丽多彩的视觉特效,打造震撼游戏画面的终极指南
【8月更文挑战第31天】粒子系统是Unity引擎的强大功能,可创建动态视觉效果,如火焰、爆炸等。本文介绍如何在Unity中使用粒子系统,并提供示例代码。首先创建粒子系统,然后调整Emission、Shape、Color over Lifetime等模块参数,实现所需效果。此外,还可通过C#脚本实现更复杂的粒子效果,增强游戏视觉冲击力和沉浸感。
223 0
|
4月前
|
开发者 图形学 前端开发
绝招放送:彻底解锁Unity UI系统奥秘,五大步骤教你如何缔造令人惊叹的沉浸式游戏体验,从Canvas到动画,一步一个脚印走向大师级UI设计
【8月更文挑战第31天】随着游戏开发技术的进步,UI成为提升游戏体验的关键。本文探讨如何利用Unity的UI系统创建美观且功能丰富的界面,包括Canvas、UI元素及Event System的使用,并通过具体示例代码展示按钮点击事件及淡入淡出动画的实现过程,助力开发者打造沉浸式的游戏体验。
105 0
|
4月前
|
图形学
Unity动画☀️Unity动画系统Bug集合
Unity动画☀️Unity动画系统Bug集合
|
6月前
|
存储 JSON 关系型数据库
【unity实战】制作unity数据保存和加载系统——大型游戏存储的最优解
【unity实战】制作unity数据保存和加载系统——大型游戏存储的最优解
176 2
|
6月前
|
图形学
【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统(下)
【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统
89 0
|
6月前
|
图形学 容器
【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统(上)
【unity实战】Unity中基于瓦片的网格库存系统——类似《逃离塔科夫》的库存系统
90 0
|
6月前
|
图形学
【unity小技巧】Unity中实现一个战斗连击连招系统,可以动态添加减少连击连招段数功能
【unity小技巧】Unity中实现一个战斗连击连招系统,可以动态添加减少连击连招段数功能
127 0