【Unity学习笔记】New Input System 部分源码和测试用例补充

转载请注明出处:🔗https://blog.csdn.net/weixin_44013533/article/details/135630016
作者:CSDN@|Ringleader|

主要参考:

  • Unity官方Input System手册与API
  • 【Unity学习笔记】Unity TestRunner使用
  • 【Unity学习笔记】第十二 · New Input System 及其系统结构 和 源码浅析

注:本文使用的unity版本是2021.3.25f,InputSystem版本为1.5.1

deafault Interaction测试用例

  1. ButtonAndValue

    [Test]
    public void Actions_ButtonActions_RespectButtonPressPoints()
    {InputSystem.settings.defaultButtonPressPoint = 0.5f;InputSystem.settings.buttonReleaseThreshold = 0.9f; // Release at 90% of press point puts release at 0.45.// Customize gamepad with specific button press point on right trigger (but not on left).InputSystem.RegisterLayoutOverride(@"{""name"" : ""GamepadRightTriggerWithPressPoint"",""extend"" : ""Gamepad"",""controls"" : [{ ""name"" : ""rightTrigger"", ""parameters"" : ""pressPoint=0.75"" }]}");var gamepad = InputSystem.AddDevice<Gamepad>();var rightTriggerButton = new InputAction(type: InputActionType.Button, binding: "<Gamepad>/rightTrigger");var rightTriggerValue = new InputAction(type: InputActionType.Value, binding: "<Gamepad>/rightTrigger");var leftTriggerButton = new InputAction(type: InputActionType.Button, binding: "<Gamepad>/leftTrigger");var leftTriggerValue = new InputAction(type: InputActionType.Value, binding: "<Gamepad>/leftTrigger");rightTriggerButton.Enable();rightTriggerValue.Enable();leftTriggerButton.Enable();leftTriggerValue.Enable();using (var rightTriggerButtonTrace = new InputActionTrace(rightTriggerButton))using (var rightTriggerValueTrace = new InputActionTrace(rightTriggerValue))using (var leftTriggerButtonTrace = new InputActionTrace(leftTriggerButton))using (var leftTriggerValueTrace = new InputActionTrace(leftTriggerValue)){Set(gamepad.leftTrigger, 0.25f);Set(gamepad.rightTrigger, 0.25f);// Have crossed neither button threshold. Actions start but don't perform.Assert.That(leftTriggerButtonTrace, Started(leftTriggerButton, gamepad.leftTrigger, value: 0.25f));Assert.That(rightTriggerButtonTrace, Started(rightTriggerButton, gamepad.rightTrigger, value: 0.25f));Assert.That(leftTriggerValueTrace,Started(leftTriggerValue, gamepad.leftTrigger, value: 0.25f).AndThen(Performed(leftTriggerValue, gamepad.leftTrigger, value: 0.25f)));Assert.That(rightTriggerValueTrace,Started(rightTriggerValue, gamepad.rightTrigger, value: 0.25f).AndThen(Performed(rightTriggerValue, gamepad.rightTrigger, value: 0.25f)));rightTriggerButtonTrace.Clear();rightTriggerValueTrace.Clear();leftTriggerButtonTrace.Clear();leftTriggerValueTrace.Clear();Set(gamepad.leftTrigger, 0.6f);Set(gamepad.rightTrigger, 0.6f);// Have grossed global but not right trigger threshold.Assert.That(leftTriggerButtonTrace, Performed(leftTriggerButton, gamepad.leftTrigger, value: 0.6f));Assert.That(rightTriggerButtonTrace, Is.Empty);Assert.That(leftTriggerValueTrace, Performed(leftTriggerValue, gamepad.leftTrigger, value: 0.6f));Assert.That(rightTriggerValueTrace, Performed(rightTriggerValue, gamepad.rightTrigger, value: 0.6f));rightTriggerButtonTrace.Clear();rightTriggerValueTrace.Clear();leftTriggerButtonTrace.Clear();leftTriggerValueTrace.Clear();Set(gamepad.leftTrigger, 0.9f);Set(gamepad.rightTrigger, 0.9f);// No change on left trigger action, right trigger crossed threshold.Assert.That(leftTriggerButtonTrace, Is.Empty);Assert.That(rightTriggerButtonTrace, Performed(rightTriggerButton, gamepad.rightTrigger, value: 0.9f));Assert.That(leftTriggerValueTrace, Performed(leftTriggerValue, gamepad.leftTrigger, value: 0.9f));Assert.That(rightTriggerValueTrace, Performed(rightTriggerValue, gamepad.rightTrigger, value: 0.9f));rightTriggerButtonTrace.Clear();rightTriggerValueTrace.Clear();leftTriggerButtonTrace.Clear();leftTriggerValueTrace.Clear();Set(gamepad.leftTrigger, 0.6f);Set(gamepad.rightTrigger, 0.6f);// No change on left trigger action, right trigger action cancels.Assert.That(leftTriggerButtonTrace, Is.Empty);Assert.That(rightTriggerButtonTrace, Started(rightTriggerButton, gamepad.rightTrigger, value: 0.6f));Assert.That(leftTriggerValueTrace, Performed(leftTriggerValue, gamepad.leftTrigger, value: 0.6f));Assert.That(rightTriggerValueTrace, Performed(rightTriggerValue, gamepad.rightTrigger, value: 0.6f));rightTriggerButtonTrace.Clear();rightTriggerValueTrace.Clear();leftTriggerButtonTrace.Clear();leftTriggerValueTrace.Clear();Set(gamepad.leftTrigger, 0.4f);Set(gamepad.rightTrigger, 0.4f);// Left trigger cancels, right trigger *starts* again (but doesn't perform).Assert.That(leftTriggerButtonTrace, Started(leftTriggerButton, gamepad.leftTrigger, value: 0.4f));Assert.That(rightTriggerButtonTrace, Is.Empty);Assert.That(leftTriggerValueTrace, Performed(leftTriggerValue, gamepad.leftTrigger, value: 0.4f));Assert.That(rightTriggerValueTrace, Performed(rightTriggerValue, gamepad.rightTrigger, value: 0.4f));rightTriggerButtonTrace.Clear();rightTriggerValueTrace.Clear();leftTriggerButtonTrace.Clear();leftTriggerValueTrace.Clear();Set(gamepad.leftTrigger, 0f);Set(gamepad.rightTrigger, 0f);// No change on left and right trigger actions.Assert.That(leftTriggerButtonTrace, Canceled(leftTriggerButton, gamepad.leftTrigger, 0f));Assert.That(rightTriggerButtonTrace, Canceled(rightTriggerButton, gamepad.rightTrigger, 0f));Assert.That(leftTriggerValueTrace, Canceled(leftTriggerValue, gamepad.leftTrigger, value: 0f));Assert.That(rightTriggerValueTrace, Canceled(rightTriggerValue, gamepad.rightTrigger, value: 0f));rightTriggerButtonTrace.Clear();leftTriggerButtonTrace.Clear();// Make sure that we start and cancel if we press the buttons just a little and then release.Set(gamepad.leftTrigger, 0.25f);Set(gamepad.rightTrigger, 0.25f);Assert.That(leftTriggerButtonTrace, Started(leftTriggerButton, gamepad.leftTrigger, value: 0.25f));Assert.That(rightTriggerButtonTrace, Started(rightTriggerButton, gamepad.rightTrigger, value: 0.25f));rightTriggerButtonTrace.Clear();leftTriggerButtonTrace.Clear();Set(gamepad.leftTrigger, 0f);Set(gamepad.rightTrigger, 0f);Assert.That(leftTriggerButtonTrace, Canceled(leftTriggerButton, gamepad.leftTrigger, value: 0f));Assert.That(rightTriggerButtonTrace, Canceled(rightTriggerButton, gamepad.rightTrigger, value: 0f));}
    }
    
  2. passthrough

    [Test]
    public void Actions_passthroughActions()
    {var gamepad = InputSystem.AddDevice<Gamepad>();var rightTriggerValue = new InputAction(type: InputActionType.PassThrough, binding: "<Gamepad>/rightTrigger");rightTriggerValue.Enable();using (var rightTriggerValueTrace = new InputActionTrace(rightTriggerValue)){Set(gamepad.rightTrigger, 0.25f);Assert.That(rightTriggerValueTrace, Performed(rightTriggerValue, gamepad.rightTrigger, value: 0.25f));rightTriggerValueTrace.Clear();Set(gamepad.rightTrigger, 0.6f);Assert.That(rightTriggerValueTrace, Performed(rightTriggerValue, gamepad.rightTrigger, value: 0.6f));rightTriggerValueTrace.Clear();Set(gamepad.rightTrigger, 0.9f);Assert.That(rightTriggerValueTrace, Performed(rightTriggerValue, gamepad.rightTrigger, value: 0.9f));rightTriggerValueTrace.Clear();Set(gamepad.rightTrigger, 0f);Assert.That(rightTriggerValueTrace, Performed(rightTriggerValue, gamepad.rightTrigger, value: 0f));rightTriggerValueTrace.Clear();}
    }
    

Press Interaction测试用例

using System.Diagnostics.CodeAnalysis;
using NUnit.Framework;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Utilities;namespace Scenes.TestAction
{[SuppressMessage("ReSharper", "AccessToStaticMemberViaDerivedType")]public class TestAction : InputTestFixture{[Test][TestCase(InputActionType.Value)][TestCase(InputActionType.Button)][TestCase(InputActionType.PassThrough)]public void Actions_PressOnly(InputActionType type){var gamepad = InputSystem.AddDevice<Gamepad>();InputSystem.settings.defaultButtonPressPoint = 0.5f;InputSystem.settings.buttonReleaseThreshold = 0.75f; // Puts release point at 0.375.var action = new InputAction(type:type, binding: "<Gamepad>/leftTrigger", interactions: "press(behavior=0)");action.Enable();using (var trace = new InputActionTrace(action)){Set(gamepad.leftTrigger, 0.35f);Assert.That(trace, Started(action, control: gamepad.leftTrigger, value: 0.35f));trace.Clear();Set(gamepad.leftTrigger, 0.5f);Assert.That(trace, Performed(action, control: gamepad.leftTrigger, value: 0.5f));trace.Clear();Set(gamepad.leftTrigger, 0.6f);Assert.That(trace, Is.Empty);Set(gamepad.leftTrigger, 0.4f);Assert.That(trace, Is.Empty);Set(gamepad.leftTrigger, 0.3f);Assert.That(trace, Started(action, control: gamepad.leftTrigger, value: 0.3f));trace.Clear();Set(gamepad.leftTrigger, 0);Assert.That(trace, Canceled(action, control: gamepad.leftTrigger, value: 0));}}[Test][TestCase(InputActionType.Value)][TestCase(InputActionType.Button)][TestCase(InputActionType.PassThrough)]public void Actions_RealeasOnly(InputActionType type){var gamepad = InputSystem.AddDevice<Gamepad>();InputSystem.settings.defaultButtonPressPoint = 0.5f;InputSystem.settings.buttonReleaseThreshold = 0.75f; // Puts release point at 0.375.var action = new InputAction(type:type, binding: "<Gamepad>/leftTrigger", interactions: "press(behavior=1)");action.Enable();using (var trace = new InputActionTrace(action)){Set(gamepad.leftTrigger, 0.35f);Assert.That(trace, Started(action, control: gamepad.leftTrigger, value: 0.35f));trace.Clear();Set(gamepad.leftTrigger, 0.5f);Assert.That(trace, Is.Empty);trace.Clear();Set(gamepad.leftTrigger, 0.6f);Assert.That(trace, Is.Empty);trace.Clear();Set(gamepad.leftTrigger, 0.4f);Assert.That(trace, Is.Empty);trace.Clear();Set(gamepad.leftTrigger, 0.3f);Assert.That(trace,Performed(action, control: gamepad.leftTrigger, value: 0.3f).AndThen(Canceled(action, control: gamepad.leftTrigger, value: 0)));trace.Clear();Set(gamepad.leftTrigger, 0.1f);Assert.That(trace, Started(action, control: gamepad.leftTrigger, value: 0.1f));trace.Clear();Set(gamepad.leftTrigger, 0);Assert.That(trace, Canceled(action, control: gamepad.leftTrigger, value: 0));trace.Clear();Set(gamepad.leftTrigger, 0.4f);Set(gamepad.leftTrigger, 0.3f);//onlyRelease 不超过press-threshold只回落release是不会触发的Assert.That(trace, Started(action, control: gamepad.leftTrigger, value: 0.4f));trace.Clear();}}[Test][TestCase(InputActionType.Value)][TestCase(InputActionType.Button)][TestCase(InputActionType.PassThrough)]public void Actions_PressAndRelease(InputActionType type){var gamepad = InputSystem.AddDevice<Gamepad>();InputSystem.settings.defaultButtonPressPoint = 0.5f;InputSystem.settings.buttonReleaseThreshold = 0.75f; // Puts release point at 0.375.var action = new InputAction(type:type, binding: "<Gamepad>/leftTrigger", interactions: "press(behavior=2)");action.Enable();using (var trace = new InputActionTrace(action)){Set(gamepad.leftTrigger, 0.35f);Assert.That(trace, Started(action, control: gamepad.leftTrigger, value: 0.35f));trace.Clear();Set(gamepad.leftTrigger, 0.5f);Assert.That(trace, Performed(action, control: gamepad.leftTrigger, value: 0.5f));trace.Clear();Set(gamepad.leftTrigger, 0.6f);Assert.That(trace, Is.Empty);trace.Clear();Set(gamepad.leftTrigger, 0.4f);Assert.That(trace, Is.Empty);trace.Clear();Set(gamepad.leftTrigger, 0.3f);Assert.That(trace,Performed(action, control: gamepad.leftTrigger, value: 0.3f));trace.Clear();Set(gamepad.leftTrigger, 0);Assert.That(trace, Is.Empty);trace.Clear();Set(gamepad.leftTrigger, 0.9f);Assert.That(trace, Started(action, control: gamepad.leftTrigger, value: 0.9f).AndThen(Performed(action, control: gamepad.leftTrigger, value: 0.9f)));trace.Clear();Set(gamepad.leftTrigger, 0);Assert.That(trace, Performed(action, control: gamepad.leftTrigger, value: 0f).AndThen(Canceled(action, control: gamepad.leftTrigger, value: 0f)));trace.Clear();Set(gamepad.leftTrigger, 0.4f);Set(gamepad.leftTrigger, 0.3f);//press&release 不超过press-threshold只回落release是不会触发的Assert.That(trace, Started(action, control: gamepad.leftTrigger, value: 0.4f));trace.Clear();}}}}

UnityEvent方式注册回调关键逻辑

  1. PlayerInput.InitializeActions()
    UnityEvent方式注册回调的核心在于PlayerInput组件enable时进行InitializeActions初始化操作
    在这里插入图片描述
  2. PlayerInputEditor
    但对于上面ActionEvent的eventId怎么匹配上actionId,则要看PlayerInputEditor.OnInspectorGUI()OnActionAssetChange()
    在这里插入图片描述
  3. UnityEvent<T0>
    上面action触发后,对应actionEvent调用Invoke,但此时真正的回调方法并没有注册,是在下面的InvokableCall中注册的,最后在InvokableCall.Invoke中执行最终的方法回调,处理输入处理。
    在这里插入图片描述
  4. InvokableCall<T1> 注册回调
    在这里插入图片描述
    从上面看,UnityAction方式远比原生C#事件复杂得多。(而且我也并没完全弄懂)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/639011.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL的执行流程

一、MySQL的执行流程 MySQL架构分为Server层、存储引擎&#xff0c;其中Server层又分为连接器、查询缓存、分析器、优化器执行器五个部分。当客户端发送请求后依次需要经过 处理请求、查询缓存、语法解析、查询优化、存储引擎部分。 1. 连接器 负责维持和管理连接&#xff…

【差分数组】【图论】【分类讨论】【整除以2】100213按距离统计房屋对数目

作者推荐 【动态规划】【数学】【C算法】18赛车 本文涉及知识点 差分数组 图论 分类讨论 整除以2 LeetCode100213按距离统计房屋对数目 给你三个 正整数 n 、x 和 y 。 在城市中&#xff0c;存在编号从 1 到 n 的房屋&#xff0c;由 n 条街道相连。对所有 1 < i < n…

Java代码审计Shiro反序列化CB1链source入口sink执行gadget链

目录 0x00 前言 0x01 CC链&CB链简介 1. Commons Collections链是什么&#xff1f; 2. Commons BeanUtils链是什么&#xff1f; 0x02 测试Commons BeanUtils1链 0x03 Shiro550 - Commons BeanUtils1链 - 跟踪分析&#xff08;无依赖&#xff09; 1. 前置知识 2. Co…

Node开发基础

1. 概述 1.1 为什么要学习服务器端开发基础 能够和后端程序员更加紧密的配合 网站业务逻辑前置&#xff0c;学习前端技术需要后端技术支撑 扩宽知识视野&#xff0c;能够站在更高的角度审视整个项目 1.2 服务器端开发要做的事情 实现网站的业务逻辑 ---网站登录部分&#…

矩阵重叠问题判断

创作背景 看到一道题目有感而发想写一篇题解&#xff0c;涉及的是一种逆向思维 桌面窗体重叠 - 洛谷https://www.luogu.com.cn/problem/U399827题目来源于《信息学奥赛课课通》 大致就是给一个长方形的左上顶点坐标&#xff08;x1,y1&#xff09;和右下顶点坐标&#xff08;x…

【设计模式】适配器和桥接器模式有什么区别?

今天我探讨一下适配器模式和桥接模式&#xff0c;这两种模式往往容易被混淆&#xff0c;我们希望通过比较他们的区别和联系&#xff0c;能够让大家有更清晰的认识。 适配器模式&#xff1a;连接不兼容接口 当你有一个类的接口不兼容你的系统&#xff0c;而你又不希望修改这个…

云服务器定价_云服务器价格_云主机计费模式_腾讯云

腾讯云服务器租用价格表&#xff1a;轻量应用服务器2核2G3M价格62元一年、2核2G4M价格118元一年&#xff0c;540元三年、2核4G5M带宽218元一年&#xff0c;2核4G5M带宽756元三年、轻量4核8G12M服务器446元一年、646元15个月&#xff0c;云服务器CVM S5实例2核2G配置280.8元一年…

嵌入式培训机构四个月实训课程笔记(完整版)-C++和QT编程第六天-Qt UDP编程(物联技术666)

链接&#xff1a;https://pan.baidu.com/s/1-u7GvgM0TLuiy9z7LYQ80Q?pwd1688 提取码&#xff1a;1688 在Qt中提供了QUdpSocket 类来进行UDP数据报&#xff08;datagrams&#xff09;的发送和接收。这里我们还要了解一个名词Socket&#xff0c;也就是常说的“套接字”。 Qt 网络…

强化学习(四)动态规划——1

动态规划算法&#xff08;DP&#xff09;&#xff1a;在马尔可夫决策过程&#xff08;MDP&#xff09;的完美环境模型下计算最优策略。但其在强化学习中实用性有限&#xff0c;其一是它是基于环境模型已知&#xff1b;其二是它的计算成本很大。但它在理论伤仍然很重要&#xff…

2023年12月青少年机器人技术等级考试(五级)理论综合试卷

2023年12月青少年机器人技术等级考试&#xff08;五级&#xff09;理论综合试卷 单选题 第 1 题 单选题 通常状况下&#xff0c;ESP32 WROOM模组的工作电压是&#xff1f;&#xff08; &#xff09; A.3V B.3.3V C.3.6V D.5V 第 2 题 单选题 ESP32 WROOM模组中核&am…

java大数据hadoop2.9.2 Linux安装mariadb和hive

一、安装mariadb 版本centos7 1、检查Linux服务器是否已安装mariadb yum list installed mariadb* 2、如果安装了&#xff0c;想要卸载 yum remove mariadb rm -rf /etc/my.cnf rm -rf /var/lib/mysql 才能完全删除 3、安装mariadb 在线网络安装 yum install -y mari…

网络通信(Socket/TCP/UDP)

一、Socket 1.概念: Socket(又叫套接字)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接协议,客户端的IP地址,客户端的端口,服务器的IP地址,服务器的端口。 一个Socket是一对IP地址…

笔试面试题——二叉树进阶(一)

&#x1f4d8;北尘_&#xff1a;个人主页 &#x1f30e;个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上&#xff0c;不忘来时的初心 文章目录 一、根据二叉树创建字符串1、题目讲解2、思路讲解3、代码实现 二、二叉树的分层遍历1、题目讲…

大数据导论(4)---大数据应用

文章目录 1. 在互联网中的应用1.1 推荐系统1.2 长尾理论1.3 推荐方法与模型1.4 推荐系统应用 2. 在其他领域的应用2.1 企业营销2.2 智慧交通 1. 在互联网中的应用 1.1 推荐系统 1. 推荐系统产生&#xff1a;  (1) 互联网的飞速发展使我们进入了信息过载的时代&#xff0c;搜索…

【赠书第17期】Excel高效办公:文秘与行政办公(AI版)

文章目录 前言 1 了解Excel的强大功能和工具 2 提升Excel技能的方法 3 结合AI技术提升Excel应用 4 注意事项 5 推荐图书 6 粉丝福利 前言 随着人工智能&#xff08;AI&#xff09;技术的快速发展&#xff0c;我们的工作方式也在发生深刻变革。其中&#xff0c;Excel 作…

使用cmake进行完成开发实践

根据这个UML图进行cmake的实践 首先按照使用vscode在wsl2中配置clangd环境-CSDN博客的内容先创建出cmake项目。 之后在项目目录中创建include和src目录。 根据UML图&#xff0c;首先要完成Gun类的实现。分别在include&#xff0c;src目录下创建头文件和源文件&#xff0c;写入…

上位机图像处理和嵌入式模块部署(qt图像处理)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 很多人一想到图像处理&#xff0c;本能的第一反应就是opencv&#xff0c;这也没有错。但是呢&#xff0c;这里面还是有一个问题的&#xff0c;不知…

Leetcode刷题笔记题解(C++):LCR 174. 寻找二叉搜索树中的目标节点

思路&#xff1a;二叉搜索树的中序遍历是有序的从大到小的&#xff0c;故得出中序遍历的结果&#xff0c;即要第cnt大的数为倒数第cnt的数 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeN…

JUC并发编程-集合不安全情况以及Callable线程创建方式

6. 集合不安全 1&#xff09;List 不安全 //java.util.ConcurrentModificationException 并发修改异常&#xff01; public class ListTest {public static void main(String[] args) {List<Object> arrayList new ArrayList<>();for(int i1;i<30;i){new Thr…

​WordPress顶部管理工具栏怎么添加一二级自定义菜单?

默认情况下&#xff0c;WordPress前端和后台页面顶部都有一个“管理工具栏”&#xff0c;左侧一般就是站点名称、评论、新建&#xff0c;右侧就是您好&#xff0c;用户名称和头像。那么我们是否可以在这个管理工具栏中添加一些一二级自定义菜单呢&#xff1f; 其实&#xff0c…