当前位置: 首页 > news >正文

Unity VR开发教程 OpenXR+XR Interaction Toolkit 番外(一)用 Grip 键, Trigger 键和摇杆控制手部动画

文章目录

  • 📕制作手部动画
  • 📕设置 Animation Controller
  • 📕添加触摸摇杆的 Input Action
  • 📕代码部分

在大部分 VR 游戏中,手部的动画通常是由手柄的三个按键来控制的。比如 Grip 键控制中指、无名指、小拇指的弯曲,Trigger 键控制食指的弯曲,触摸摇杆控制大拇指的弯曲。

这个教程,我将介绍如何利用这三个按键的输入来控制手部动画。原理和我之前写的一篇教程“Unity VR开发教程 OpenXR+XR Interaction Toolkit (二) 手部动画”是类似的,只不过 Animation Controller 和相关脚本会有一些变化。

项目源码(持续更新):https://github.com/YY-nb/Unity_XRInteractionToolkit2.3.2_Demo (场景位于 Asset/Scene/Extra/01.Hand(New),脚本位于 Asset/Scripts/Extra/01.Hand(New),手部模型和相应的动画位于 Asset/Oculus Hands 中。

效果图:

在这里插入图片描述


📕制作手部动画

在我之前写的手部动画教程中,我创建了两种手部动画(握拳和捏合),分别由手柄的 Grip 键和 Trigger 键来控制。这篇教程我们将创建三种手部动画,用 Grip 键控制中指、无名指、小拇指的弯曲,Trigger 键控制食指的弯曲,触摸摇杆控制大拇指的弯曲。创建动画的原理是类似的,我们需要用 Unity 的 Animation 窗口来录制关键帧,制作手势的动画。我们可以直接点击 Hirerarchy 窗口中的手部模型,然后点击 Unity 编辑器菜单栏上方的 Window -> Animation -> Animation 打开 Animation 窗口:

在这里插入图片描述

在这里插入图片描述

然后就可以在 Animation 窗口中录制动画了,简单来说就是在关键帧中修改需要弯曲的手指的 Transform,我这边是已经有现成的动画了,如果小伙伴们想制作自己的手部动画,可以去搜索 Animation 录制的相关教程,这里就不作详细介绍了。

按下 Grip 键的动画:

在这里插入图片描述

按下 Trigger 键的动画:

在这里插入图片描述

触摸摇杆的动画:

在这里插入图片描述

需要特别注意的是:

  1. 左右手都要准备相应的动画,我这边就是要准备 3×2=6 个动画
  2. 在一个手部动画中,如果有手指是不需要弯曲的,就不要在 Animation 窗口中添加它的 Transform。比如我想制作 Trigger 动画,我只需要弯曲食指,所以在关键帧中需要对食指的 Transform 进行修改。而其他手指保持默认的状态,也就是说它们的 Transform 保持不变,那么我是不需要将这些手指的 Transform 添加到关键帧中的。因此在我的项目里,“按下 Trigger 键”的动画只有 Index (食指)的 Transform 被添加到了 Aniamtion 的 Property 中。这样是为了避免之后不同动画混合后产生的动画覆盖问题。

在这里插入图片描述

📕设置 Animation Controller

分别为左右手创建 Animation Controller,然后添加到手部模型的 Animator 组件中,我以左手为例:

在这里插入图片描述

Animation Controller:

在这里插入图片描述

我们需要点击 Layers 的 “+” 号,额外添加三个动画层,分别对应按下 Grip 键,按下 Trigger 键,触摸摇杆(为了实现我们的需求,Animation Controller 可以有很多中设置方式,我这里提供我的一种实现方式)

Base Layer 按照默认的就行,无需添加任何动画。重要的是新添加的三个动画层。

首先在 Parameters 中添加三个 Float 类型的参数:

在这里插入图片描述

然后我们将这三个动画层的权重设为 1,以 Grip Layer 为例:

在这里插入图片描述

接下来我们需要设置三个动画层的动画和状态连线。

Grip Layer:

在这里插入图片描述

首先创建一个空状态,然后创建一个 Blend Tree,将这两个状态进行连线。状态切换的条件如下(记得取消勾选 Has Exit Time):

在这里插入图片描述

在这里插入图片描述

然后我们看看这个 Blend Tree 长什么样:

在这里插入图片描述

我这里把 Blend Type 设为了 Direct,创建 Blend Tree 的目的是让手部动画有个平滑的过渡。Direct 直接混合可以直接将animator的参数映射到混合树动画的权重,也就是用参数精确控制混合的动画,而不是通过以两个参数间接控制动画的混合。

然后将按下左手 Grip 键的动画添加到上图所示的 Motion 中

Trigger Layer:

原理和 Grip Layer 是一样的。

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

Thumb Layer:

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

右手也是同理。


📕添加触摸摇杆的 Input Action

那么,程序要怎么知道我们触摸了手柄的摇杆呢?这里需要用到 Unity 的 Input System。XR Interaction Toolkit 提供了一个 Input Action Asset ,我们可以在里面配置各种输入和动作的映射关系。

在这里插入图片描述

我还是以左手为例,按下 Grip 键和按下 Trigger 键对应了 XRI LeftHand Interaction 中的 Select Value 和 Activate Value,选 Value 是因为按键会有个按下的程度,是个具体的值。

在这里插入图片描述

但是默认的 Action 并没有和“触摸摇杆”绑定的,所以我们需要手动配置。首先点击 Actions 旁的 “+” 号,添加一个 Action,我将它命名为 Thumb Value,然后将 Action Properties 中的 Action Type 改为 Value:

在这里插入图片描述

然后点击 Thumb Value 下的 Binding,设置 Binding 的 Path:

在这里插入图片描述

这个 Path 位于 XR Controller/XR Controller(Left Hand)/Optional Controls/thumbstick Touched

最后,别忘了保存我们新添加的 Action


📕代码部分

配置了 Action 后,我们需要用代码来判断 Action 是否被触发,然后根据从 Action 获取到的值来控制动画。

我们创建一个脚本,分别挂载到左手和右手的模型上。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;public class NewAnimateHandController : MonoBehaviour
{public InputActionProperty triggerActionProperty;public InputActionProperty gripActionProperty;public InputActionProperty thumbActionProperty;private InputAction pinchAction;private InputAction gripAction;private InputAction thumbAction;private Animator animator;private string triggerName = "Trigger";private string gripName = "Grip";private string thumbName = "Thumb";void Start(){pinchAction = triggerActionProperty.action;gripAction = gripActionProperty.action;thumbAction = thumbActionProperty.action;animator = GetComponent<Animator>();}void Update(){float gripValue = gripAction.ReadValue<float>();animator.SetFloat(gripName, gripValue);float triggerValue = pinchAction.ReadValue<float>();animator.SetFloat(triggerName, triggerValue);float thumbValue = thumbAction.ReadValue<float>();animator.SetFloat(thumbName, thumbValue);}
}

然后在 Inspector 面板中添加 Action 的引用(以左手为例):

最终效果:

在这里插入图片描述

相关文章:

Unity VR开发教程 OpenXR+XR Interaction Toolkit 番外(一)用 Grip 键, Trigger 键和摇杆控制手部动画

文章目录 &#x1f4d5;制作手部动画&#x1f4d5;设置 Animation Controller&#x1f4d5;添加触摸摇杆的 Input Action&#x1f4d5;代码部分 在大部分 VR 游戏中&#xff0c;手部的动画通常是由手柄的三个按键来控制的。比如 Grip 键控制中指、无名指、小拇指的弯曲&#xf…...

H.265/HEVC编码原理及其处理流程的分析

H.265/HEVC编码原理及其处理流程的分析 H.265/HEVC编码的框架图&#xff0c;查了很多资料都没搞明白&#xff0c;各个模块的处理的分析网上有很多&#xff0c;很少有把这个流程串起来的。本文的主要目的是讲清楚H.265/HEVC视频编码的处理流程&#xff0c;不涉及复杂的计算过程。…...

数据结构初阶--链表OJⅡ

目录 前言相交链表思路分析代码实现 环形链表思路分析代码实现 环形链表Ⅱ思路分析代码实现 复制带随机指针的链表思路分析代码实现 前言 本篇文章承接上篇博客&#xff0c;继续对部分经典链表OJ题进行讲解 相交链表 先来看题目描述 思路分析 这道题我们还是首先来判断一…...

离职or苟住?

面对不太好的大环境&#xff0c;我们什么时候该离职&#xff0c;什么时候不应该离职呢&#xff1f;分享几个观点&#xff0c;希望对你有所启发。 以前就有大佬讲过&#xff0c;离职无非是两个原因&#xff0c;一是因为薪资不到位&#xff0c;二是因为受委屈了&#xff0c;总之&…...

微服务之以nacos注册中心,以gateway路由转发服务调用实例(第一篇)

实现以nacos为注册中心,网关路由转发调用 项目版本汇总项目初始化新建仓库拉取仓库项目父工程pom初始化依赖版本选择pom文件如下 网关服务构建pom文件启动类配置文件YMLnacos启动新建命名空间配置网关yml(nacos)网关服务启动 用户服务构建pom文件启动类配置文件YML新增url接口配…...

主成分分析(PCA)直观理解与数学推导

近期在完成信息论的作业&#xff0c;发现网上的资料大多是直观解释&#xff0c;对其中的数学原理介绍甚少&#xff0c;并且只介绍了向量降维&#xff0c;而没有介绍向量重构的问题&#xff08;重构指的是&#xff1a;根据降维后的低维向量来恢复原始向量&#xff09;&#xff0…...

什么是合伙企业?普通合伙和有限合伙区别?

1.什么是合伙企业? 合伙企业是指由各合伙人订立合伙协议&#xff0c;共同出资&#xff0c;共同经营&#xff0c;共享收益&#xff0c;共担风险&#xff0c;并对企业债务承担无限连带责任的营利性组织。合伙企业一般无法人资格&#xff0c;不缴纳企业所得税&#xff0c;缴纳个…...

系统结构考点之不明白的点

系统结构考点系列 计算机系统结构的定义计算机组成的定义计算机实现的定义计算系统的定量设计&#xff1f;1. 哈夫曼压缩原理2. Amdahl定律3. cpu性能公式4. 程序访问局部性定理 ​ 这样的题已经不多了&#xff0c;主要是要了解下概念。打下一个好的基础。 2023年4月份成绩已经…...

Android中AIDL的简单使用(Hello world)

AIDL&#xff1a;Android Interface Definition Language&#xff08;Android接口定义语言&#xff09; 作用&#xff1a;跨进程通讯。如A应用调用B应用提供的接口 代码实现过程简述&#xff1a; A应用创建aidl接口&#xff0c;并且创建一个Service来实现这个接口&#xff08…...

ZED使用指南(五)Camera Controls

七、其他 1、相机控制 &#xff08;1&#xff09;选择视频模式 左右视频帧同步&#xff0c;以并排格式作为单个未压缩视频帧流式传输。 在ZED Explorer或者使用API可以改变视频的分辨率和帧率。 &#xff08;2&#xff09;选择输出视图 ZED能以不同的格式输出图像&#xf…...

wrk泛洪攻击监控脚本

wrk泛洪攻击介绍 WRK泛洪攻击&#xff08;WRK Flood Attack&#xff09;是一种基于WRK工具进行的DDoS攻击&#xff08;分布式拒绝服务攻击&#xff09;。WRK是一个高度并行的HTTP负载生成器&#xff0c;可以模拟大量用户访问一个网站&#xff0c;从而导致该网站服务器瘫痪或失效…...

软件I2C读写MPU6050代码

1、硬件电路 SCL引到了STM32的PB10号引脚&#xff0c;SDA引到了PB11号引脚软件I2C协议&#xff1a; 用普通GPIO口&#xff0c;手动反转电平实现协议&#xff0c;不需要STM32内部的外设资源支持&#xff0c;故端口是可以任意指定MPU605在SCL和SDA自带了两个上拉电阻&#xff0c;…...

销售/回收DSOS254A是德keysight MSOS254A混合信号示波器

Agilent DSOS254A、Keysight MSOS254A、 混合信号示波器&#xff0c;2.5 GHz&#xff0c;20 GSa/s&#xff0c;4 通道&#xff0c;16 数字通道。 ​Infiniium S 系列示波器 信号保真度方面树立新标杆 500 MHz 至 8 GHz 出色的信号完整性使您可以看到真实显示的信号&#xff1…...

RIDGID里奇金属管线检测仪故障定位仪维修SR-20KIT

里奇RIDGID管线定位仪/检测仪/探测仪维修SR-20 SR-24 SR-60 美国里奇SeekTech SR-20管线定位仪对于初次使用定位仪的用户或经验丰富的用户&#xff0c;都同样可以轻易上手使用SR-20。SR-20提供许多设置和参数&#xff0c;使得大多数复杂的定位工作变得很容易。此外&#xff0c…...

NodeJs之调试

关于调试 当我们只专注于前端的时候&#xff0c;我们习惯性F12&#xff0c;这会给我们带来安全与舒心的感觉。 但是当我们使用NodeJs来开发后台的时候&#xff0c;我想噩梦来了。 但是也别泰国担心&#xff0c;NodeJs的调试是很不方便&#xff01;这是肯定的。 但是还好&…...

Java面试知识点(全)- Java并发-多线程JUC二-原子类/锁

Java面试知识点(全) 导航&#xff1a; https://nanxiang.blog.csdn.net/article/details/130640392 注&#xff1a;随时更新 JUC原子类 什么是CAS CAS的全称为Compare-And-Swap&#xff0c;直译就是对比交换。是一条CPU的原子指令&#xff0c;其作用是让CPU先进行比较两个值…...

CSS--移动web基础

01-移动 Web 基础 谷歌模拟器 模拟移动设备&#xff0c;方便查看页面效果 屏幕分辨率 分类&#xff1a; 物理分辨率&#xff1a;硬件分辨率&#xff08;出厂设置&#xff09;逻辑分辨率&#xff1a;软件 / 驱动设置 结论&#xff1a;制作网页参考 逻辑分辨率 视口 作用&a…...

Appuploader 常见错误及解决方法

转载&#xff1a;Appuploader 常见错误及解决方法 问题解决秘籍 遇到问题&#xff0c;第一个请登录苹果开发者官网 检查一遍账号是否有权限&#xff0c;是否被停用&#xff0c;是否过期&#xff0c;是否有协议需要同意&#xff0c;并且在右上角切换账号后检查所有关联的账号是否…...

消息通知之系统层事件发布相关流程

前言 Openharmony 3.1Release中存在消息通知的处理&#xff0c;消息通知包括系统层事件发布、消息订阅、消息投递与处理&#xff0c;为了开发者能够熟悉消息的处理流程&#xff0c;本篇文章主要介绍系统层事件发布的相关流程。 整体流程 代码流程 发布消息 { eventAction)w…...

Elsevier Ocean Engineering Guide for Authors 解读

文章目录 ★Types of contributions★Submission checklistEthics in publishing★Declaration of competing interestDeclaration of generative AI in scientific writingSubmission declaration and verificationPreprint posting on SSRNUse of inclusive languageReportin…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

C++初阶-list的底层

目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1)&#xff1a;从基础到实战的深度解析-CSDN博客&#xff0c;但实际面试中&#xff0c;企业更关注候选人对复杂场景的应对能力&#xff08;如多设备并发扫描、低功耗与高发现率的平衡&#xff09;和前沿技术的…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

生成 Git SSH 证书

&#x1f511; 1. ​​生成 SSH 密钥对​​ 在终端&#xff08;Windows 使用 Git Bash&#xff0c;Mac/Linux 使用 Terminal&#xff09;执行命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" ​​参数说明​​&#xff1a; -t rsa&#x…...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...

NFT模式:数字资产确权与链游经济系统构建

NFT模式&#xff1a;数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新&#xff1a;构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议&#xff1a;基于LayerZero协议实现以太坊、Solana等公链资产互通&#xff0c;通过零知…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)

骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术&#xff0c;它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton)&#xff1a;由层级结构的骨头组成&#xff0c;类似于人体骨骼蒙皮 (Mesh Skinning)&#xff1a;将模型网格顶点绑定到骨骼上&#xff0c;使骨骼移动…...

关于 WASM:1. WASM 基础原理

一、WASM 简介 1.1 WebAssembly 是什么&#xff1f; WebAssembly&#xff08;WASM&#xff09; 是一种能在现代浏览器中高效运行的二进制指令格式&#xff0c;它不是传统的编程语言&#xff0c;而是一种 低级字节码格式&#xff0c;可由高级语言&#xff08;如 C、C、Rust&am…...