Unity Meta Quest MR 开发(三):Scene API 配置+实现虚拟与现实之间的碰撞

news2024/12/27 3:17:49

文章目录

  • 📕教程说明
  • 📕 Scene 配置
    • ⭐开启场景理解功能和应用访问空间数据的权限
    • ⭐OVRSceneManager
    • ⭐制作 Plane Prefab 和 Volume Prefab
    • ⭐运行场景
    • ⭐添加透视材质
  • 📕虚拟与现实物体的碰撞(弹球 Demo)
  • 📕Mesh API

此教程相关的详细教案,文档,思维导图和工程文件会放入 Spatial XR 社区。这是一个高质量 XR 社区,博主目前在内担任 XR 开发的讲师。此外,该社区提供教程答疑、及时交流、进阶教程、外包、行业动态等服务。

社区链接:
Spatial XR 高级社区(知识星球)
Spatial XR 高级社区(爱发电)

在这里插入图片描述


📕教程说明

这期教程我将会介绍如何在 Unity 中,利用 Meta XR SDK 中的 Scene API,去使用 Meta Quest 中的空间设置和场景理解功能。最后我们会实现一个弹球 Demo,当虚拟小球碰撞到现实物体上会有反弹效果。

一体机开发环境配置可参考:https://blog.csdn.net/qq_46044366/article/details/133967343

配置一个基本的玩家物体可以参考前几期教程:https://blog.csdn.net/qq_46044366/article/details/134097455

MR 透视配置可参考:
https://blog.csdn.net/qq_46044366/article/details/135612769

系列教程专栏:https://blog.csdn.net/qq_46044366/category_12118293.html

配套的视频链接:
https://www.bilibili.com/video/BV1t7421K7em

​电脑操作系统:Windows 11

使用的 VR 设备:Meta Quest 3(Quest 系列都适用)

使用的 Unity 版本:2022.3.15 f1c1 LTS (这里推荐使用 2021 及以上的 LTS 版本)

Meta XR SDK 版本:v60

Meta Quest 系统需要是 v40 及以上

官方文档:https://developer.oculus.com/documentation/unity/unity-gs-overview/

官方 Scene API 配置文档:
https://developer.oculus.com/documentation/unity/unity-scene-gs/

OVRSceneManager 官方介绍:
https://developer.oculus.com/documentation/unity/unity-scene-use-scene-anchors/

最终效果:

在这里插入图片描述


📕 Scene 配置

⭐开启场景理解功能和应用访问空间数据的权限

在 OVRCameraRig 玩家物体的 OVRManager 脚本上,在 Quest Features 中将 Scene Support 设为 Supported 或者 Required,设置好之后 Anchor Support 会自动设为 Enabled

在这里插入图片描述

将界面继续往下拉,点开 Permission Requests On Startup,将 Scene 选项勾选上。

在这里插入图片描述

它的作用是:因为场景理解需要使用到用户的空间数据,这涉及到一些隐私政策,所以Meta 规定了如果应用使用了 Scene API,必须要让用户在第一次使用应用的时候,允许应用访问空间数据。

然后在 Unity 菜单栏点击 Oculus > Tools > Update AndroidManifest.xml

在这里插入图片描述

它会更新打包到安卓端的配置文件。这个时候如果将应用打包成 APK 文件,导入到头显中运行,就会看到 “允许这款应用访问你的空间数据” 的请求弹窗。

⭐OVRSceneManager

在 Unity 编辑器的 Project 窗口中搜索 OVRSceneManager 预制体,搜索时把搜索选项设为 All 或者 In Packages,因为这个预制体(Prefab)在 Packages 文件夹下。

在这里插入图片描述

然后将它拖到场景中。

在这里插入图片描述

可以看到这个物体身上的 OVR Scene Manager 脚本有两个空的参数:Plane Prefab。我们在上一期教程中有介绍过,场景理解可以使用 2D 平面或 3D 立方体来表示现实世界。因此 Plane Prefab 和 Volume Prefab 分别表示 2D 平面和 3D 立方体

⭐制作 Plane Prefab 和 Volume Prefab

首先我们来制作 Plane Prefab。在 Unity 的 Hierarchy 面板中创建一个空物体,名为 Plane Prefab。在该物体上添加 OVRSceneAnchor 脚本。

在这里插入图片描述

然后在该物体身上添加一个 Quad 子物体(鼠标右键 Plane Prefab,选择 3D Object > Quad)。Quad 物体就是一个方形的,只渲染一面的物体,刚好符合 2D 平面的样子。

在这里插入图片描述

删除 Quad 物体上的 Mesh Collider 组件,添加上 Box Collider 组件。因为 Box Collider 更贴合 Quad 物体。然后将 Quad 物体的 y轴上的旋转角度改为 180:

在这里插入图片描述

为什么要把 Quad 的 y 轴旋转角度改为 180 度呢?因为由 Meta 的 Scene API 创建出来的 2D 平面或 3D 立方体会有自己的坐标原点,叫做 Anchor Pivot,由 Quest 系统进行识别,但是需要注意的是 Pivot 的位置可能会和 Unity 里物体显示的坐标原点不一样。Meta 规定了由场景理解生成的 2D 平面的 Pivot 原点位于物体的中心,并且 z 轴会特定的朝向。如果 2D 平面代表地面,z 轴朝上。如果 2D 平面代表墙面,z 轴朝向房间内部。(下图里蓝色的轴为 z 轴朝向,红色为 x 轴,绿色为 y 轴)而 Quad 物体被渲染的那一面朝向自身 z 轴的负方向,所以要翻转 180 度,让 Quad 物体被渲染的那一面朝向 2D 平面的 z 轴的正方向。

在这里插入图片描述

在这里插入图片描述

Volume Prefab 的制作也是类似,在 Unity 的 Hierarchy 面板中创建一个空物体,名为 Volume Prefab。在该物体上添加 OVRSceneAnchor 脚本。然后在该物体身上添加一个 Cube 子物体(鼠标右键 Plane Prefab,选择 3D Object > Cube)。然后把 Cube 的 z 轴上的 position 改为 -0.5:

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

为什么把 Cube 的 z 轴上的 position 改为 -0.5 呢?因为 Meta 规定了由场景理解生成的 3D 立方体的 Pivot 原点位置位于物体上表面的中心,并且 z 轴朝上(如下图所示):

在这里插入图片描述
因此要让 Pivot Anchor 的坐标与 Volume Prefab 的坐标对齐,就需要将子物体往 z 轴负方向移动 0.5

做好 Plane Prefab 和 Volume Prefab 后将它们拖入任意文件夹下做成 Prefab 预制体,然后把它们分别拖到 OVRSceneManager 脚本的 Plane Prefab 和 Volume Prefab 参数上:

在这里插入图片描述

⭐运行场景

这个时候就可以尝试运行场景。不过要注意的是一定要确保自己的设备已经进行过了空间设置。可以在 Quest 系统内的“设置面板->实际空间->空间设置”找到。

在这里插入图片描述

在这里插入图片描述

并且串流模式下是无法进行空间设置的,所以如果设备已经串流了但是还没有进行空间设置,需要先取消串流,然后在系统内进行设置。

如果运行后遇到如下图所示的弹窗报错 “Scene Capture does not work over link”

在这里插入图片描述

需要确保设备是否进行过了空间设置。如果确保设置过了但仍然跳出这个弹窗,可以尝试退出运行模式然后再次运行,一般第二次运行就能正常进入。

当你看到场景中多了一个 Room 物体,就代表在空间设置中记录的场景模型已经成功在 Unity 场景中被创建出来了。
在这里插入图片描述

这个 Room 物体就近似于自己在空间设置中为房间建立的房间布局,它的子物体由 Plane Prefab 和 Volume Prefab 组成,Plane Prefab 包含在空间设置中建立的墙面,地板和天花板,或者自己手动标定的 2D 平面。Volume Prefab 包含了自己在空间设置中手动标定的 3D 立方体。

但是这里大家可能有疑问:之前我们配置了 MR 透视的功能,但是此时我们戴上头显后只能看到虚拟的房间,而看不到透视的现实场景,这是为什么呢?

实际上虚拟房间的外面就全是透视的现实场景,只不过我们被包在了虚拟房间当中,看到的自然是虚拟的场景。那么我们要怎么做才能看到现实场景呢?

⭐添加透视材质

我们可以把 Plane Prefab 和 Volume Prefab 的材质替换成透视材质。我们可以在 Project 窗口的搜索栏中搜索 SelectivePassthrough,可以在 Packages 文件夹下找到这个材质。

在这里插入图片描述

我自己是习惯创建一个和这个官方透视材质一模一样的材质,这样后续可以对材质做一些自定义的设置。那么我在 Assets 文件夹下的任意一个文件夹中创建了一个材质,叫做 CustomSelectivePassthrough,然后把 Shader 改成 Oculus/SelectivePassthrough,Render Queue 可以模仿官方透视材质设为5000。Render Queue 越大,越后渲染。设为 5000 就会比其他所有的物体后渲染。当然这个值也能根据自己的渲染需求更改。如果在场景中看不到某个材质,可以尝试让透视材质的 Render Queue 小于该材质的 Render Queue;如果场景中某个位于透视材质后面的材质仍然显示了出来(正常情况下位于前面的材质会遮挡位于后面的材质),可以尝试让透视材质的 Render Queue 大于该材质的 Render Queue

在这里插入图片描述

如果想要实现需要透视材质的物体遮挡住虚拟物体,可以如上图所示将 Blend Color 从原来的 ReverseSubstract 改为 Substract。

然后将 Plane Prefab 中的 Quad 子物体身上的 Mesh Renderer 的 Materials 修改成我们自定义的透视材质。Volume Prefab 同理。

在这里插入图片描述

现在运行程序,就能看到现实环境了。

📕虚拟与现实物体的碰撞(弹球 Demo)

因为用来表示现实世界的 2D 平面和 3D 立方体具有碰撞体,那么在 Unity 中,如果两个物体都有碰撞体,且至少其中一个物体有刚体,就能够发生碰撞,所以我们是能够用这个特性来实现虚拟与现实物体之间的碰撞,本质上还是虚拟物体与虚拟平面或立方体发生碰撞。

我这边是制作了一个弹球 Demo:可以用手将球从远距离或者近距离抓取到手上。然后把球扔到现实中的墙壁,地板等物体时,会产生反弹效果。

在这里插入图片描述

小球的抓取交互用上了我之前出过的手势追踪交互里的知识点,比如 Hand Grab,Distance Hand Grab, 交互事件等。我会把完整的制作过程发布到我们 Spatial XR 社区里。

配置好小球的抓取功能后,我们给小球添加上更好的弹力效果。

首先我们创建一个 Physic Material 物理材质:

在这里插入图片描述

修改物理材质的参数:

在这里插入图片描述

Bounciness 参数越大,弹力效果越强。然后我们把这个物理材质添加给小球的碰撞体:

在这里插入图片描述

最终效果:

在这里插入图片描述

📕Mesh API

Meta Quest 3 有一个场景扫描的功能(或者 Meta 在未来推出的设备也可能有这个功能),可以在空间设置的时候为扫描过的现实物体建立场景网格(Scene Mesh),场景网格也会作为场景模型中的一部分数据。场景网格由不同的三角面组成(如下图所示):

在这里插入图片描述

Meta XR SDK 使用的是 Mesh API 来访问场景网格。如果为场景网格添加上碰撞体,那么也能实现虚拟与现实物体之间的碰撞。

我们可以如下图所示制作一个 Prefab:

在这里插入图片描述

然后在 OVRSceneManager 的 Prefab Overrides 中新增一个元素,将 GLOBAL_MESH 替换成我们刚刚创建的 Global Mesh Collider:

在这里插入图片描述

Global Mesh Collider 具有碰撞体,而它会作为 GLOBAL_MESH,也就是场景网格。因此场景网格也具有了碰撞效果。

在 Quest 3 的场景扫描功能推出之前,我们只能用一个个具有碰撞效果的 2D 平面和 3D 物体来表示现实中的物体,从而实现虚拟与现实物体之间的碰撞。但是有了场景扫描的功能后,只要现实物体被覆盖上了带有碰撞体的场景网格,就会具有碰撞效果。

这样的好处是:

  1. 空间设置的过程更加方便省事
  2. 能够实现更加精确的基于现实物体的碰撞

在这里插入图片描述

如上图所示,我们可以在串流调试下看到 Unity 场景中生成的绿色场景网格。

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

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

相关文章

两数之和 - 暴力枚举+哈希表

两数之和原题地址 方法一:暴力枚举 首先,我们需要枚举数组中所有可能的下标对组合,对于n个数的数组,从中选2个下标,有种可能。做法很简单,遍历数组中的所有元素,对于每一个元素,遍…

yo!这里是c++IO流相关介绍

目录 前言 C语言的输入输出 CIO流基本介绍 流的概念 IO流类库 iostream fstream stringstream 后记 前言 学过C语言的输入输出相关知识点的童鞋应该多多少少会觉得有些许麻烦,反正我就是这么觉得的,scanf、printf等函数不仅数量众多&#xff0c…

RNN实战具体跑的代码

一、首先先上代码:这个是接pytorch API的调用代码 import torch import torch.nn as nn bs, T 2,3#批次大小,输入序列长度 input_size,hidden_size2,3#输入特征大小,隐含层特征大小 input torch.randn(bs,T, input_size) h_prev torch.ze…

css新手教程

css新手教程 课程:14、盒子模型及边框使用_哔哩哔哩_bilibili 一.什么是CSS 1.什么是CSS Cascading Style Sheet 层叠样式表。 CSS:表现(美化网页) 字体,颜色,边距,高度,宽度&am…

用户体验优化:HubSpot的秘密武器

在当今数字化市场中,提升用户体验已经成为企业成功的关键因素之一。HubSpot,作为一款领先的营销自动化工具,不仅在推动销售业绩上表现出色,同时通过其独特的策略也致力于提升用户体验。运营坛将深入探讨HubSpot是如何通过个性化推…

Leetcode92:反转链表II(区间反转链表)

一、题目 给你单链表的头指针 head 和两个整数 left 和 right &#xff0c;其中 left < right 。请你反转从位置 left 到位置 right 的链表节点&#xff0c;返回 反转后的链表 。 示例&#xff1a; 输入&#xff1a;head [1,2,3,4,5], left 2, right 4 输出&#xff1a…

Redisson看门狗机制

一、背景 网上redis分布式锁的工具方法&#xff0c;大都满足互斥、防止死锁的特性&#xff0c;有些工具方法会满足可重入特性。如果只满足上述3种特性会有哪些隐患呢&#xff1f;redis分布式锁无法自动续期&#xff0c;比如&#xff0c;一个锁设置了1分钟超时释放&#xff0c;…

Servlet+Ajax实现对数据的列表展示(极简入门)

目录 1.准备工作 1.数据库源&#xff08;这里以Mysql为例&#xff09; 2.映射实体类 3.模拟三层架构&#xff08;Dao、Service、Controller&#xff09; Dao接口 Dao实现 Service实现&#xff08;这里省略Service接口&#xff09; Controller层&#xff08;或叫Servlet层…

Vulnhub billu b0x

0x01 环境搭建 1. 从官方下载靶机环境&#xff0c;解压到本地&#xff0c;双击OVF文件直接导入到vmware虚拟机里面。2. 将虚拟机的网络适配器调成NAT模式&#xff0c;然后开机即可进行操作了。 0x02 主机发现 nmap -sn 192.168.2.0/24 成功获取靶机IP为192.168.2.129。 0x0…

网络时间协议NTP工作模式

单播服务器/客户端模式 单播服务器/客户端模式运行在同步子网中层数较高层上。这种模式下,需要预先知道服务器的IP地址。 客户端:运行在客户端模式的主机(简称客户端)定期向服务器端发送报文,报文中的Mode字段设置为3(客户端模式)。当客户端接收到应答报文时,客户端会…

指针2 1月31日学习笔记

一、strncpy、strncmp、strncat函数 strncpy函数用于将一个字符串的一部分拷贝到另一个字符串中。 char* strncpy(char *dest, const char *src, size_t n){size_t i;for (i 0; i < n && src[i] ! \0; i)dest[i] src[i];for ( ; i < n; i)dest[i] \0;return …

2024牛客寒假算法基础集训营1部分题解

// 能力有限&#xff0c;做多少发多少。 A-DFS搜索 题目描述 最近&#xff0c;fried-chicken完全学明白了DFS搜索&#xff08;如上图所示&#xff09;&#xff01;于是学弟向他请教DFS搜索&#xff0c;fried-chicken热心的进行了讲解&#xff1a; 所谓DFS搜索&#xff0c;就…

上海纽约大学信息技术部高级主任常潘:解密大数据引领的未来教育革命

大数据产业创新服务媒体 ——聚焦数据 改变商业 在数字化时代&#xff0c;大数据技术的应用已经深刻地改变着各行各业。特别是在教育领域&#xff0c;智慧校园建设作为现代化校园的代名词&#xff0c;正迎来大数据技术的巨大机遇。 1月17日&#xff0c;上海纽约大学信息技术部…

嵌入式软件工程师面试题——嵌入式专题(五十二)

说明&#xff1a; 面试群&#xff0c;群号&#xff1a; 228447240面试题来源于网络书籍&#xff0c;公司题目以及博主原创或修改&#xff08;题目大部分来源于各种公司&#xff09;&#xff1b;文中很多题目&#xff0c;或许大家直接编译器写完&#xff0c;1分钟就出结果了。但…

EtherCAT转ModbusTCP网关

一、功能概述 1.1设备简介 本产品是EtherCAT和Modbus TCP网关&#xff0c;使用数据映射方式工作。 本产品在EtherCAT侧作为EtherCAT从站&#xff0c;接TwinCAT、CodeSYS、PLC等&#xff1b;在ModbusTCP侧做为ModbusTCP主站&#xff08;Client&#xff09;或从站&#xff08;…

【蓝桥杯冲冲冲】[NOIP2003 普及组] 数字游戏

蓝桥杯备赛 | 洛谷做题打卡day25 文章目录 蓝桥杯备赛 | 洛谷做题打卡day25[NOIP2003 普及组] 数字游戏题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示思路 题解代码我的一些话 [NOIP2003 普及组] 数字游戏 题目描述 丁丁最近沉迷于一个数字游戏之中。这个游戏看…

MySQL for update锁表还是锁行校验

select * from user where id 1 for update ; 1. for update作用 在MySQL中&#xff0c;使用for update子句可以对查询结果集进行行级锁定&#xff0c;以便在事务中对这些行进行更新或者防止其他事务对这些行进行修改。 当使用for update时&#xff0c;锁定行的方式取决于wh…

【初中生讲机器学习】4. 支持向量机算法怎么用?一个实例带你看懂!

创建时间&#xff1a;2024-02-02 最后编辑时间&#xff1a;2024-02-03 作者&#xff1a;Geeker_LStar 你好呀~这里是 Geeker_LStar 的人工智能学习专栏&#xff0c;很高兴遇见你~ 我是 Geeker_LStar&#xff0c;一名初三学生&#xff0c;热爱计算机和数学&#xff0c;我们一起加…

【八大排序】冒泡排序 | 快速排序 + 图文详解!!

&#x1f4f7; 江池俊&#xff1a; 个人主页 &#x1f525;个人专栏&#xff1a; ✅数据结构冒险记 ✅C语言进阶之路 &#x1f305; 有航道的人&#xff0c;再渺小也不会迷途。 文章目录 交换排序一、冒泡排序1.1 算法步骤 动图演示1.2 冒泡排序的效率分析1.3 代码实现1.4 …

HSRP配置指南

实验大纲 第 1 部分&#xff1a;验证连通性 步骤 1&#xff1a;追踪从 PC-A 到 Web 服务器的路径 步骤 2&#xff1a;追踪从 PC-B 到 Web 服务器的路径 步骤 3&#xff1a;观察当 R3 不可用时&#xff0c;网络的行为 第 2 部分&#xff1a;配置 HSRP 主用和 备用路由器 步…