Unity InputSystem 实现同一按键单击、双击、长按执行不同逻辑

2023-11-18

最近学习了一下Unity InputSystem。该系统可用于实现、管理复杂的操作逻辑,上限很高。但由于它有一定的学习成本,导致一些和我一样的小白一入门时不得要领。之前卡住我的一个需求就是通过InputSystem 实现同一按键单击、双击、长按执行不同逻辑。例如点击单位执行攻击、双击单位选中所有同类单位、长按单位查看信息。现在想到了相对合理的方式,在此记录并分享。

InputSystem的官方示例提供了4种使用方法,即官方示例“Simple Demo”中提到的4种:

  1. SimpleDemo_UsingState
  2. SimpleDemo_UsingActions
  3. SimpleDemo_UsingActionAsset
  4. SimpleDemo_UsingPlayerInput

其中后两种是我认为的官方推荐的正式用法,我是用的是第三种,即使用了ActionAsset但没有使用PlayerInput的实现方式。

我的测试目标是在单击、双击、长按时在Unity控制台打出不同的log,且一次操作不会出现两次执行log。ActionAsset配置如图:
Input Action Asset配置截图
这里有三点注意事项:

  1. 虽然我们关注的操作有3种(单击、双击、长按),但由于是同个按键,所以应设为一个Action,即截图中的唯一的Action:“Tap”。
  2. 虽然我们关注的操作有3种(单击、双击、长按),但显然双击与单击的操作是由特殊关系的,实际的逻辑应该是单击后等待片刻若无第二次点击才执行单击的逻辑。所以这里我们在Interactions中只添加了“Hold”和“Multi Tap”这两种。其他设置保持默认。
  3. “Hold”和“Multi Tap”在图示Interactions列表中的顺序是影响其执行逻辑的,建议保持图示顺序。

测试代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem.Interactions;

public class TictactoeControl : MonoBehaviour
{
    private TictactoeAction InputActions;
    private void Awake()
    {
        InputActions = new TictactoeAction();
        InputActions.TestMap.Tap.started += ctx =>
        {
            Debug.Log("操作开始");
        };
        InputActions.TestMap.Tap.performed += ctx =>
        {
            if (ctx.interaction is MultiTapInteraction)
            {
                Debug.Log("执行双击逻辑");
            }
            else if (ctx.interaction is HoldInteraction)
            {
                Debug.Log("执行长按逻辑");
            }
            else
            {
                //列表中只有MultiTapInteraction和HoldInteraction对应的两种Interaction。
                //故不会走到这个else里。
            }
        };
        InputActions.TestMap.Tap.canceled += ctx =>
        {
            if (ctx.interaction is MultiTapInteraction)
            {
                Debug.Log("执行点击逻辑");
            }
        };
    }
    void Start()
    {
        
    }
    void Update()
    {

    }
    public void OnEnable()
    {
        InputActions.Enable();
    }
    public void OnDisable()
    {
        InputActions.Disable();
    }
}

我贴了测试脚本的完整代码,我们主要关注Awake()方法中的内容。

当我们设置的“Tap”Action执行时,会调用InputActions.TestMap.Tap.performed,这里要根据它执行时是通过哪个Interaction执行的(Hold 或 MultiTap)。区分后分别执行对应的逻辑即可。

当“Tap”Action取消时,会调用InputActions.TestMap.Tap.canceled,我们在此处判断一下是否是 MultiTap的取消,若是,则执行单击的逻辑。若之前Interactions列表的顺序和图示不一致,则此处执行单击逻辑的时机也会不一致。可能出现单击后不执行却在长按的时候执行的情况。

测试结果如图:
测试结果
我在图示这次测试时先长按了一次,松手后进行了双击,最后进行了一次单击。可以看到三种操作分别独立地执行了,没有出现缺失或是混淆单击、双击的问题。(每次操作出现多次“操作开始”是因为我们配置了不止一种Interaction,在它们之间切换时会执行多次InputActions.TestMap.Tap.started。这个特性当前需求下可以忽略,也可利用起来实现其他功能。)

我使用的这种方式很可能不是最合理的甚至可能是多次一举的,欢迎指正、讨论。如果我发现了新的相关技巧,也会在此更新。

====================================================
2022.03.21更新
上文提到的InputSystem的几种回调(started、performed、canceled)在部分机型(华为折叠屏某款)、模拟器(网易mumu)会失效,原因不明。可使用每帧读取操作状态的方式实现同等功能。

例如:

InputActions.TestMap.Tap.ReadValue<float>();

点击、长按等Button类型的操作要读float类型的值,值为 1f 表示“有操作”,0f 表示“无操作”。
(我实际上很不理解这里为什么不是读bool值,所以怀疑这种每帧读值的方案不是标准方案。)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Unity InputSystem 实现同一按键单击、双击、长按执行不同逻辑 的相关文章

  • 数据模板绑定垃圾邮件输出窗口出现错误:找不到管理 FrameworkElemen

    我有问题 System Windows Data 错误 2 找不到目标元素的管理 FrameworkElement 或 FrameworkContentElement BindingExpression 无路径 数据项 空 目标元素是 So
  • 在实体框架拦截器中向 DbScanExpression 添加内部联接

    我正在尝试使用实体框架 CommandTree 拦截器通过 DbContext 向每个查询添加过滤器 为了简单起见 我有两个表 一个称为 User 有两列 UserId 和 EmailAddress 另一个称为 TenantUser 有两列
  • 我如何理解这个 C 类型声明?

    double bar int double double double double 在查看讲座幻灯片时 我发现了留给学生的练习 用简单的英语来说 什么是类型bar在这个 C 声明中 Please帮助我解决这个问题 我什至不知道从哪里开始
  • 何时使用 =default 使析构函数默认?

    尽管对构造函数使用 default 对我来说很清楚 即强制编译器在其他构造函数存在时创建默认构造函数 但我仍然无法理解这两种类型的析构函数之间的区别 那些使用 default 的 那些没有显式定义并由编译器自动生成的 我唯一想到的是 gro
  • 为什么在创建矩阵类时使用向量不好?

    对于我的矩阵类 我做了 template
  • EF Core 通过完全替换断开集合导航属性的更新

    使用 EF Core 5 0 我有一个 SPA 页面 可以加载Group实体及其集合Employee来自 API 的实体 var groupToUpdate await context Groups Include g gt g Emplo
  • 动态生成的控件 ID 返回为 NULL

    我可以在 Page PreInit 函数中创建动态控件 如何检索控件及其 ID 我的 C 代码用于创建动态控件之一 var btn new WebForms Button btn Text btn ID Addmore btn Click
  • fprintf() 线程安全吗?

    我正在为野人就餐问题的某些变量编写一个 C 解决方案 现在 我创建线程 每个线程都将 FILE 获取到同一个调试文件 在线程内我正在使用 fprintf 进行一些打印 打印的语句不受任何类型的互斥锁等保护 我没有在调试文件中观察到任何交错行
  • 如何获取 QTableView 的标题列表?

    我有一个QTableView我的对话框中的对象 我需要访问该表的水平标题并将它们放入QStringList object 尽管进行了大量搜索 但我在 Qt 文档中找不到如何获取此标头列表 编辑 我发现的最接近的地方是this https w
  • 如何在 QTabWidget Qt 中展开选项卡

    我有一个QTabWidget像这个 但我想展开选项卡以 填充 整个小部件宽度 如下所示 我怎样才能做到这一点 我在用Qt 5 3 2 and Qt 创建者 3 2 1 Update 我尝试使用setExpanding功能 ui gt myT
  • C++ php 和静态库

    我创建了一个library a 其中包含 cpp 和 h 文件 其中包含很多类 嵌套类和方法 我想在 php 示例中包含这个静态库并尝试使用它 我想提一下 我是 php 新手 我已经在 test cpp 文件中测试了我的 libray a
  • 检查 RoutedEvent 是否有任何处理程序

    我有一个自定义 Button 类 当单击它时 打开特定窗口 它总是执行相同的操作 我添加了一个可以在按钮的 XAML 中分配的 Click 事件 就像常规按钮一样 当它被单击时 我想执行 Click 事件处理程序 如果已分配 否则我想执行默
  • 给出 5 个参数,但在终端中只得到 3 个参数

    我想将一个文件传递给一个c 程序 如果我在 IDE 中执行此操作 test string string lt test txt return argc 5 但在终端上我刚刚得到argc 3 看来 这是因为 什么是 lt 意思是 我正在使用
  • 如何分析组合的 python 和 c 代码

    我有一个由多个 python 脚本组成的应用程序 其中一些脚本正在调用 C 代码 该应用程序现在的运行速度比以前慢得多 因此我想对其进行分析以查看问题所在 是否有工具 软件包或只是一种分析此类应用程序的方法 有一个工具可以将 python
  • 跨多个域的 ASP.NET 会话

    是否有合适的 NET 解决方案来在多个域上提供持久服务器会话 即 如果该网站的用户在 www site1 com 下登录 他们也将在 www site2 com 下登录 安全是我们正在开发的程序的一个问题 Thanks 它是否需要在会话中
  • 每个数据库多个/单个 *.edmx 文件

    我有一个通过 ADO net 数据服务与数据库交互的项目 数据库很大 近 150 个具有依赖关系的表 该项目几年前开始 当时使用的是数据集 现在我们正在转向实体模型关系 由于我们添加了更多需要使用的表 该模型正在不断增长 这是管理这一切的正
  • 您是否将信息添加到每个 .hpp/.cpp 文件的顶部? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 创建新的 C 头文件 源文件时 您会在顶部添加哪些信息 例如 您是否添加日期 您的姓名 文件描述等 您是否使用结构化格式来存储此信息 e g F
  • 更改 Windows Phone 系统托盘颜色

    有没有办法将 Windows Phone 上的系统托盘颜色从黑色更改为白色 我的应用程序有白色背景 所以我希望系统托盘也是白色的 您可以在页面 XAML 中执行此操作
  • C++ Streambuf 方法可以抛出异常吗?

    我正在尝试找到一种方法来获取读取或写入流的字符数 即使存在错误并且读 写结束时间较短 该方法也是可靠的 我正在做这样的事情 return stream rdbuf gt sputn buffer buffer size 但如果streamb
  • C++0x中disable_if在哪里?

    Boost 两者都有enable if and disable if 但 C 0x 似乎缺少后者 为什么它被排除在外 C 0x 中是否有元编程工具允许我构建disable if按照enable if 哦 我刚刚注意到std enable i

随机推荐

  • 这份4577页的Java面试PDF,让我成功斩获阿里、字节等大厂offer

    我为大家准备了一份超级全面的Java 学习面试笔记 这份电子版笔记涵盖了诸多后端技术栈的面试题和答案 相信可以帮助大家在最短的时间内复习Java后端的大多数技术点和面试题 从而拿到自己心仪的offer 共4577页 整体还是比较清爽的 大家
  • 使用python中的随机森林进行数据分类预测

    以下是使用Python中的随机森林进行数据分类预测的示例代码 引入需要的库 from sklearn ensemble import RandomForestClassifier from sklearn model selection i
  • 利用百度AI 合成语音2

    文字合成语音 coding UTF 8 from aip import AipSpeech from playsound import playsound 你的 APPID AK SK APP ID 20232679 API KEY bZc
  • HEVC原理-图像的二维变换与离散余弦变换(DCT)

    最近在做RDOQ算法优化和硬件系统结构设计 建立其时序模型 估算算法的硬件复杂度 在做这部分工作的同时 博主学习了图像的二维变换与离散余弦变换 DCT 总结如下 1 图像的二维离散变换 与一维的有限长离散非周期信号存在傅里叶变换 DFT 一
  • properties文件快速转为yml文件

    只是做了简单的测试 没有考虑过文件里有注释的情况 思想就是先把数据读到map中 然后再保存到新的文件中 public class Test public static void main String args throws Excepti
  • C++ 0x 之移动语义和传导模板实现原理

    文 李博 光宇广贞 C 0x 之左值与右值 文中提到 std forward 和 std move 本文开头对之补充一句 在操作函数返回值或函数参数时 匿名左值仍然为左值 左值可以具名 匿名右值仍然为右值 右值一旦具名成功 立即转变为左值
  • Fping命令解析

    Fping程序类似于ping ping是通过ICMP 网络控制信息协议InternetControl Message Protocol 协议回复请求以检测主机是否存在 Fping与ping不同的地方在于 fping可以在命令行中指定要pin
  • QT_内存

    深度解析QMap与QHash 转载于 http www cnblogs com 5iedu p 5835715 html
  • Redis——持久化数据

    Redis被称为是内存数据库 那是因为它会将其所有数据存储在内存里 因此Redis具有强劲的速度性能 但是 也正因为数据存储在内存中 当Redis重启后 所有存储在内存的数据就会丢失 为了使得数据持久化 Redis提供了两种方式 RDB方式
  • VGG预训练模型网络结构详解——以VGG16为例

    VGG卷积神经网络是牛津大学在2014年提出来的模型 当这个模型被提出时 由于它的简洁性和实用性 马上成为了当时最流行的卷积神经网络模型 它在图像分类和目标检测任务中都表现出非常好的结果 在2014年的ILSVRC比赛中 VGG 在Top
  • Win10环境+ CUDA9.0 +CUDNN7.0+TensorFlow1.7/1.6/1.5配置

    前言 很多小伙伴在选择CUDA版本和cudnn版本上有疑问 这里简短的说一下 希望能帮到各位小伙伴 我在网上看到有人说 要根据自己的显卡来选择CUDA 其实是错误的 你可以下载自己所需要的CUDA版本 这只是个驱动而已 CUDA的版本和cu
  • kubernetes系列二之Deployment的管理和使用

    目录 1 Kubernetes管理对象 Pod ReplicationController 简称RC ReplicaSet 简称RS Deployment 逻辑关系 从小到大的管理逻辑 2 创建Deployment 运行一个Deployme
  • Lack of free swap space on 192.168.3.1

    zabbix健康报错 Lack of free swap space on 192 168 3 1 解决办法 先查看磁盘swap磁盘容量 是因为Zabbix监控没有考虑虚拟主机的交换空间情况 解决办法修改配置 选择 Lack of free
  • easypoi校验数据时获取excel行号和错误信息

    目录 什么是easypoi easypoi校验excel实体类怎么获取错误信息和excel的行号 需要用到的excel实体类 调用的客户端代码 什么是easypoi easypoi功能如同名字easy 主打的功能就是容易 让一个没见接触过p
  • 华为校招机试题- 数组的中心位置-2023年

    题目描述 给你一个整数数组nums 请计算数组的中心位置 数组中心位置是数组的一个下标 其左侧所有元素相乘的积等于右侧所有元素相乘的积 数组第一个元素的左侧积为1 最后一个元素的右侧积为1 如果数组有多个中心位置 应该返回最靠近左边的那一个
  • 修改lvgl Linux demo使用tslib获取触摸坐标

    1 为什么要修改 o 交叉编译官方lvgl linux demo发现触摸坐标不准确 官方demo获取坐标的做法是 evdev fd open EVDEV NAME O RDWR O NOCTTY O NDELAY if evdev fd 1
  • 再谈TCP三次握手/四次挥手

    TCP三次握手 四次挥手 在TCP IP协议中 TCP协议提供可靠的连接服务 采用三次握手建立一个连接 如图1所示 1 第一次握手 建立连接时 客户端A发送SYN包 SYN j 到服务器B 并进入SYN SEND状态 等待服务器B确认 2
  • 比PS还好用!Python 20行代码批量抠图

    抠图前 vs Python自动抠图后 在日常的工作和生活中 我们经常会遇到需要抠图的场景 即便是只有一张图片需要抠 也会抠得我们不耐烦 倘若遇到许多张图片需要抠 这时候你的表情应该会很有趣 Python能够成为这样的一种工具 在只有一张图片
  • cypress——前端自动化测试框架

    前端自动化测试概述 MVC Model View Controller 模式开始流行 MVC是模型 Model 视图 View 和控制器 Controller 的缩写 它使业务逻辑 数据 界面显示分离 这时Web开发属于View层 Ajax
  • Unity InputSystem 实现同一按键单击、双击、长按执行不同逻辑

    最近学习了一下Unity InputSystem 该系统可用于实现 管理复杂的操作逻辑 上限很高 但由于它有一定的学习成本 导致一些和我一样的小白一入门时不得要领 之前卡住我的一个需求就是通过InputSystem 实现同一按键单击 双击