Unity-XR-开发指南-全-
Unity XR 开发指南(全)
原文:
zh.annas-archive.org/md5/a5bc7963c54920c0d3fd1b03386c7bdf译者:飞龙
前言
你好,欢迎来到激动人心且不断发展的扩展现实(XR)开发世界!如果你对第一次尝试在 Unity 中进行 XR 开发既感到兴奋又感到紧张,你并不孤单。
但别担心——本书的主要目标是使 XR 开发对每个人来说都触手可及,无论是否有先前的经验。我们将使用简单的语言,提供生动的例子,并指导你完成每个步骤,从制作可抓取的对象到编写 C# 脚本以及将手部追踪集成到你的场景中。你甚至不需要访问 VR 头盔或 AR 兼容的手机来跟随;你可以使用笔记本电脑或 PC 上的模拟器测试大多数项目,确保对所有人都是可访问的。
在我们自己的 XR 开发之旅中,我们曾面临过花费无数小时试图让一个基本的 XR 体验工作的挫败感。现在,我们在诸如德国电信和弗劳恩霍夫 IGD 等知名公司和学术机构积累了丰富的经验,我们希望与您分享我们的知识。
这本书不仅是一本完整的指南,它将带你从 XR 开发或 Unity 的初学者水平提升到创建任何领域交互式 XR 应用程序的中级水平。其结构也旨在帮助你轻松访问 XR 相关技术以构建出色的 XR 应用程序,因此你无需像我们曾经做的那样不断在网上搜索答案。我们的目标不是将你的 XR 开发专长局限于特定用例,而是为你提供一系列工具,以便你可以不受限制地将任何 XR 项目变为现实。
我们很高兴与您一起开始这段旅程!
本书面向的对象
如果你是一名学生、专业人士,或者只是对探索 VR、MR 或 AR 感兴趣,这本书是为你量身定制的。无论你是否熟悉交互式媒体,或者只是刚开始,我们都会引导你轻松地在 Unity 中构建 XR 应用程序。没有 Unity 经验?没问题。我们涵盖了基础知识,为你提供开发交互式 VR、MR 和 AR 项目的技能。
本书涵盖的内容
第一章,XR 和 Unity 简介,是 Unity 中 XR 开发主题的一般介绍。本章解释了将 VR、MR 和 AR 带到现实中的各种方法。此外,Unity 在 XR 开发中的作用也被介绍。本章的主要目标是提供一个良好的起点,开始学习如何构建 XR 应用程序。
第二章,Unity 编辑器和场景创建,旨在帮助那些对 Unity 不熟悉的读者。它解释了如何安装 Unity Hub 和 Unity 编辑器,并提供了在 Unity 中创建基本场景的逐步指南。本章介绍了从照明和渲染到从 Unity 资产商店导入资产的基本概念,为你深入 XR 开发前提供所需的一切知识。
第三章, 《Unity 中的 VR 开发》,介绍了 XR 交互工具包的功能和组件,以及如何将其添加到 VR 场景中。在探索了从抓取到攀爬的不同类型的交互后,本章解释了如何测试和部署 VR 场景到 VR 头戴式设备或模拟器,如 XR 设备模拟器。
第四章, 《Unity 中的 AR 开发》,解释了如何使用 AR Foundation、ARKit 和 ARCore 在 Unity 中创建 AR 体验。在构建了您的第一个简单 AR 应用程序后,本章专注于直接在 PC 上使用 XR 模拟测试此应用程序,并将其部署到 Android 和 iOS 设备上。
第五章, 《构建交互式 VR 体验》, 解释了如何通过动画、按钮事件或 C#编程语言为场景添加交互性。尽管本章教授的是中级概念,但它对初学者友好,且不需要任何先前的 C#知识。
第六章, 《构建交互式 AR 体验》, 详细介绍了如何通过触摸控制和 UI 元素创建交互式 AR 应用程序。使用 C#编程语言,本章展示了如何构建与最先进的设计模式和商业 AR 应用程序的核心组件相一致的用户体验。
第七章, 《添加声音和视觉效果》,介绍了如何通过模拟现实生活中的物理现象来使 XR 场景更加沉浸和逼真。本章解释了声音理论的基础和粒子行为,并强调了如何在 Unity 环境中模拟这两种物理现象。通过一个动手项目,本章解释了如何将音频源、音频混音器和粒子系统添加到 XR 场景中,以及如何调整它们的属性,使它们尽可能逼真。
第八章, 《构建高级 XR 技术》, 介绍了高级 XR 技术,提升了任何 XR 应用程序的整体用户体验和沉浸感。具体来说,本章详细介绍了如何通过 XR 交互工具包将手部追踪或注视追踪支持添加到 VR 应用程序中,并解释了如何构建多人体验,用户可以通过简单的头像和手部动画相互看到对方。
第九章, 《XR 开发的最佳实践和未来趋势》,探讨了 XR 技术的当前和未来趋势。它提供了对 XR 研究和各行业 XR 公司的见解,并介绍了整个 XR 开发生命周期的最佳实践。为了总结这本书,本章介绍了 XR 开发的额外工具包和插件。这些资源非常适合在未来的 XR 项目中进一步探索,这些项目超出了本书所涵盖的内容。
为了充分利用这本书
如果你还没有在 PC 或笔记本电脑上安装 Unity,不要担心——我们将在第二章中引导你完成这个过程。
| 本书涵盖的软件/硬件 | 操作系统要求 |
|---|---|
| Unity 版本 2021.3.4 或更高版本 | Windows、macOS 或 Linux |
当你开始创建沉浸式虚拟、增强和混合现实体验时,正确设置基础至关重要。这从使用 Git LFS 克隆项目仓库开始。即使你计划从头开始构建所有项目,也强烈建议克隆整个仓库。无疑会有一些部分,将你的进度与实际解决方案进行交叉引用将非常有用。
注意
不要简单地以 ZIP 格式下载仓库。这样做很可能会在打开时出现错误。正确的方法是使用 Git LFS 克隆它。
当你在 Unity 中处理虚拟、增强和混合现实项目时,处理大文件是很常见的——想想 3D 模型、纹理、音频剪辑等等。简单地下载一个项目可能看起来是一个直接的方法,但你可能会遇到问题。原因在于 GitHub(以及许多其他平台)处理大文件的方式。
让我们用一个简单的类比来说明这一点。想象你有一个庞大的图书馆。与其把这些书都存放在家里,占用巨大的空间,不如为每本书都得到一张参考卡。每次你想读一本书时,你就在图书馆出示这张卡,他们就会为你提供这本书。
Git LFS(代表 Git 大型文件存储),其工作原理与此类似。Git LFS 不会直接在仓库中保存庞大的文件,而是维护一个微小的引用或“指针”。实际的庞大文件存储在其他地方。因此,当你直接下载一个未使用 LFS 的项目时,你只获得这些指针,而不是真正的文件。要获取完整内容,你必须使用 Git LFS 克隆项目。
Git LFS 的安装过程以及克隆我们的仓库非常简单。以下是一步一步的指南:
-
如果你使用 Homebrew,请在终端中运行
brew install git。对于基于 Debian 的发行版,使用你的包管理器,例如sudo apt-get install git。 -
git config --global user.name "Your Name"。使用git config --global配置你的电子邮件user.email "youremail@example.com"。 -
安装 Git LFS:访问官方 Git LFS 网站(
git-lfs.com/)并按照他们的安装说明进行操作。 -
git lfs install。这将为你的用户账户设置 Git LFS。 -
注册 GitHub:如果你还没有,请在 GitHub(
git-lfs.com/)上创建一个免费账户。 -
使用
git clonehttps://github.com/PacktPublishing/XR-Development-with-Unity.git命令。
就这样!你现在可以使用 Git 仓库和 Git LFS 来管理大文件了。
如果您正在使用本书的数字版,我们建议您亲自输入代码或从本书的 GitHub 仓库(下一节中提供链接)获取代码。这样做将帮助您避免与代码的复制和粘贴相关的任何潜在错误。
下载示例代码文件
您可以从 GitHub 下载本书的示例代码文件 github.com/PacktPublishing/XR-Development-with-Unity。如果代码有更新,它将在 GitHub 仓库中更新。请记住,按照之前描述的方法使用 Git LFS 进行克隆,而不是简单地下载 ZIP 格式的仓库。这样做将确保打开时没有错误。
我们还有其他来自我们丰富图书和视频目录的代码包可供选择,请访问 github.com/PacktPublishing/。查看它们吧!
其他资源
本书创建的项目演示视频可在 GitHub 仓库中找到:github.com/PacktPublishing/XR-Development-with-Unity/tree/main/Additional%20Resources
使用的约定
本书使用了多种文本约定。
文本中的代码:表示文本中的代码单词、数据库表名、文件夹名、文件名、文件扩展名、路径名、虚拟 URL、用户输入和 Twitter 昵称。以下是一个示例:“我们的最后一步是重写Update()函数。”
代码块应如下设置:
private void Update()
{
float scaleValue = slider.value;
bus.transform.localScale = new Vector3(scaleValue, scaleValue, scaleValue);
}
任何命令行输入或输出都应如下所示:
$ mkdir css
$ cd css
粗体:表示新术语、重要单词或屏幕上看到的单词。例如,菜单或对话框中的单词以粗体显示。以下是一个示例:“在 Unity Hub 中,导航到安装选项卡并点击添加按钮,以添加新的 Unity 编辑器版本。”
小贴士或重要提示
看起来像这样。
联系我们
欢迎读者反馈。
请将 customercare@packtpub.com 发送邮件,并在邮件主题中提及书籍标题。
勘误表:尽管我们已经尽一切努力确保内容的准确性,但错误仍然可能发生。如果您在本书中发现错误,我们将非常感激您向我们报告。请访问 www.packtpub.com/support/errata 并填写表格。
copyright@packt.com 并附上材料链接。
如果您有兴趣成为作者:如果您在某个领域有专业知识,并且有兴趣撰写或为书籍做出贡献,请访问 authors.packtpub.com。
分享您的想法
一旦您阅读了 XR Development with Unity,我们很乐意听听您的想法!请点击此处直接进入此书的亚马逊评论页面并分享您的反馈。
您的评论对我们和科技社区非常重要,并将帮助我们确保我们提供高质量的内容。
下载此书的免费 PDF 副本
感谢您购买此书!
你喜欢在路上阅读,但无法随身携带你的印刷书籍吗?
你的电子书购买是否与您选择的设备不兼容?
别担心,现在每购买一本 Packt 图书,您都可以免费获得该书的 DRM-free PDF 版本。
在任何地方、任何设备上阅读。直接从您最喜欢的技术书籍中搜索、复制和粘贴代码到您的应用程序中。
优惠远不止于此,您还可以获得独家折扣、时事通讯和每日免费内容的每日访问权限
按照以下简单步骤获取优惠:
- 扫描下面的二维码或访问以下链接

packt.link/free-ebook/9781805128120
-
提交您的购买证明
-
就这样!我们将直接将您的免费 PDF 和其他优惠发送到您的电子邮件中
第一部分 – 理解 XR 和 Unity 的基础知识
欢迎来到本书的第一部分,我们将为您提供关于扩展现实(XR)技术和 Unity 引擎的基本信息。本部分为后续部分 XR 应用程序开发之旅奠定基础。在这里,我们将指导您安装 Unity Hub 和 Unity 编辑器,并介绍场景创建、从 Unity Asset Store 下载资产、Unity 中可用的各种光源类型以及支持的渲染类型等重要概念。无需具备 Unity 或 XR 技术的先验知识即可跟随本部分。相反,本部分将为您提供开始动手 XR 开发冒险所需的所有必要知识。
本部分包括以下章节:
-
第一章,XR 和 Unity 简介
-
第二章,Unity 编辑器和场景创建
第一章:XR 与 Unity 简介
在本章中,我们将探讨XR 开发的非凡潜力以及作为该领域领先游戏引擎的Unity如何帮助我们解锁它。通过这次旅程,你将深入理解各种形式的扩展现实(XR)及其功能,为你创造沉浸式和难忘的体验铺平道路。你将发现 Unity 如何在全球范围内融合物理世界和数字世界方面发挥关键作用。让我们深入这个迷人的世界,发现等待我们的无限可能性。
在本章中,我们的讨论将包括以下主题:
-
理解 XR 及其不同形式(AR、MR 和 VR)
-
Unity 作为 XR 开发平台是如何演变的?
理解 XR 及其不同形式(VR、AR 和 MR)
XR 是一个包含一系列旨在增强我们感官的技术综合术语。无论是提供有关物理世界的额外信息,还是为我们创建全新的、可探索的模拟世界,XR 都包括虚拟现实(VR)、增强现实(AR)和混合现实(MR)技术。你可能已经佩戴过多个XR 头戴式设备,沉浸在像Beat Saber这样的VR 游戏中,或者甚至拥有自己的VR 头戴式设备。如果是这样,你对 XR 已经有了相当不错的了解。你可能知道,虽然 VR 意味着一种完全沉浸的体验,可以屏蔽物理世界,但 AR 和 MR 将真实世界与虚拟世界结合起来。然而,你能准确指出 AR 和 MR 之间的区别吗?
AR 和 MR 之间的区别是什么?
让我们通过一个例子来探讨这个问题——想象你正在佩戴一个Meta Quest 3头戴式设备。这个头戴式设备配备了允许透视功能的摄像头——这是一个功能,允许你在沉浸在虚拟环境的同时查看你的真实世界环境。当这些摄像头处于活动状态时,你实际上是在一个MR 体验中。例如,当你站在你的客厅里,你可能会在咖啡桌上看到一只古董花瓶。实际上,你的咖啡桌是真实的,但花瓶是一个通过 MR 无缝集成的虚拟对象。MR 的真正魔力在于其将数字世界和物理世界如此紧密地交织在一起,以至于很难区分它们。然而,当透视功能被禁用时,头戴式设备则回到一个纯粹的VR 体验,将你从物理世界的视角中分离出来。
与此相反,增强现实(AR)通过将数字信息投射到现实世界中,增强了我们对现实世界的体验。当佩戴增强现实眼镜,例如HoloLens或Magic Leap时,你视野中的真实元素和虚拟元素之间有明显的界限。例如,想象一下佩戴增强现实眼镜,看到互动标签在你的房间物体旁边悬浮,比如一个漂浮的便条提醒你给植物浇水,或者箭头指引你找到放错位置的东西。
此外,还有移动增强现实设备,通过智能手机或平板电脑屏幕体验增强。这些设备提供了增强世界的窗口式体验——例如,像宝可梦 GO这样的游戏,你使用智能手机的摄像头在现实世界中捕捉虚拟生物,或者一个应用程序让你在购买之前可视化家具在你的房间里的样子。
增强现实力求增强我们的当前现实,但混合现实(MR)则将想象的界限推向了极致,设想了一个真实和虚拟物体无缝融合的世界,而虚拟现实(VR)则完全创造了一个替代现实。许多人发现区分混合现实头盔和增强现实眼镜具有挑战性,但显示屏是一个良好的指示器。增强现实眼镜使用透明显示屏而不是摄像头,使它们能够直接访问现实世界的光线,实现数字叠加的无缝集成。相比之下,混合现实头盔允许用户通过额外的传感器和摄像头查看环境,但它们不提供直接访问阳光。这就像现实的一个光谱——一端是我们熟悉和真实的世界,通过数字元素微妙地增强;另一端是完全创造的世界,具有无限的探索和冒险潜力。而在两者之间,我们有一个神奇的空间,现实和虚拟在这里融合,无缝地融合了两个世界的最佳之处。你能猜出哪个想法最早可以追溯到——VR、AR 还是 MR?以及 XR 是如何进入画面的?
AR、VR、MR 和 XR 是如何演变的?
虽然到目前为止,虚拟现实(VR)无疑是这些技术中最先进的,但预测增强现实的是《奥兹国的奇妙魔法师》的作者 L. Frank Baum,他在 1901 年的小说《主钥匙:一个电气童话及其信徒的乐观主义》中预测了 AR。然而,直到半个世纪后,穿越虚拟领域和增强我们现实的最初愿望才真正起飞。
1962 年,莫顿·海利格推出了Sensorama——一种比现代 VR 头戴式设备更能刺激更多感官的设备。在 Sensorama 的一次体验中,你被传送到一个神话般的丛林,可以听到热带鸟的叫声,闻到湿润的土壤,在你沿着一条狭窄的小径漫步时,感受到脸上轻柔的微风。在另一次体验中,你骑着四轮摩托车穿越沙漠,通过鼻子吸入热岩石的气味,在转弯时感受到从不同角度吹来的风,并听着风在沙丘上流动和四轮摩托的生锈引擎交响乐。Sensorama 由一个立体彩色显示屏、风扇模拟风、化学物质产生的不同气味的气味发射器、一个可移动的椅子和立体声音频系统组成(www.youtube.com/watch?v=vSINEBZNCks)。
XR 技术的出现是一段崎岖且不可预测的旅程。在 Sensorama 的感官沉浸体验之后,它描绘了一个触手可及的混合现实壮丽图景,20 世纪 90 年代见证了 VR 领域布满了不幸装置的碎片,例如世嘉 VR和任天堂虚拟男孩。它们未能点燃消费者的想象力。因此,头戴式显示器(HMDs)的势头开始减弱。
这就是为什么印第安纳大学的研究人员发明了一种完全不同的 XR 技术,称为计算机自动虚拟环境(CAVE)。这项技术使得观众站在一个立方体内部,并戴着 3D 眼镜,可以看到投射到墙壁、天花板和地板上的任何 3D 图形,就像他们在太空中漂浮一样。用户可以在场景中漫步,从任何角度观察投射的物体。CAVE 通常可以容纳多达 10 人,他们可能都站在米开朗基罗的大卫雕像的虚拟复制品前,从任何角度欣赏这幅杰作,沉浸在唤起的情感过山车中,用他们的眼睛捕捉每一个细微的边缘。在重型的低分辨率 HMDs 是唯一替代品的时候,CAVE 使得高分辨率的 XR 体验成为可能,因此它们似乎在几年内成为了体验 XR 最有前途的方式。那么,哪些因素导致了 HMDs 在体验虚拟世界中的广泛应用,而看似更优越的 CAVE 却未能获得显著的市场份额?
安装一个 CAVE 需要一大笔钱,通常需要数十万美元,加上高昂的月度维护和使用成本。设置一个 CAVE 可能会让人筋疲力尽。你需要正确调整投影仪,添加适当的照明和空调,并协调一组计算机,以确保投影仪之间无缝同步。最重要的是,当涉及到需要用户与应用程序之间互动的多用户体验或沉浸式故事线时,CAVEs 显得力不从心:sky-real.com/news/the-vr-cave-halfway-between-reality-and-virtuality/ 和 web.archive.org/web/20070109083006/http://inkido.indiana.edu/a100/handouts/cave_out.html。
在经历了 XR 开发领域一个寒冷的冬天之后,这个冬天以对 CAVEs 的短暂兴奋和一系列失败的 HMDs 为标志,2000 年代初出现了一丝希望的光芒。2005 年,世界见证了第一个名为AR Tennis的AR 应用的诞生。这款游戏可以通过两部手机和一份冒险精神来玩,这两部手机是诺基亚手机。使用手机的摄像头跟踪一个标记,然后——看吧——一个网球场就在屏幕上出现了。两位参与者都可以与虚拟球、球场和对手互动,所有这些都在设备内部模拟。手机本身充当球拍,为玩家提供沉浸式的游戏体验(www.imgawards.com/games/ar-tennis/)。
2012 年,Palmer Luckey,因其开创性的工作而常被视为现代 VR 之父,通过推出一款名为Oculus Rift的众筹 VR 头盔,在 XR 开发领域又树立了一个里程碑。Luckey 创立了项目母公司Oculus VR,该公司最终在 2014 年被Facebook收购(history-computer.com/oculus-history/)。次年,Microsoft推出了革命性的HoloLens AR 头盔,它将高清晰度的全息影像与真实世界无缝融合(news.microsoft.com/en-au/2016/10/12/microsoft-announces-global-expansion-for-hololens/)。2016 年,Niantic发布了Pokémon Go,这款游戏最终赢得了数百万人的心,并引领了AR 游戏新时代的到来。这款游戏的流行像野火一样迅速蔓延到全球,点燃了人们对 AR 技术的新一轮兴奋和热情。
2017 年,IKEA推出了其著名的 AR 应用,允许客户超越想象的界限,看看 IKEA 的家具在家中会是什么样子,而无需离开他们舒适的沙发。
现在,我们来到了 XR 历史上的一个关键时刻,技术从未如此令人兴奋,可能性也从未如此无限。从其作为小众产业的朴素起点,XR 现在正准备爆炸式地融入我们生活的各个方面,就像创新和进步的超级新星。2021 年,马克·扎克伯格公布了其对未来的大胆愿景——一个沉浸式、实用的XR 设备不仅是一种新奇事物,而且也是提升我们生活质量和使我们的日常快乐更加非凡的必要工具。2022 年,Meta Quest Pro的发布标志着Meta首次涉足发布MR 头戴式设备,在他们的 VR 头戴式设备(如Meta Quest 2)占据了 81%的全球市场份额之后(www.counterpointresearch.com/global-xr-ar-vr-headsets-market-share/)。
然而,尽管 XR 技术变得更加先进和复杂,仍有一些人相信应该让它对所有人开放。开源增强现实社区(OpenAR)的创始人,一个致力于民主化 AR 的团体,创造了一款 DIY Open AR Glasses,这是一个预算友好的项目,任何人只需花费 20 欧元(sites.uef.fi/openar/ 和 openar.fi/)就能制作出自己的AR 眼镜。看到技术如何被用来让人们团结在一起,并使世界变得更美好,真是令人欣慰。
Unity 作为 XR 开发平台的演变历程是怎样的?
Unity Technologies,现在在游戏和 XR 领域成为了一个十亿美元的巨头,起源于 2004 年在哥本哈根一个舒适的公寓里的朴素起点。该公司以其Unity 游戏引擎主导市场的旅程,与 XR 技术的历程一样,充满了不确定性和动荡。
2002 年,一位丹麦的图形学学生在一个数字论坛上寻求帮助,一个有后端经验的柏林高中生加入了他的行列。巧合地将他们的游戏工作室梦想联系在一起。他们只有父亲的财务支持加上咖啡馆的工资,2005 年创造了他们的第一款游戏——一个被困在生命维持球体内的外星人,在地球上导航。玩家倾斜世界,外星人滚动,收集宝石并躲避 CIA 的捕捉,利用粘墙和跳跃技巧。游戏的难度掩盖了其尖端的光照效果,并且它并没有取得太大的成功。意识到他们在构建工具和原型方面的才能,这对搭档将精力重新集中在为 Mac 社区打造一个游戏引擎上,将其命名为 Unity——一个合作和兼容性的象征(techcrunch.com/2019/10/17/how-unity-built-the-worlds-most-popular-game-engine/)。
今天,Unity 在移动游戏创作领域的名声是传奇般的,这是有充分理由的。作为全球近一半游戏背后的建筑师,它成为了无数开发者向往的典范。然而,Unity 的影响力远不止于游戏。它越来越多地被用于电影、汽车和建筑等其他行业的 3D 设计和模拟。事实上,Unity 被用于创建全球 60%以上的 AR 和 VR 体验(www.dailydot.com/debug/unity-deempind-ai/)。
在高端电影制作的世界里,VR 和 Unity 游戏引擎是创作电影杰作的热门元素。迪士尼的奥斯卡获奖电影《狮子王》、斯皮尔伯格的《头号玩家》以及奥斯卡获奖电影《银翼杀手 2049》都归功于这些突破性技术(unity.com/madewith/virtual-cinematography)。《狮子王》作为照片现实主义动画领域的技术奇迹,也不例外。从每一根骨头和每一次呼吸到每一块肌肉和每一根胡须,非洲狮的每一个方面都被仔细观察并模拟在 Unity 中,尽可能模仿现实生活中的狮子,同时保留原始动画电影的特点(ai.umich.edu/blog-posts/how-disneys-the-lion-king-became-a-pioneer-in-the-use-of-virtual-reality/)。
除去电影制作领域,Unity 中的 XR 开发有潜力改变我们相互沟通和互动的方式。通过使用沉浸式虚拟环境和尖端的人工智能(AI)以及情感系统,XR 有能力创造非线性叙事、个性化体验和动态交互,模糊现实与幻想之间的界限。从教育和培训到游戏和社交媒体,XR 的可能性是无限的,而 Unity 正是这一激动人心的全新前沿的先锋。
Unity 中的 XR 开发实现了前所未有的体验,例如获奖的 VR 游戏《Bonfire》,在这个游戏中,你被困在一个荒凉的星球上,只有一簇闪烁的篝火。你的生存取决于与一个不会说任何已知语言的外星人建立联系,他完全依赖于你的非言语提示和手势。结果是神奇的非言语沟通,伴随着一个完全自然、非线性的故事情节,由复杂的 AI 和情感系统驱动,这些系统能够实时适应你的每一个动作。
Unity 的 XR 开发不仅改变了游戏行业,还彻底革新了医疗保健领域,正如VirtaMed的创新应用所展示的那样,这些应用改变了外科医生获取手术技能的方式。MR 模拟器模仿了真实手术操作的每一个动作,从最细微的动作到并发症,如意外出血和胆汁泄漏。每位学员的每一个动作都以毫米级的精度记录下来,提供了宝贵的反馈。模拟训练加速了有志成为外科医生的学员的学习曲线,使他们能够更有信心和技能地进入手术室。
摘要
本章向您介绍了 XR 的不同方面,即 AR、MR 和 VR。您学习了 AR 如何努力增强我们的现实,MR 如何推动想象的边界,以设想一个真实和虚拟物体无缝融合的世界,以及 VR 如何创造一个完全不同的现实。您现在理解了早期探索完全虚拟或增强现实的梦想如何转化为大胆的行动,以及 XR 开发过去和现在都不是一条简单的道路。您了解了 Unity,从其不起眼的起点到在全球游戏开发、模拟和 XR 开发中的全球主导地位,探讨了某些最先进的使用案例。下一章将向您介绍 Unity Hub 和编辑器。您将学习如何导入资产、创建材质以及获得您在开始开发第一个 XR 体验之前所需的所有其他技能。
第二章:Unity 编辑器和场景创建
在本章中,我们将为您 Unity 之旅打下基础。您将熟悉 Unity 编辑器,创建一个基本场景,并探索基本照明方面。我们将涵盖安装 Unity、导航编辑器、使用GameObject、导入资源和尝试各种照明设置。到那时,您将拥有深入 Unity 并创建越来越复杂和引人入胜场景的坚实基础。
我们将在接下来的内容中涵盖以下主题:
-
设置 Unity 开发环境
-
了解 Unity 编辑器和其界面
-
理解 GameObject 和组件
-
在 Unity 中创建基本场景并添加对象
技术要求
在深入 Unity 编辑器之前,确保您的系统满足运行 Unity 的最低要求非常重要。为了成功完成本章的练习,您需要一个已安装Unity 2021.3 LTS 或更高版本的计算机。为了确保您的硬件满足要求,您可以在 Unity 网站上交叉检查(docs.unity3d.com/Manual/system-requirements.html)。
设置 Unity 开发环境
首先,让我们在您的开发机器上启动 Unity。在整个本书中,我们将利用 Unity 3D 游戏引擎的强大功能来创建令人鼓舞的项目。Unity 是一个功能强大的跨平台 3D 开发环境,配备直观且视觉上吸引人的编辑器。
如果您尚未在计算机上安装 Unity,我们将引导您完成安装过程。安装完成后,我们将继续创建我们的初始场景。让我们开始设置和探索 Unity。
安装 Unity Hub
在本书的整个过程中,Unity Hub将成为您管理不同 Unity 项目、Unity 编辑器版本和模块的可靠指挥中心。要启动 Unity Hub 的安装过程,请按照以下步骤操作:
-
访问官方 Unity 网站(
unity3d.com/get-unity/download)并导航到最新版本的 Unity Hub。 -
按照屏幕上的说明安装 Unity Hub。
-
安装 Unity Hub 后,打开它并使用您的 Unity 账户登录。如果您是 Unity 的新用户,请创建一个账户以加入其他创作者的行列。
如果没有安装 Unity 编辑器,Unity Hub 就像没有 CD 的 CD 播放器一样强大。下一节将介绍如何在 Unity Hub 中安装 Unity 编辑器。
安装 Unity 编辑器
Unity 编辑器是魔法发生的地方——一个用于设计、构建和测试游戏项目的 workspace。要安装它,请按照以下步骤操作:
-
在 Unity Hub 中,导航到安装选项卡,然后点击添加按钮以添加新的 Unity 编辑器版本。
-
选择 Unity 编辑器的最新 LTS 版本,并点击下一步以启动安装过程。
-
在安装过程中,别忘了包括满足您特定需求的必要平台和模块。根据您 PC 的操作系统,添加Windows/Mac/Linux 构建支持。同样,根据您智能手机的性质,选择Android或iOS 构建支持,以便您能跟随本书中的 AR 教程。最后,如果您使用的是运行 Android 的 VR 头盔,例如Quest 2或Quest Pro,请务必添加Android 构建支持模块及其子模块:OpenJDK和Android SDK & NDK Tools。
由于我们已经安装了 Unity 编辑器,现在是时候创建一个项目了。
将示例场景作为新 Unity 项目加载
安装完 Unity Hub 和 Unity 编辑器后,现在是时候创建一个新的 Unity 项目了。为了简单起见,我们首先使用一个示例场景。Unity 中的示例场景是由 Unity 预先构建的场景,用于向开发者展示如何实现各种功能和技巧。Unity 提供了各种示例场景,从简单的 2D 游戏到复杂的 3D 环境,可以作为您自己项目的起点。示例场景可以通过资产商店或直接从 Unity Hub 下载。以下是直接从 Unity Hub 进行操作的方法。
图 2.1显示了在 Unity Hub 中创建项目的过程。

图 2.1 – 在 Unity Hub 中使用示例场景创建项目的方法
要将示例场景作为新项目加载,只需按照以下步骤操作:
-
打开 Unity Hub 并转到项目标签页。
-
点击新建按钮以创建一个新项目。
-
选择3D 示例场景(URP),给你的项目命名,并选择一个保存位置。对于这个项目,我们选择了3D 示例场景(URP),因为它提供了一个预配置的环境,展示了通用渲染管线(URP)的功能,非常适合 Unity 新手或寻求参考的人。虽然标准的3D(URP)模板通常受到开发者的青睐,因为它提供了一个干净的起点,允许自定义设置,但他们通常通过包管理器或 Unity 资产商店导入额外的包或资产来增强这些项目。
-
点击创建按钮以创建项目。
现在我们已经解决了这个问题,让我们来看看如何选择正确的渲染管线。
选择正确的渲染管线
在检查示例场景选项时,你可能已经注意到了 URP 和高清渲染管线(HDRP)之间的选择。但哪一个更好,渲染管线究竟是什么?本质上,渲染管线是一系列步骤和过程,它决定了引擎如何渲染图形。它将 3D 资产、光照和其他场景组件转换成最终出现在你屏幕上的 2D 图像。虽然 URP 和 HDRP 共享一些底层任务,但每个管线都是针对特定项目需求和目标平台定制的。
表 2.1显示了 URP 和 HDRP 如何相互比较:

表 2.1 – URP 和 HDRP 的比较
一个舒适的 VR 体验需要高帧率,通常超过 90 FPS。URP 强调性能,确保在各种 VR 设备上,包括独立 VR 头戴式设备、基于 PC 的 VR 和移动 VR,都能保持流畅的帧率。随着市场上独立 VR 头戴式设备的数量不断增长,URP 因其适应性和项目优化的简便性而变得非常有价值。
虽然 URP 可能不具备 HDRP 的视觉能力,但它平衡了图形质量和性能,使其适合大多数对性能至关重要的 VR 项目。
Unity 的通用性不仅限于 HDRP 和 URP 管线,它还允许经验丰富的图形程序员创建自定义的可脚本渲染管线(SRP)管线。然而,开发自定义 SRP 管线需要深入了解 3D 图形编程、渲染管线和 C#语言的熟练度。对于那些缺乏这些技能的人来说,HDRP 和 URP 提供了灵活性和易用性之间的最佳平衡。
由于其众多优势,URP 成为了大多数 VR 项目的首选选择。在这本书中,我们将专注于 URP。然而,HDRP 对于追求高端 PC VR 体验的人来说仍然是一个值得考虑的竞争者。
在安装了 Unity、选择了渲染管线并且你的项目在你的指尖上时,是时候熟悉 Unity 编辑器了。
了解 Unity 编辑器和其界面
如果你刚开始使用 Unity,编辑器的界面一开始可能会有些令人不知所措。但别担心——我们将引导你通过 Unity 编辑器,并展示如何导航其各种菜单和面板。经验丰富的用户也可以通过保持对最新最佳实践和技术的新鲜感而受益,因为为 VR 设计会带来独特的挑战,可能需要与传统游戏开发不同的方法。
探索 Unity 界面
当你启动一个新的 Unity 项目时,你会看到 Unity 编辑器。这个多功能的 workspace 由几个称为面板的独立窗口组成。
图 2.2显示了刚刚创建的示例场景项目的窗口布局。

图 2.2 – 示例场景项目的窗口布局
图 2.2 展示了多个面板,包括:(1) 场景视图,(2) 游戏视图,(3) 层级,(4) 检查器,(5) 项目,和(6) 控制台。
让我们探索构成 Unity 界面的这些基本面板。
将场景视图 (1) 想象成你的画布,你将在上面让你的游戏世界栩栩如生,创造迷人的景观,并将你的角色放置在奇幻的环境中。这个面板是游戏的核心,每个对象都被放置和排列,以讲述一个引人入胜的故事。例如,你可以在我们的示例场景中选择安全帽GameObject,并移动、旋转、缩放或删除它。
游戏视图 (2) 是你可以从玩家视角体验游戏的地方。它提供了游戏玩法的实时预览,包括你实现的视觉渲染和用户界面元素。
层级面板 (3) 或 场景层级窗口 是你游戏的设计蓝图,展示了构成你游戏世界的每个 GameObject 的有序列表。它就像一张建筑图纸,帮助你导航、管理和可视化游戏元素之间的关系,确保体验连贯且结构化。我们的示例场景展示了良好结构化的层级是什么样的。所有添加的 GameObject 都隶属于示例资产父对象。这包括道具GameObject,它本身也作为任何装饰场景并增加游戏世界细节和背景的 GameObject 或资产的父对象——例如,拼图、锤子、工作台等等。因此,请记住,将相关对象分组放在父 GameObject 下,可以更容易地管理和操作它们作为一个单一实体。此外,命名约定可以用来使层级更易于阅读和理解。
检查器面板(4)或检查器窗口是微调游戏元素的控制中心。在这里,您可以调整 GameObject 或资产的所有细微细节,确保您的游戏世界精确地符合您的设想。从位置和缩放到添加组件和修改脚本,检查器面板是您通往完美的通行证。让我们通过导航到示例资产 | 道具 | 安全帽在场景层次结构窗口中选择安全帽对象。检查器窗口显示了安全帽对象的所有定义组件。变换组件负责定位、旋转和缩放对象。您将在场景视图中找到它的 Gizmo 表示,这允许我们直接在那里变换对象。检查器窗口中还可以看到的其他两个组件是网格过滤和网格渲染器组件。网格过滤和网格渲染器组件提供了一种在场景中创建和显示 3D 模型的方法。网格过滤组件定义了模型的几何形状,而网格渲染器组件应用了如材质和纹理等视觉属性。没有这些组件,您在场景视图中将看不到对象。
项目面板(5)包含了您游戏的所有构建块,从纹理和模型到声音和脚本。它就像是一个资源库,其中每个导入或创建的资产都触手可及,等待在您的 XR 项目中使用。
最后,控制台面板(6)是一个重要的工具,在开发过程中帮助识别和解决问题。它提供详细的日志、警告和错误消息,允许进行高效的故障排除,并确保游戏性能的完整性。
您现在熟悉了 Unity 中的默认面板。接下来,我们将了解 Unity 网格和吸附系统,这在构建场景时是一个变革性的工具。
小贴士
您可以保持默认布局,或者使用 Unity 编辑器右上角的下拉菜单在布局下自定义您的面板。我们通常更喜欢 2x3 布局,但为了简单起见,本书中将使用默认布局。
使用网格和吸附系统
Unity 网格和吸附系统帮助在游戏环境中以更组织化的方式对齐和放置对象。它允许您将对象吸附到网格上,也可以吸附到其他对象上,以便更容易地进行放置和排列。
图 2**.3显示了您可以在哪里找到该系统。

图 2.3 – 如何使用网格和吸附系统
要使用此系统,您需要启用网格吸附按钮,该按钮由一个带有网格和磁铁图标的图标表示(1)。此外,请确保通过选择位于网格 吸附字段旁边的全局图标(2)来激活全局句柄。
所有三个轴(X、Y和Z)的1,意味着每个网格方格的宽度、高度和深度都是一单位。此设置可以根据需要调整,以匹配场景中对象的缩放。网格大小字段决定了对象吸附到网格的增量,因此较大的网格大小会导致更粗糙的吸附,而较小的网格大小会导致更精细的吸附。
你的回合
-
选择与图 2**.3中相同的支架,并将其沿Y方向移动两个单位。激活网格吸附,并尝试不同的网格大小,将支架放回工作台上。
-
通过在场景中移动、环绕和缩放来熟悉场景视图中的导航。以下文档可能对你有所帮助:
docs.unity3d.com/510/Documentation/Manual/SceneViewNavigation.html) -
选择另外两个游戏对象,并按你的喜好移动、缩放和旋转它们。
理解游戏对象和组件
游戏对象和组件是 Unity 项目的核心构建模块,允许开发者创建交互性和动态内容。现在,我们将提供一个关于游戏对象和组件的全面概述,以及它们是如何协同工作的。
理解默认新场景
Unity 赋予开发者能够在编辑器内创建多个场景的能力。这一功能有助于管理复杂性、提升性能,并促进更模块化和可重用的游戏项目。要创建一个与我们的示例场景并列的新默认场景,请访问编辑器最上方的菜单,并选择名为你选择的Scenes文件夹。按照这些步骤操作后,你将看到一个包含主摄像机游戏对象和方向光游戏对象的 Unity 新场景。这两个游戏对象都位于场景层次结构窗口中,并在场景窗口中显示,该窗口具有无限参考地面网格。在 Unity 中,游戏对象是游戏场景的基础构建模块。它们代表可见或交互式元素,如角色、道具、光源或摄像机。每个游戏对象都有一个变换组件,它定义了其位置、旋转和缩放,并且可以通过添加额外的组件来增强物理、碰撞检测或游戏逻辑。
让我们创建我们的第一个 GameObject。请注意,虽然 Unity 主要是一个游戏引擎,但它确实提供了一些基本的建模能力。您可以使用 Unity 内置的 3D 对象原语创建简单的 3D 模型,或者导入在其他 3D 建模软件中创建的更复杂的模型。还有第三方插件可以进一步增强 Unity 的建模能力。然而,重要的是要记住,Unity 无法与专门的 3D 建模软件如Blender、3ds Max或Maya相提并论,它更适合创建和操作用于游戏开发的模型。
我们将首先创建一个平面原语作为我们的地板。为此,在(0,0,0)的默认位置右键单击,而是在不同的位置。默认情况下,新创建的对象被放置在Ground的激活对象下。
在Ground对象的检查器窗口中,您会注意到,除了负责 GameObject 视觉外观的网格过滤器和网格渲染器组件外,还有一个网格碰撞器组件。接下来,您将了解更多关于这个和其他类型碰撞器的信息。
添加碰撞器
碰撞器是定义对象形状的组件,用于确定场景中与其他对象的物理交互。Unity 中提供了几种类型的碰撞器,每种都有其特定的用途,如下所示:
-
盒子碰撞器:此类碰撞器定义了矩形形状,非常适合类似盒子的对象。
-
球体碰撞器:此类碰撞器定义了球形形状,非常适合圆形对象,例如球。
-
胶囊碰撞器:此类碰撞器是圆柱体和两个球体的组合,适用于形状像胶囊的对象,例如角色。
-
网格碰撞器:此类碰撞器根据对象的网格定义其形状,允许精确的碰撞检测。
-
轮式碰撞器:此类碰撞器专门为基于轮子的对象设计,例如车辆。它允许实现逼真的轮子和悬挂行为。
通过集成碰撞器组件,您可以定义对象与其他场景碰撞器之间的交互,例如反弹、停止或穿透。此外,碰撞器可以触发事件,例如在碰撞时激活声音效果。将碰撞器应用于地面是合理的,因为它建立了环境边界,并使场景中的其他对象能够进行逼真的交互,例如防止角色穿过地面。
组件是可变的工具,可以被分配给 GameObject,塑造其行为、外观和功能。考虑主摄像机,它配备了如变换(定义位置、旋转和缩放)和摄像机(指定如视野(FOV)和裁剪平面)等组件。同样,方向光GameObject 具有如变换和灯光等组件,这些组件决定了灯光的类型、颜色和强度,以及其他属性。
其他组件的例子包括用于引入基于物理行为的刚体,用于播放声音的音频源,以及用于制作如火焰、烟雾或魔法咒语等视觉效果粒子系统。每个组件都执行独特的功能,并显著影响你的游戏世界及其交互。
随着我们这本书的进展,我们将探索和利用一系列基本组件,从下一节开始,我们将为我们的初始基本场景注入生命。
在 Unity 中创建基本场景并添加对象
在本节中,我们将向您展示如何构建图2**.4中所示的场景,该场景集成了如原始形状、材质、预制件、光照和导入资源等元素。

图 2.4 – 我们将要创建的基本场景
通过参与这个逐步教程,你将在组装一个美观的场景的同时,对这些核心概念有一个深入的了解。我们的初始任务包括使用原始形状制作一个表格。
使用原始形状构建桌子
如其名所示,原始形状是简单的几何形状,它们构成了我们场景中更复杂模型的构建块。想象一把椅子逐渐成形,一个立方体形成座位,两个圆柱体成为坚固的腿,另外两个圆柱体变成支撑的后腿。靠背是由一个平面制成的,其大小和位置完美地补充了座位和腿。
对于我们的场景,可以用类似的方式制作一个桌子——一个立方体作为桌面,而四个圆柱体则作为腿。应用纹理,使桌面和腿看起来更加逼真。调整每个原始形状的大小和位置,结果是一个看起来像是从现实世界中摘取的桌子。
要创建桌子,我们建议遵循图2**.5中所示的操作顺序。

图 2.5 – 如何使用网格和吸附系统
要构建你的桌子,请按照以下步骤进行:
-
通过将一个圆柱体引入场景来创建一个单独的桌腿。这可以通过在
0.05,0.2,0.05)处右键单击并定位在(0,0.2,0)来实现。 -
桌子需要四条相同的腿。为了实现这一点,通过复制(在Scene Hierarchy窗口中右键单击对象并点击Copy)和粘贴三次来复制原始腿。根据前面的参考图像,根据需要调整复制腿的位置。
-
接下来,向场景添加一个Cube原始对象,该对象将作为桌面。调整立方体的缩放和位置,使其 resting on the table legs。为了更简单地实现缩放和定位,切换到Wireframe模式,如图图 2**.6所示。

图 2.6 – 如何使用线框模式
小贴士
我们的建议是首先仅缩放Y值,并使用网格和吸附系统将立方体放置在腿上。随后,您可以切换视图从场景到顶部,并将Shading模式从Shaded更改为Wireframe。这种更改揭示了圆柱体和立方体,简化了缩放X和Z值以及定位Cube对象的任务。
-
要组织桌子组件,创建一个嵌套的父子对象层次结构。首先,通过重命名
Table top和圆柱体为相应的桌子腿来为对象分配适当的名称。随后,选择所有腿(cmd/Ctrl + 左键点击)。点击并拖动它们到Table top对象中的Table top对象上,建立父子关系。 -
要进一步细化表格结构,通过选择
Table创建一个空 GameObject。将Table top对象设置为Table对象的子对象。这样,就得到了一个由五个相互连接的原始对象组成的和谐结构的桌子。使用这种布局,可以轻松地缩放和移动桌子,无需单独选择每个 GameObject。
要完成场景,放置一个名为Table的球体原始对象。您可以为此使用前面讨论过的网格和吸附技术。为了获得更精致的外观,您可以自由地缩放球体。在下一节中,我们将使用材质增强Table和Sphere对象的外观。
如何更改地面、桌子和球体的外观
到目前为止,场景由一个地面和一个桌子组成,球体放在桌子上,所有这些都显示标准的灰色。让我们通过以下步骤创建一个新的红色材质来增强球体的外观:
-
导航到
Assets|Materials中的Materials文件夹。 -
点击
Red Material。 -
在Inspector窗口中,选择Base Map字段旁边的白色方块。此操作将启动Color窗口。选择#FF0000十六进制代码。
-
现在,您可以通过将
Red Material材质拖放到Sphere对象上方来应用该材质。
现在,球体应该呈现红色。到目前为止,我们已经使用了最简单的材质形式,将简单的红色应用到球体几何形状上。
在创建 3D 游戏或应用程序中的物体材质时,通常需要在物体表面添加额外的细节和深度,而不仅仅是使用单个纹理所能达到的。这就是基础地图、金属地图、法线地图、高度地图和遮挡地图等地图发挥作用的地方。
让我们依次了解这些地图:
-
我们可以将材质指定为红色材质(Red Material)或者我们可以分配一个纹理(例如砖墙的图片)来定义物体表面的颜色和图案。
-
金属地图:金属地图定义了物体表面看起来应该是金属的程度,地图中白色区域看起来非常金属,而黑色区域看起来非金属。
-
法线地图:法线地图是一种纹理,定义了物体的表面法线向量,给表面带来额外的深度和细节的错觉。法线地图通常用于在物体的表面上创建凹凸、坑洼和其他小细节的外观,而不需要添加额外的几何形状。
-
高度地图:高度地图是一种黑白图像,定义了物体表面的高度。高度地图用于在表面上创建深度和立体感,例如地形上的山脉和山谷或指纹的脊和谷。
-
遮挡地图:遮挡地图是一种纹理,定义了物体的哪些部分被遮挡或隐藏在视线之外。遮挡地图用于创建阴影和环境遮挡的效果,通过使物体看起来能够投射阴影和具有深度,从而让物体看起来更加真实和有质感。
为了可视化这些地图,想象一张画有墙壁图片的纸张。基础地图将是墙上的油漆,法线地图将为表面添加凹凸感,高度地图将创造出深度和立体感,而遮挡地图将添加阴影效果。当这些地图结合在一起时,它们可以创建一个更加详细和逼真的墙壁表示。你可能已经注意到这个例子没有涵盖金属地图。你不需要为一种材质使用所有这些地图。选择使用哪些地图取决于所需的材质外观和想要达到的细节程度。例如,一个简单材质的平面单色物体可能只需要一个基础地图(或反照率颜色)来定义其外观。一个更复杂的材质,如具有复杂细节的金属物体,可能需要一个基础地图、法线地图、高度地图和金属地图来实现期望的外观。
创建地图可能是一个复杂且耗时的工作,尤其是对于复杂的物体。为了节省时间和精力,通常最好利用市场上现成的材质或模型,例如Unity Asset Store、ArtStation和Sketchfab。这些网站提供了丰富的免费内容供选择。
在我们的示例场景中,我们有各种预制的材质可供使用。让我们为桌面使用木质材质。以下是您需要做的:
-
打开
Materials文件夹(Assets|ExampleAssets|Materials)。 -
搜索OBS_Mat材质并将其拖放到桌面的顶部。
现在,桌面应该显示出木质纹理,如图图 2.7所示。

图 2.7 – 带有木质纹理的桌面
在检查器窗口中检查表面输入,木质材质包括基础图、金属图、法线图和遮挡图。要预览每个图,请cmd/Ctrl + 左键单击图旁边的相应方块。
让我们也为地面选择一个合适的材质。在Materials文件夹(Assets | ExampleAssets | Materials)中搜索Ground_Mat材质。将其拖放到地面上,现在表面应该看起来更加逼真。
接下来,您将学习如何在场景中创建砖墙材质。
创建砖墙材质
在前面的章节中,我们探讨了将红色漫反射颜色应用于球体以及使用更高级的材质为地面和桌子。值得注意的是,材质在确定表面渲染方式方面起着至关重要的作用,它不仅包括物体表面的纹理,还包括它与光源的交互。
纹理是应用于 3D 模型或 2D 表面以添加细节或颜色的图像。它可以被视为覆盖在物体表面的皮肤,以赋予它特定的外观或感觉。纹理可以在 Unity 中创建或从外部图像文件导入,然后分配给场景中 GameObject 应用的材质。这种技术增强了渲染对象的细节和真实感。
在本节中,我们将通过开发砖墙材质并将其应用于由变换后的立方体构建的墙壁,深入了解创建和应用更复杂材质的过程。按照以下步骤开始:
-
让我们先在场景中插入一个新的立方体来创建墙壁,将其重命名为
Wall,将其缩放为(2,1,0.1),并将其定位在(0.2,0.5,1.8)在桌子后面。 -
导航到
Textures中的Assets文件夹。 -
为了使
Wall立方体呈现出砖块般的外观,请下载并使用本书 GitHub 仓库中提供的BrickWall.jpg纹理文件,或者通过在线搜索找到合适的砖墙纹理。将图像导入新创建的Textures文件夹。这可以通过简单地从您的本地文件系统拖动图像并将其放入相应的 Unity 文件夹中完成。 -
保持处于
Materials文件夹中。在这里,生成一个新的材质并将其重命名为Brick_Mat。您可以通过在文件夹内右键单击,选择创建,然后选择材质来创建材质。 -
在选择
Brick_Mat材质后,导航到检查器窗口。寻找位于基础贴图字段旁边的较小环状符号并选择它。然后继续搜索并选择导入的BrickWall图像。 -
最后一步是将
Brick_Mat材质从场景窗口中现有的Wall立方体移动出来。这可以通过简单的拖放操作完成。
通过这些步骤,您的场景现在应该看起来与图2.8中所示相似。

图 2.8 – 场景中的砖墙
您现在已经见证了材质在转换场景真实感方面的能力。在下一节中,我们将更详细地了解 Unity 场景的另一个重要组件:预制件。
解包预制件
在本节中,我们将学习如何将样本场景中的预制件转换为 Unity 中的普通 GameObject。预制件是可重复使用的预制对象,可以在场景中多次使用,类似于构建环境的积木。它们是保存在单独文件中的对象的副本,允许您创建多个实例并简化场景管理。
要导入预制件,导航到Assets | ExampleAssets | Prefabs。将场景层次结构窗口中的ConstructionLight_Low对象拖放到场景中。在场景层次结构窗口中,您会注意到一个蓝色立方体图标,表示它是一个预制件实例。
我们现在将解包ConstructionLight_Low对象,将其转换为普通 GameObject。在场景层次结构窗口中右键单击并选择预制件 | 解包。这样,对预制件的修改不会影响解包实例。请将其放置在砖墙前面。
重要的是要记住,在 Unity 中使用预制件在各种场景中都有优势,例如以下情况:
-
重复的游戏对象:通过一次创建一个对象,将其转换为预制件,并在需要时进行复制,可以节省时间和精力
-
自定义游戏对象:使用包含所有可能修改的预制件,更有效地管理自定义,根据需要调整实例
-
模块化游戏设计:通过为单个级别组件创建预制件并将它们组装成完整级别,促进模块化设计
在 Unity 中使用预制件有助于节省时间、管理复杂 GameObject 以及支持可适应的模块化游戏设计。接下来,我们将讨论如何从 Unity 资产商店导入资产。
从 Unity 资产商店导入
让我们学习如何导入和使用资产商店中可用的模型。Unity 资产商店是一个市场,用户可以在此处找到、购买和下载各种资产,包括 3D 模型、动画、音频、视觉效果等,用于他们的 Unity 项目。
这是如何从资产商店导入聚光灯模型的方法:
-
打开你喜欢的网络浏览器,导航到 Unity 资产商店
assetstore.unity.com/。在这里,在搜索栏中输入Spotlight and Structure。或者,你可以直接通过assetstore.unity.com/packages/3d/props/interior/spotlight-and-structure-141453访问包页面。 -
一旦将包添加到你的资产中,寻找在 Unity 中打开按钮并点击它。
-
Unity 应用应该会打开,提示导入包。进行导入操作。
-
成功导入后,导航到
Assets|SpaceZeta_Spotlight|Assets目录下的包目录。 -
将
Spotlight.fbx和SpotlightStructure1.fbx文件拖入场景并解包(右键单击,然后选择预制体 | 解包)。
如果物体呈现品红色,这通常表明相关的材料要么不存在,要么与当前使用的渲染管线不兼容。要解决这个问题,请在检查器窗口中选择聚光灯,并将着色器更改为通用渲染管线 | Lit。
如果你的Spotlight_basecolor.png、Spotlight_roughness.png、Spotlight_normal.png和Spotlight_emission.png文件。
现在,根据图 2.9所示,将你的BrickWallLight和BrickWallLightStructure进行变换。

图 2.9 – 导入的 BrickWallLight 模型及其 BrickWallLightStructure 模型
你可以使用相同的程序来查找和导入你场景所需的其它 3D 模型、动画、音频和视觉效果。与刚刚导入的BrickWallLight模型一致,下一节将处理照明的最关键方面。
理解 Unity 的照明管线
在实施项目之前考虑的一个关键方面是规划照明。在这里,我们介绍了一种经过验证的方法,这种方法多年来一直在各种 XR 项目中提供了卓越的照明效果,并与 Unity 的最佳实践照明管线紧密一致(docs.unity3d.com/Manual/BestPracticeLightingPipelines.html)。此过程包括三个主要步骤,如图 2.10所示。

图 2.10 – Unity 的最佳实践照明管线
为你的项目选择合适的渲染管线是整体照明管线流程的第一步。如表 2.1中所述,我们建议对于 XR 项目使用 URP,这为有效的照明奠定了基础。
照明管道的第二步是通过选择合适的全局照明(GI)系统和相应的照明模式来确定如何生成间接照明。
想象一下在一个阳光明媚的日子里,只有一个窗户的房间。直射光就像通过窗户直接进入房间的明亮阳光——如果你站在窗户的路径上,这就是你直接感受到的光。这与我们在 Unity 中说的直射光类似。
现在,看看房间的角落或不在窗户正前方的地方。它们并不是完全黑暗的,对吧?它们被照亮了,但不是那么明亮。这是因为进入的阳光击中了不同的表面——地板、墙壁或家具——并反射到这些部分。这就是我们所说的间接照明。
Unity 中的 GI 系统模仿了光线在房间中反弹的规则。它是计算光线根据其击中表面的反射量到达房间较暗部分的系统。
最后,Unity 中的照明模式类似于选择房间中的表面类型。是光滑、反光的 marble 地板还是暗淡、哑光的木地板?根据您的选择,光线会以不同的方式反射并以独特的方式照亮房间。这就是照明模式控制的内容——它决定了光线如何与不同的表面相互作用,以在游戏场景中创建整体照明效果。
根据 GI 设置调整到您项目的需求,现在是时候释放您的艺术想象力了。照明管道的最后一步是将灯光、发射表面、反射探针和灯光探针整合到您的场景中,以和谐地编织场景的照明。通过遵循这种方法,您将构建一个统一且详细的照明环境,增强虚拟空间的真实感和参与度,并确保高质量的用户体验。
现在,是时候将照明管道的步骤应用到我们的场景中了。由于 URP 已经为您的项目选择,让我们继续到照明管道的第二阶段。在这里,我们将专注于理解和选择适合您场景的适当照明设置。这一关键步骤确保您的虚拟世界得到有效的照明。
选择正确的照明设置
由于您已为您的 XR 项目选择了 URP,接下来的任务是配置间接照明。这个过程包括选择一个合适的 GI 系统和照明模式。GI模仿 3D 环境中的间接光,导致柔和的阴影和自然的外观,因为光线在物体和表面之间反弹。
对于简单的移动 XR 场景,减法模式是最具性能的选项,它依赖于预先计算的光图来最小化GPU负载并提高性能。阴影遮罩模式紧随其后,提供实时照明和静态对象的烘焙阴影,通过减少 GPU 负载并使用预先计算阴影来在视觉效果和性能之间取得平衡。另外,烘焙间接照明模式提供了实时照明、阴影和烘焙间接照明的理想组合,适用于高质量的 XR 视觉效果。
要设置间接照明,导航到Assets文件夹,其中可以重命名。我们建议默认选择混合照明,在照明设置窗口中启用烘焙全局照明选项。对于照明模式,阴影遮罩在质量和性能之间提供了最佳平衡。
小贴士
虽然烘焙全局照明允许自动生成光图,但我们建议不要这样做。相反,在测试场景或实施更改后手动生成光图,因为它提供了测试不同照明场景和迭代设计的灵活性,而无需承受不断自动更新的开销。
在确定这些之后,你可以继续在你的场景中放置光源对象。
添加光源和天空盒
Unity 中的轻量级对象是创建沉浸式和逼真环境的重要组成部分。你可以选择多种不同的光源对象,包括点光源、聚光灯、方向光和区域光。它们可以被归类为直接照明,这指的是直接从光源发出的光线。让我们更详细地看看每种光源对象。
点光源从单个点均匀地发出光线,非常适合局部光源,如灯具和蜡烛。聚光灯以圆锥形投射光线,非常适合方向光源,如手电筒和车灯。方向光以单一方向投射光线,类似于太阳或月亮,而区域光从特定区域散布光线,类似于天花板灯板。
每种光源类型都有其独特的属性,当它们组合在一起时,可以产生不同的照明效果。理解这些光源类型是实现 Unity 中有效照明的关键。
首先,在场景层次结构窗口中选择方向光GameObject,并在其检查器窗口顶部取消勾选复选框。你会观察到它对场景照明的显著影响。然而,你可能好奇为什么场景比预期的更亮——原因在于激活的天空盒。
在 Unity 中,天空盒充当场景的背景,环绕场景,赋予环境感和深度,类似于现实生活中的天空和周围景观。天空盒是通过将特定材质应用于包围场景的大立方体来创建的,这个立方体始终出现在所有其他元素之后。这个立方体产生了天空和环境延伸到场景实际边界之外的错觉。
天空盒在间接照明中扮演着至关重要的角色,因为它们影响场景的整体照明氛围。例如,晴朗的天空和炽热的太阳在场景上投射出温暖的光线,营造出欢迎和邀请的氛围。相反,一个有满月的天空投射出凉爽的蓝色光线,营造出更加诡异和神秘的氛围。Unity 中其他间接照明的例子包括全局光照(GI)、环境光和光照贴图,它们都为最终的视觉体验做出了贡献。
让我们按照以下步骤创建并应用一个完全黑暗的天空盒:
-
要创建一个新的材质,导航到项目窗口中的
Materials文件夹。右键单击并选择创建 | 材质。 -
将新材质命名为
DarkSkybox_Mat并选择它,以在检查器窗口中查看其属性。 -
通过转到天空盒 | 程序化来选择着色器类型,并保持默认设置。
-
将新的天空盒材质拖放到天空上。
你的场景现在应该类似于图 2.11中所示的场景。

图 2.11 – 应用到场景中的天空盒
现在,你可以看到场景中的元素之所以可见,仅仅是因为从ConstructionLightLow对象发出的激活聚光灯。由于间接照明条件的影响已被消除,现在是时候尝试剩余的不同光照类型了。
首先,选择ConstructionLightLow对象的Spot Light子对象,然后转到检查器窗口。在这里,将光照类型更改为点光源,虽然它并不完全适合建筑灯光,但可以用来说明行为的变化。点光源,正如你所看到的,向所有方向辐射其亮度,与聚光灯的聚焦光束不同。
现在,让我们让导入的BrickWallLight对象充满生机。要做到这一点,向其现有的子对象添加一个空子对象。将其重命名为Light,然后选择Light。选择聚光灯作为类型后,你可以自由调整位置、颜色、强度和其他参数。为了见证你创作的影响的全貌,暂时禁用ConstructionLightLow对象。
最后,我们来到了光照类型中的最后一个未知领域——区域光源。图 2.12展示了将区域光源融入我们的场景,将其提升到新的亮度高度。

图 2.12 – 区域光源照亮场景
要在你的场景中添加区域光源,请按照以下步骤操作:
-
添加一个
1.3,0.75,0.1),并更改其 位置 和 旋转 参数,使其大致与 图 2**.12 中显示的白色立方体光源对齐。 -
将对象命名为
Cube Light。 -
创建一个空子对象。右键单击并选择
Area Light。 -
在
Light中,现在你可以找到将灯光类型更改为 区域(仅烘焙) 的选项。通过在 检查器 窗口中取消选中相应的复选框,暂时熄灭场景中所有其他光源。你可能观察到场景陷入黑暗,区域光源似乎无法履行其照明职责。
Unity 提供了两种照明系统:实时照明 和 预计算照明。实时照明动态地照亮场景,随着玩家在环境中的移动而变化。相比之下,预计算照明在游戏开始前计算场景的亮度,提供稳定且优化的照明体验。第三种混合照明模式结合了两者之长,允许灵活地确定场景的哪些部分使用实时和预计算照明。
区域光源仅允许预计算光照,这要求我们首先烘焙光照贴图,并将其 发射表面 分配给被光照照亮的游戏对象。烘焙光照贴图涉及预先计算光照数据并将其存储在纹理中,优化场景在运行时的光照。烘焙是一个一次性过程,仅在光照条件改变时重复。
首先,确定受 Area Light 影响的游戏对象,例如 Wall 对象和 Cube Light 对象本身,并在 检查器 窗口中激活它们的 静态 复选框。接下来,通过导航到 窗口 | 渲染 | 照明,切换到 烘焙光照贴图 选项卡,来烘焙光照贴图。点击 生成光照 以查看转换。
注意,只有 Wall 对象看起来在发光,而 Cube Light 对象没有。这是因为没有对象来反射其光线,就像下面的 Ground 对象一样。
为了增强场景,关注 Ground,BrickWallLight,BrickWallLightStructure 对象及其相应的子对象。启用它们的 静态 复选框,并再次烘焙光照贴图。观察场景的转换。
图 2.13 强调了使用发射表面与区域光源一起使用时的差异。

图 2.13 – 区域光源发射表面的影响
图 2.13 的左侧图像仅展示了墙面和区域光源作为发射表面,而右侧图像则包含了多个游戏对象,从而带来更加动态、视觉上更具吸引力的体验。
让我们重新激活BrickWallLight和ConstructionLightLow对象的灯光。通过这样做,我们遵循混合光照的原则,结合了实时和预计算光照的优点。结果,场景中的对象以和谐的方式被照亮。
作为一名 XR 开发者,光照的选择反映了你的艺术视野和场景的需求。实时光照以其动态性吸引人,预计算光照以其稳定性著称,混合光照则以其多功能性迷人。在本章的最后部分,我们将介绍光照和反射探针。
探索光照和反射探针
最后,让我们通过重新访问SampleScene对象来深入了解反射探针和光照探针。要访问它,请在项目窗口中导航到资产 | 场景,然后双击SampleScene对象。
在 Unity 中,反射探针和光照探针有助于在场景中创建逼真的光照和反射效果。反射探针从周围环境中捕获反射数据并将其应用于场景中的对象。通过捕获环境的 360 度视图并将其存储为立方体贴图,反射探针能够在场景中的反射表面上实现精确的反射。例如,如果你想在游戏中让一辆闪亮的汽车反射附近的树木和天空,你可以在汽车附近放置一个反射探针来收集环境数据并将其应用于汽车的反射。
相反,光照探针从周围环境中捕获光照数据并将其应用于场景中的对象。通过在场景中的不同位置放置探针,它们收集光照信息并将其存储为纹理。然后,这个纹理被用来为场景中的对象提供逼真的光照。例如,如果一个角色站在森林中,你可以在角色周围放置光照探针来捕获树木的光照信息并将其应用于角色的皮肤。
在场景层次结构窗口中检查SampleScene对象,我们可以看到它包含三个反射探针和一个包含多个光照探针的光照探针组。图 2.14中的图像展示了所选反射探针(左侧)和光照探针(右侧)的外观。

图 2.14 – 样场景中的反射和光照探针
从本质上讲,在场景中不使用反射探针和光照探针可能会导致光照和反射效果不够真实。然而,如果你的场景中没有高度反光的物体,或者光照主要是均匀的,移除探针可能不会在最终结果中产生明显的差异。对于这个SampleScene对象来说,这种情况很可能成立。
如所示,反射和光照探针是显著增强 Unity 场景真实感的有力工具。然而,在简单的场景中,它们的使用并不总是必需或明显的,因为 Unity 内置的光照贴图技术擅长在没有探针的情况下近似光照和反射。
掌握了这些原则,你就有能力创建沉浸式和视觉上引人入胜的 XR 体验。
摘要
在本章中,你构建了一个基本场景,熟悉了 Unity 编辑器,开始学习如何将资产导入到自己的项目中,并介绍了照明的关键方面。
你通过 Unity Hub 安装 Unity 并使用 URP 创建一个带有示例场景的新项目开始了这段旅程。然后,你探索了 Unity 编辑器的基础,例如导航其众多窗口和利用场景编辑选项,包括网格和吸附。此外,你深入研究了 GameObject 及其组件,例如碰撞体。
此后,你制作了自己的基本场景,包括地面平面、砖墙和一个支撑球体的桌子。在这个过程中,你发现了材质的强大作用,应用了一些材质,并使用导入的图像作为纹理设计了你自己高级的砖墙材质。你还考察了预制件的有用性,并学习了如何将它们转换为常规 GameObject。
此外,你通过在资产商店中搜索并导入聚光灯来理解导入资产的重要性,解决了由于渲染管线不兼容可能出现的潜在问题。最后,你深入研究了照明、理解和实施 Unity 最佳实践照明管线的基本场景。在这个过程中,你确定了理想的渲染管线,选择了正确的照明设置,并试验了各种灯光,包括点光源、聚光灯、方向光源和区域光源。你还使用了天空盒,并熟悉了光照和反射探针。
在这个坚实的基础之上,你现在准备深入 Unity,创建越来越复杂和引人入胜的场景。在下一章中,我们将构建我们的第一个 VR 场景,部署它,并在各种 VR 头盔或模拟器上测试它,进一步扩展你对 Unity 的理解和掌握。
第二部分 – 使用自定义逻辑、动画、物理、声音和视觉效果进行交互式 XR 应用
在本书的第一部分深入 Unity 引擎的复杂性并探索各种 XR 技术之后,本部分涵盖了 XR 开发的全部基本要素,将你的技能从初学者提升到中级水平。在本部分中,你将掌握创建你的第一个 VR 和 AR 体验,包括将应用部署到不同设备,并使用模拟器进行测试,而无需特定的 VR 头盔或智能手机。一旦你对创建和部署基本的 XR 场景有了扎实的理解,你将进步到开发更高级的 XR 应用。
你将为你的 XR 应用添加交互性,利用无代码选项,如按钮点击,并通过 C#脚本深入更复杂的逻辑。虽然这部分包含许多代码片段,但请放心——我们将以初学者友好的方式解释 C#。此外,你还将了解如何通过结合声音和粒子效果来增强你的 XR 场景的真实感,同时确保这些物理现象遵循现实世界的物理定律。
本部分包含以下章节:
-
第三章,Unity 中的 VR 开发
-
第四章,Unity 中的 AR 开发
-
第五章,构建交互式 VR 体验
-
第六章,构建交互式 AR 体验
-
第七章,添加声音和视觉效果
第三章:Unity 中的 VR 开发
让我们探索 VR 的世界,从在 Unity 中创建你的第一个 VR 项目到在头戴式设备或模拟器上部署我们的第一个 VR 场景。在本章中,我们将介绍 Unity 中可用的最重要的 VR 工具包和插件,帮助你熟悉每个的功能。
你将通过 XR Interaction Toolkit 的演示场景获得实际操作经验,了解其最重要的组件和脚本,并学习如何在未来的 VR 项目中使用它们。我们将帮助你理解 VR 开发与传统游戏开发之间的细微差别,以及分享确保 VR 头盔计算能力的不同策略。
本章中你将获得的重要技能之一是学习如何在各种设备上测试和部署 VR 体验,从模拟器到 VR 头盔。本章将为你提供一个坚实的基础,为你提供创建越来越复杂和沉浸式 VR 场景所需的必要技能和知识。
我们将在接下来的内容中涵盖以下主题:
-
什么是 VR 开发?
-
在 Unity 中设置 VR 项目和 XR Interaction Toolkit
-
探索 XR Interaction Toolkit 演示场景
-
将 VR 体验部署和测试到不同的 VR 平台或模拟器
技术要求
为了有效地跟随本章关于 Unity 中 VR 开发的说明,拥有适当的硬件和软件设置至关重要。为了获得最有效和无缝的体验,我们强烈建议使用 Windows PC 或坚固的 Windows 笔记本电脑,即使你的目标平台是独立 VR 头盔。
Windows
Windows 是大多数 VR 头盔制造商,包括 Meta Quest 和 HTC,支持的平台。这种支持源于 Windows 对硬件的全面支持以及其对游戏的优化。无论你是为 PC 绑定式还是独立 VR 头盔开发,Windows 环境将为 Unity 中的 VR 开发提供最丰富的资源和兼容性。
为了获得流畅的体验,我们建议以下最低要求:
-
操作系统:Windows 10 或更高版本
-
处理器:Intel i5-4590/AMD Ryzen 5 1500X 或更高
-
内存:8 GB RAM 或更多
-
图形:NVIDIA GTX 1060/AMD Radeon RX 480 或更高
macOS
虽然 macOS 很少被 VR 头盔支持,但 Unity 仍然可以通过 ARKit 等平台在苹果设备上实现 VR 开发,这些平台主要针对 AR 而不是 VR。如果你正在使用 macOS 并针对独立 VR 头盔进行开发,考虑通过 Boot Camp 设置 Windows 分区,这允许你使用任何兼容 Windows 的 VR 头盔。这种设置将使你能够无重大问题地跟随本章中的说明。
Linux
Linux 对 VR 的支持相对有限,但Valve通过 SteamVR 在 Linux 平台上扩展了对Valve Index和HTC Vive头戴设备的支持。如果你针对的是如Oculus Quest这样的独立 VR 头戴设备,可以通过在 Unity 中创建 VR 应用程序的 Android 版本来进行 Linux 平台上的开发,然后将这些构建转移到头戴设备上进行测试。然而,独立 VR 头戴设备通常运行 Android 版本而不是 Linux,这可能会带来独特的挑战。
如果你正在使用 Linux 平台,请确保你的系统满足以下最低要求:
-
操作系统:Ubuntu 18.04 LTS 或更新版本
-
处理器:双核 CPU 带超线程技术
-
内存:8 GB RAM 或更高
-
图形:Nvidia GeForce GTX 970,AMD RX480
什么是 VR 开发?
当开始 Unity 中 VR 开发的迷人旅程时,了解 VR 开发的特性和独特之处非常重要。这包括欣赏软件和硬件限制,以及该领域存在的挑战。在接下来的章节中,我们将深入探讨 VR 开发和传统 2D 计算机屏幕游戏开发的差异。
此外,我们将探讨 VR 头戴设备技术的当前轨迹和未来趋势。这种探索包括每个 VR 头戴设备带来的独特优缺点。这种理解至关重要,因为它不仅指导你做出明智的选择,选择适合你需求的 VR 头戴设备,还使你具备判断在特定情境下哪种 VR 头戴设备理想或不理想所必需的知识。
到本节结束时,你将具备充分的知识和技能,以在 Unity 中导航沉浸式和动态的 VR 开发世界。
探索经典游戏与 VR 游戏开发的差异
经典游戏开发和 VR 开发,尽管存在于游戏光谱的不同端点,但它们都源于创造沉浸式、虚拟景观的相同愿望。有趣的是,这两个类别不仅共享吸引观众的共同目标,它们还建立在类似的游戏设计基础元素之上,并需要相应的工具集。
游戏创作的两个领域都要求仔细规划和考虑游戏玩法机制、用户界面、目标、关卡和剧情。开发者,无论是从事传统游戏还是 VR 项目,通常使用相同的编程语言套件,如 C++、C#或 Python 进行脚本编写。
游戏资产(纹理、模型、动画和声音)的创建是这两个领域的另一个共同点。VR 开发可能略微偏向于 3D 模型和空间音频,以丰富环境的沉浸感。然而,创建和整合这些资产的整体过程在两个学科中仍然是一致的。无论游戏媒介是 2D 屏幕还是 VR 头盔,实现逼真的物理效果对于沉浸式体验至关重要。
虽然它们有这些相似之处,但经典游戏开发和 VR 开发之间的差异同样引人入胜,这主要归因于 VR 的独特性质和能力。
其中一个显著的对比在于设计的维度。经典 2D 游戏主要在一个平面上运行,其中物体以二维形式呈现:高度和宽度。《超级马里奥兄弟》就是一个经典的例子,其动作从左到右展开,角色的移动主要限制在这个平面上。
相反,VR 游戏将深度作为一个重要的第三维度引入游戏,从而使用户能够从任何角度或位置探索场景,类似于他们在现实世界中的体验。例如,在Beat Saber这样的 VR 游戏中,玩家可以四处张望,伸手,并以模仿现实世界空间交互的方式与游戏环境互动。
这些微妙但影响深远的不同为经典游戏开发和 VR 开发中的各种体验铺平了道路,每种体验都有其独特的魅力和挑战。
同样重要的是,玩家移动的范围在经典 2D 游戏和 VR 游戏体验之间表现出明显的区别。传统的 2D 游戏通常将玩家的动作限制在x和y轴上,将移动限制在一定的平面上。相反,VR 引入了不同程度的自由度。
例如,三个自由度(3DoF)设备,通常与移动 VR解决方案如Google Cardboard搭配使用,允许用户自由地四处张望(俯仰、偏航和翻滚),但不会跟踪空间内的物理位移。这提供了一种基本的沉浸感,使用户能够站在原地从多个角度观看场景或物体。
进一步深入 VR 领域的是六自由度(6DoF)设备。这些设备不仅跟踪玩家的视角,还能记录他们在x、y和z轴上的物理移动,从而创造一个更加沉浸和互动的环境。为 6DoF 创造体验可能相当复杂,需要完整的 3D 空间交互。例如,现代 VR 头戴设备如Meta Quest 2与 VR 控制器配对,甚至提供手势追踪功能。用户可以以极其直观的方式与虚拟世界交互,按按钮、转动双手,进行一系列动作,VR 头戴设备上 AI 驱动的摄像头能够准确捕捉并实时翻译这些动作。
玩家安全的重要性是区分 VR 开发与传统游戏制作的独特方面。虽然物理安全问题是经典 2D 游戏开发中几乎不存在的,但 VR 中运动范围的扩大可能导致现实世界的意外。因此,开发者需要设计安全特性,如虚拟边界或警报系统,以防止事故发生。
最终的区分因素在于玩家习惯。经典的 2D 游戏通常依赖于玩家对标准游戏控制和机制的熟悉度——考虑到 PC 在日常生活中的普及,这是一个安全的假设。然而,VR 往往开创了新颖的交互形式,可能会让初次用户感到困惑。为了弥合这一差距,开发者可能需要整合教程或指南来帮助玩家导航并交互 VR 游戏世界。
VR 开发不仅与传统游戏制作有显著差异,而且展示了为 VR 头戴设备供电的更广泛的技术范围。这些多样化的方法对于 VR 技术的运行至关重要,将在下一节中揭晓。
理解为 VR 头戴设备供电的不同方法
虚拟现实头戴设备的功率可以显著影响你 VR 应用的成败。让我们深入了解其中最常见的情况。
PC VR(也称为基于 PC 的 VR 或有线 VR 头戴设备)
基于 PC 的 VR 头戴设备,包括如Valve Index和HTC Vive Pro等型号,依赖于台式机或笔记本电脑的计算能力。它们将繁重的工作,如密集计算、图形渲染和 3D 模拟,委托给连接的电脑。时至今日,相当一部分 VR 头戴设备要么完全是基于 PC 的,要么在独立版本之外还支持 PC VR 模式。这主要是因为 PC VR,得益于 PC 卓越的计算能力和图形能力,提供了最丰富和沉浸式的 VR 体验。在基于 PC 的 VR 中,细节级别、帧率和响应速度都是一流的。
基于 PC 的 VR 系统主要采用两种连接方式将 VR 头盔与电脑连接。有线电缆连接通常使用 HDMI 或 DisplayPort 进行视频传输,USB 进行数据传输,这是传统的连接方式。一种较新的创新是无线连接,例如Meta Quest系列中的Air Link连接。然而,由于无线 PC VR 连接的延迟较高,可能会影响 VR 体验的响应速度,因此在现实中很少使用。视频质量也会根据网络条件而波动,需要强大的稳定 Wi-Fi 信号才能实现最佳操作。
尽管无线连接方便,但为了获得无缝的 VR 体验,即使头戴式设备支持无线连接,有线连接仍然是首选。然而,需要注意的是,有线 PC VR 系统由于物理连接到电脑,牺牲了便携性。无论选择有线还是无线,VR 设置的移动性都受到限制。例如,你无法轻松地将 VR 头盔打包用于度假、活动、会议或朋友的聚会。如果你决定携带 VR 设备,则需要携带一台强大的电脑或确保目的地有所需的计算资源。加上高性能或游戏电脑可能高昂的价格,这可能会使 PC VR 系统对某些用户来说是一项重大投资。
独立式 VR 头盔
针对基于 PC 的 VR 头盔的局限性,独立式 VR 设备在市场上引起了轰动,获得了巨大的流行度。处于领先地位的是Meta Quest系列。这些设备将所有必要的计算组件都集成在头戴式设备中,使其成为独立的单元。大多数现代独立式头戴式设备由Qualcomm Snapdragon芯片驱动,提供强大的处理能力。
独立式 VR 头盔推崇便携性和自由移动,消除了连接到单独计算设备的需要。这些一体化系统为基于 PC 的 VR 提供了一种经济实惠的替代方案。此外,许多独立式头戴式设备,如Meta Quest系列中的设备,支持 PC VR 模式,提供了在需要时处理更密集计算应用(如Half-Life Alyx)的灵活性。
然而,一个缺点是独立式头盔的电池寿命相对较短,通常最多只能使用两个小时。尽管如此,也存在一些补救措施,例如购买配备额外电池寿命延长器的舒适头带。在大多数情况下,我们推荐更经济实惠的独立式头盔,如Meta Quest系列,而不是基于 PC 的头盔。在学术和商业环境中,独立式头盔是一个高效的选择。简单的解决方案,如购买多个独立式头盔或一套增强电池寿命的头带,与传统 PC VR 解决方案相比,仍然可以节省大量费用。在活动或会议中使用独立式 VR 头盔展示产品或研究时,它们也表现出色,提供了一种方便且便携的解决方案。
基于控制台(Console-based)的 VR 头盔
基于控制台的 VR 头盔,如PlayStation VR 2,主要针对游戏社区。它们利用游戏控制台的处理能力,提供高质量的 VR 体验,无需单独的 PC。然而,拥有游戏控制台的成本并不低。此外,就像它们的 PC 基对手一样,由于它们的连接性质,基于控制台的 VR 头盔牺牲了便携性。VR 体验的质量也可能受到控制台能力的限制。总的来说,除非你的主要关注点是游戏,否则基于控制台的 VR 头盔可能不是在个人、商业或学术环境中创建 VR 体验的最佳选择。即使在游戏圈中,也可能有更好的选择可以考虑。
基于智能手机的 VR 头盔
基于智能手机的 VR 头盔,例如Google Cardboard和Samsung Gear VR,利用了智能手机的显示和计算能力,这些设备是大多数人已经拥有的。这些头盔提供了一种经济实惠且高度便携的解决方案。然而,由于它们的计算和图形能力有限,它们提供的沉浸式体验本质上会降低。此外,由于与其他 VR 头盔类型相比传感器范围更窄,它们在 VR 环境中的交互能力也受到限制。因此,我们很少推荐它们。即使在没有 VR 头盔的情况下进行 VR 体验的初步测试,Unity 的 XR 设备模拟器等工具也提供了一种免费、方便甚至更优的解决方案。
基于云的 VR 头盔
虚拟现实(VR)社区中越来越多的声音正在倡导开发基于云的 VR 头盔。这项新兴技术利用强大的服务器来承担计算任务,通过互联网将结果流式传输到 VR 头盔。这种安排有可能在不依赖于本地计算能力的情况下提供高分辨率的 VR 体验,从而进一步增强沉浸感和用户满意度。
基于云的方法可以使 VR 头戴设备更轻便、更易于使用,吸引更广泛的受众投资自己的 VR 硬件。另一个吸引人的方面是,为 VR 头戴设备提供动力的数据中心中的硬件可以由提供商定期升级,从而避免用户频繁投资新设备。
那么,为什么这种计算方法在当代 VR 头戴设备中并不普遍呢?主要原因是需要一个稳定、高带宽、低延迟的互联网连接——这是一个并非普遍可用的先决条件。此外,与通过互联网传输敏感数据相关的潜在隐私和安全问题。
随着技术的进步和这些挑战得到解决,我们可能会看到更多基于云的 VR 系统的采用。然而,截至目前,它们的使用仍然主要处于实验阶段,尚未成为主流。
经过对 VR 头戴设备的独特特性和 VR 开发的细微之处的探索,你现在已准备好开始创建你的首个 Unity VR 场景。这一里程碑将使你能够尝试 Unity 为 VR 提供的某些引人入胜的工具包,包括高度通用的 XR 交互工具包。
在 Unity 和 XR 交互工具包中设置 VR 项目
在接下来的章节中,你将获得创建专门针对 VR 开发的 Unity 项目的知识。此外,你将熟练掌握安装和配置两个对 Unity 中 VR 开发至关重要的插件:XR 插件管理和 XR 交互工具包。
在 Unity 中为 VR 开发创建项目
让我们从在最新版本的 Unity 中创建一个全新的项目开始。为了确保与不同设备和平台兼容,启用Installs文件夹至关重要,点击你的 Unity 版本的设置图标,选择添加模块,并安装缺失的构建支持。
要使 VR 场景生动起来,我们首先需要导航到 Unity 中的项目部分,并使用最新的 Unity 版本创建一个新的项目。虽然 Unity 确实在可供选择的各种项目类型中提供 VR 模板,但我建议选择3D URP 模板。
这些建议背后的原因是 Unity 的 VR 模板不包括 XR 交互工具包,如果你选择 VR 模板,这将导致广泛的设置修改。因此,创建一个 3D URP 项目是一个更简洁、更无烦恼的方法。
在下一节中,你将学习如何为基于 PC 和独立 VR 头戴设备安装 XR 插件管理和额外的 XR 插件。
安装 XR 插件管理和 XR 插件
现在,让我们转到编辑 | 项目设置 | XR 插件管理。从这里,通过点击安装 XR 插件管理来继续操作。将 XR 插件管理视为 Unity 和不同 VR、MR 和 AR 系统之间的桥梁。它就像一个中间人,允许 Unity 与这些设备进行通信和有效工作。在 XR 插件管理成功安装后,你可以导航到编辑 | 项目设置 | XR 插件管理,选择各种插件提供商,这将使你的 VR 应用程序能够在你的 VR 头显上以 PC VR 模式运行。以下是一些选项的简要概述:
-
Unity 模拟 HMD:非常适合可能无法直接访问 VR 头显的游戏开发者。Unity 的模拟 HMD 模仿了 VR 头显的功能,提供了一个平台,可以在 Unity 环境中设计、开发和测试你的游戏,而无需物理硬件。
-
Oculus 集成包:一个专门针对 Oculus 设备的 Unity 开发包。这包括平台特定的功能、Avatar 和 LipSync SDKs、空间音频、守护者系统以及对手部追踪的支持。然而,这个包可能会限制你的项目在非 Oculus 平台上的可移植性。
-
OpenXR:由Khronos Group开发的一个卓越的开放标准,为开发者提供了自由,可以针对广泛的 XR 设备提供相同的输入,从而消除碎片化。这消除了需要单独的 Oculus 或 SteamVR 插件的需求,通过允许单个代码库在任何 XR 系统上运行,简化了维护工作。
如果你是一个雄心勃勃的开发者,旨在创建一个能够吸引广泛受众的 VR 体验,无论他们的 VR 硬件如何,OpenXR 将是你的首选。因此,我们将在这本书中利用 OpenXR 插件。
要开始,请在PC和Android标签上启用OpenXR复选框。
此操作将触发 OpenXR 下载到你的 Unity 项目中。下载完成后,将出现一个请求权限重新启动项目的提示。点击是,因为重启是必要的,以便从 Unity 的旧输入模式过渡到新模式。Unity 重启后,你会发现 XR 插件管理中的OpenXR选项现在已激活。然而,还需要添加交互配置文件,如图 3.1旁边所示警告符号所示。

图 3.1 – 如何在 XR 插件管理中为 PC 标签选择 OpenXR 插件
导航到XR 插件管理 | OpenXR,然后在交互配置文件部分点击+图标。在这里,您可以包含您旨在支持的 所有头显的交互配置文件。例如,如果您使用的是Meta Quest系列的 VR 头盔,您应该选择Oculus Touch Controller Profile选项,如图图 3.2所示。

图 3.2 – 选择 Oculus Touch Controller Profile 作为交互配置文件的 OpenXR 选项卡
OpenXR 的交互配置文件是一组标准化的用户输入集,用于 XR 设备,确保了跨各种平台的一致性和兼容性。它们允许开发者一次编程,同时满足多个设备,使开发过程更加高效。例如,来自不同制造商的两个 VR 控制器可能有不同的按钮布局,但通过 OpenXR,它们可以被映射到一组标准交互。这意味着如果 XR 开发者编程一个动作,如抓取或跳跃,只要实现了适当的交互配置文件,它就会在任何控制器上工作,而不管具体使用的是哪种控制器。通过仅添加少量交互配置文件,开发者限制了他们应用程序的兼容性,使其仅限于特定设备集,可能会排除一些用户。相反,尽可能多地包含交互配置文件可以扩大应用程序的覆盖范围,确保它可以在广泛的 XR 设备上无缝使用。
确保为PC和Android都添加交互配置文件。如果您找不到Android选项卡,这意味着您在 Unity 初始设置过程中错过了下载模块。在这种情况下,您必须返回 Unity Hub,并将模块添加到您安装的 Unity 版本中。
你可能想知道为什么我们必须配置相同的设置两次,一次在Windows选项卡下,然后是在Android选项卡下。原因是Windows选项卡启用了 PC VR 的 VR 功能,而Android选项卡允许添加来自不同提供商的插件,以便在您的 VR 头盔上以独立模式运行您的 VR 应用程序。
接下来,让我们讨论Windows和Android选项卡的渲染模式。默认渲染模式是单遍实例化(SPI),但还有一个多遍(MP)渲染模式的选项。这两个都是针对 VR 环境定制的,每个都有自己的优点和局限性。
SPI 提供了相当的性能优势,最显著的是将绘制调用次数减半。这对于独立 VR 耳机至关重要,优化是确保应用程序平稳运行的关键。在 VR 中保持一致的帧率和流畅性对于避免运动病至关重要。此外,SPI 通过从同一实例渲染两只眼睛,保证了视觉一致性,减少了可能导致不适的视觉差异。然而,问题是 SPI 通常需要对着色器进行修改以进行准确的几何处理,这可能会引入另一层开发复杂性。
另一方面,MP 由于不需要特定的着色器修改而具有更好的着色器兼容性。如果您的场景使用了多种着色器,这可能是有益的。在 MP 中,每只眼睛都是独立渲染的,这有时可以通过减少视觉伪影来提高视觉质量。然而,这伴随着性能上的权衡:MP 将绘制调用次数加倍,这可能会使低端设备不堪重负。此外,分别渲染每只眼睛可能会产生轻微的视觉差异,这在 VR 中可能会令人不快。
对于独立 VR 开发,由于其优化优势,SPI 通常是首选。对于提供视觉上引人入胜且在独立 VR 耳机上表现良好的体验至关重要。尽管如此,最近的 Unity 版本在桌面模式下倾向于使用 MP 进行编辑器测试。
在使我们的项目准备好 VR 之后,我们现在可以继续安装 XR 交互工具包及其演示场景。
安装 XR 交互工具包和示例
通过安装 XR 插件管理,我们已经使 Unity 能够与我们的 VR 耳机进行通信。但如何使 Unity 能够从我们的耳机接收信息?以及如何将 Unity 应用程序从 VR 耳机接收到的输入转换为游戏中的动作?这就是 XR 交互工具包发挥作用的地方。要下载 XR 交互工具包,请按照以下步骤操作:
-
导航到窗口 | 包管理器。在包管理器中,您可以查看您当前已导入的所有包,例如OpenXR插件。
-
通过点击
com.unity.xr.interaction.toolkit并选择2.5.1作为版本来下载 XR 交互工具包。
重要提示
在安装包时添加特定版本号是可选的。默认情况下,如果您没有指定版本,包管理器将自动安装 XR 交互工具包的最新版本。虽然对于新项目来说,保持与最新版本的同步通常是建议的,但为了本书的目的,我们强烈建议坚持使用工具包的版本2.5.1。使用这个特定版本确保了在跟随我们的教程时的一致性和易于理解。即使新版本可能保持相似的结构,引入的额外功能和元素可能会使导航我们的教程更具挑战性。因此,为了确保学习体验顺畅,请在阅读本书时使用版本2.5.1。
-
按下Enter键,XR 交互工具包将自动下载到您的项目中。如果您看到一个带有警告的弹出窗口,要求您重新启动 Unity 编辑器,请点击是。这仅仅意味着 XR 交互工具包正在使用一个新的输入系统来验证交互。
-
在
Samples文件夹中展开 XR 交互工具包的有用附加组件列表,并导入起始资产。这是一个包含使设置行为更简单的工具的集合。它包括一组预先制作的行为,您可以用作输入,以及专门为依赖于输入系统的 XR 交互工具包行为设计的预设。
关闭XR 交互工具包文件夹后是实际的 XR 交互工具包,而Samples文件夹包括我们下载的示例附加组件。首先,让我们打开起始资产中包含的演示场景资产。为此,导航到Samples | XR Interaction Toolkit | 2.5.1 | Starter Assets,然后双击演示场景。
在下一节中,我们将探索演示场景资产的不同组件。
探索 XR 交互工具包的演示场景
在本节中,我们将深入了解 XR 交互工具包的演示场景资产。这个场景提供了所有关键概念的全面概述,这些概念对于开发您自己的沉浸式 VR 体验至关重要。如果您已经遵循了上一节中的步骤,现在应该会看到图3.3中所示的场景。

图 3.3 – XR 交互工具包演示场景的场景视图和场景层次结构窗口
通过项目窗口的搜索栏找到攀爬样本。将此预制体从项目窗口拖放到场景层次结构窗口中,将在您的新场景中呈现相同的梯子和攀爬墙,同时结合相关的脚本和功能。同样,XR 交互设置预制体,作为 XR 交互工具包最重要的预制体,将成为本书中讨论的许多即将到来的 XR 项目的标准。您将在下一节中了解更多关于它的信息。
检查预配置的玩家
虽然传送环境、交互样本、UI 样本和攀爬样本预制体都为你提供了将不同类型的交互轻松集成到 VR 场景中的方法,但XR 交互设置预制体是与这些交互组件交互的实体。本质上,它是一个预配置的玩家,旨在在场景中实现无缝导航和交互。您可以将它集成到任何未来 VR 场景中,其中您导入了 XR 交互工具包。让我们开始探索它。
通过在场景层次结构窗口中点击XR 交互设置预制体旁边的箭头,您可以看到其子组件,包括输入动作管理器、交互管理器、事件系统和XR 原点(XR Rig)。通过打开所有子组件,您可以检查该预制体的结构,如图3.4所示。

图 3.4 – 完整 XR 交互设置预制体的组件
为了理解这些组件以及它们如何相互交互,让我们想象一个 VR 游戏场景,其中玩家扮演餐厅的厨师角色,并使用 VR 头盔和控制器与厨房环境进行交互。在这个虚构的例子中,XR 交互设置预制体的组件将承担以下角色:
-
输入动作管理器:该组件负责处理 VR 控制器输入。例如,控制器按钮的按下可以启动诸如握住锅或拿起食材等动作。
-
XR 交互管理器:该组件负责玩家与虚拟对象之间的交互。例如,它管理玩家 VR 手与虚拟按钮(如门打开或灯光开启)交互的结果。同样,如果玩家手持锅,将手移至炉灶上方并释放握把按钮,锅可能会落在炉灶上。
-
事件系统:该组件负责游戏内事件的触发和处理。例如,在成功准备和上菜后,可以触发事件,例如掌声或屏幕上亮起的视觉祝贺信息。
-
XR 起点(XR Rig):这个组件作为玩家在虚拟世界中的锚点,负责管理用户在 XR 环境中的移动和定位。通过利用 VR 设备的数据,XR 起点通过其附加的XR 起点脚本来更新相机和控制器的位置和朝向,从而在虚拟环境中创造移动和交互的错觉。在我们的游戏场景中,XR 起点代表玩家在虚拟厨房中的位置;如果玩家向前迈一步,他们的角色将相应地向前迈一步靠近炉灶。
-
相机偏移与主相机:这个组件跟踪玩家的头部动作。例如,如果玩家将头部转向放在架子上的食谱书,游戏的视角将相应调整以聚焦于书本。
-
左控制器和右控制器:这些组件监控玩家的手部动作,通常与 VR 控制器的位置相对应。如果玩家使用控制器将手伸出来抓取虚拟锅具,场景中的 VR 手将模仿这个动作。这就是为什么手部包含子对象,如戳击交互器用于触摸、直接交互器用于抓取、射线交互器用于指向和传送交互器用于快速移动。
-
注视交互器:这个组件根据玩家的视线或头部注视方向促进交互。例如,如果玩家将注意力集中在特定的食材上,可能会出现一个工具提示来提供更多关于它的信息。由于并非每个 VR 头盔都支持眼动追踪,注视交互器也支持头部追踪。
-
运动系统:正如其名称所暗示的,这个具有相关运动系统脚本的 GameObject 负责为玩家配备不同的移动形式,如转向、行走、传送或攀爬。让我们来看看它的每个子组件:
-
转向:转向GameObject 附有两个重要的脚本,您可以通过在场景层次窗口中选择转向并导航到其检查器窗口来查看。首先,有一个快照转向提供者脚本。这个脚本允许玩家使用 VR 控制器在 VR 环境中以离散的步骤,或“快照”,旋转他们的视角。这在物理转向不方便或不可能的情况下非常有用。
-
第二,有一个连续转向提供者脚本。它允许在 VR 环境中使用 VR 控制器进行平滑、连续的转向,这个脚本提供了快照转向提供者脚本提供的逐步转向的替代方案。
-
Move: 例如,在我们的 VR 餐厅游戏中,玩家可以通过 VR 头显的控制器导航穿过厨房。尽管他们在物理世界中保持静止,但他们的视角在虚拟空间中发生变化,给人一种像真正在虚拟厨房中行走一样穿越环境的错觉。这种功能来自附加到Move游戏对象的Dynamic Move Provider脚本。
-
抓取移动: XR 交互工具包的XR 交互设置预制件中的这个组件促进了 VR 空间中的直观移动。通过将两个抓取移动提供者脚本附加到这个游戏对象上,玩家可以用任何一只手模拟抓住虚拟世界的感受。随着玩家移动控制器,VR 原点反向调整,保持控制器相对于虚拟环境的相对位置一致。与此相辅相成的是,双手抓取移动提供者脚本使玩家能够使用两个控制器来操纵他们的位置,就像抓住两根杆子并拉动或推动自己一样。这种双手交互允许玩家不仅能够在 VR 餐厅游戏中移动,还可以在场景中调整他们的方向和比例。
-
传送: 仅通过Move游戏对象提供的连续移动在虚拟世界中导航,可能会让一些 VR 用户感到恶心,即使他们经常沉浸在 VR 中。这就是为什么大多数 VR 应用主要使用传送功能,它允许玩家通过在 VR 控制器上移动摇杆,在虚拟空间中瞬间出现在新的位置。在此过程中,一个视觉提示,通常是一个圆形覆盖层,指示目标目的地。一旦释放摇杆,玩家就会直接传送到那个位置。XR 交互工具包中的传送游戏对象为我们虚构的 VR 餐厅游戏玩家提供了丰富的传送方式,可以在厨房或用餐区周围传送。例如,玩家可能只能导航到 VR 餐厅中的特定地点,使游戏玩法更加直接和结构化,这对于教育环境或针对 VR 新手的应用程序来说非常理想。如果探索和自发性是 VR 餐厅游戏的核心任务,允许玩家传送到地板上没有椅子、桌子或厨房橱柜的任何部分可能更为有利。
-
由于传送在 VR 应用中的重要性,我们将在下一节中深入了解 XR 交互工具包提供的哪些传送功能。
传送
Demo Scene资产中的传送环境预制件由一个传送区域预制件和四个传送锚点预制件组成。您可以在图 3.5 中看到这些组件。

图 3.5 – 传送区域和四个传送锚点,它们都是传送环境预制件的一部分
传送区域脚本,配备了一个传送区域预制件和一个子立方体,代表了一个可用于传送的空间。用户可以在这个指定区域内指向任何点进行传送,从而在立方体的范围内实现传送。
相比之下,传送锚点预制件作为一个特定的传送点,使用户能够轻松地导航到确切的位置。
想象一个 VR 游戏,用户必须通过从水中的一块石头跳到另一块石头上来穿越河流。河流的另一边是一个森林,一些树下隐藏着金币,他们必须找到这些金币。在这种情况下,传送锚点可以用于水中的每一块石头。这将使用户能够轻松地穿越河流,更多地关注实际的游戏玩法。然而,对于河流的另一边,传送区域脚本将更适合,使用户能够按自己的意愿探索该区域。
在下一节中,你将了解所有关于可抓取对象及其移动类型的内容。
探索可抓取对象
交互式样本预制件,演示场景资产的一部分,包含三个 3D 角色,突出了XR 抓取交互脚本的能力,这是 XR 交互工具包中的一个基本工具。这个脚本很可能会成为你未来 VR 项目中每次想要使对象可抓取时的必备工具。一旦你集成了 XR 交互工具包并在你的任何 VR 项目中配置了 XR 插件管理,使对象可抓取就变得轻而易举。只需在场景层次窗口中突出显示对象,然后在检查器中点击添加组件选项,然后搜索并选择XR 抓取交互脚本。此外,确保XR 交互设置预制件在场景中,因为它提供了所需的玩家以进行交互。
将XR 抓取交互脚本添加到对象中的这一步将其转换成了一个 VR 交互物品。这种易用性和效率是 XR 交互工具包在 VR 开发者中受欢迎的重要原因之一。你不必手动编写大量代码来实现这一功能,你可以将时间集中在通过调整集成的物理设置来完善用户体验。这些调整可以显著提高你的 VR 应用的沉浸感和真实感。
现在,让我们深入了解XR 抓取交互式脚本提供的各种物理配置,以增强物体抓取体验。交互式样本预制件的三个图例分别展示了XR 抓取交互式脚本的运动类型设置的不同选项,如图图 3.6所示。

图 3.6 – 场景视图中演示场景的交互式样本预制件
让我们逐个分析这些图例:
-
可交互运动学环面:当您在场景层次结构窗口中选择此对象并检查其属性时,您将看到其运动类型设置被标记为运动学。运动学对象由软件的计算而不是外部力引导。这意味着它根据游戏引擎的指令平滑移动,不会像普通对象那样受到重力或碰撞的影响。这种类型的运动在需要物体放入特定位置的应用程序中非常有用,例如益智游戏,确保一旦放置,物体就保持静止。
-
可交互的即时金字塔:此图例已将即时选为其运动类型设置。即时运动正如其名:立即。与移动时产生重量或惯性的感觉不同,此对象将立即响应并重新定位,没有任何明显的延迟或漂移。这就像在电脑屏幕上移动光标一样;你指向哪里,它就去哪里。这对于 VR 中的用户界面(UI)交互非常理想,例如选择菜单选项或拖放虚拟文件。在时间敏感的场景中也非常有用,例如快节奏的游戏,玩家必须快速将物体移动到不同的位置,而无需模拟物理交互的延迟。
-
可交互速度追踪楔形物:此图例的运动类型设置为速度追踪。在这里,运动依赖于您手部动作的速度和方向。想象一下扔球;你扔的速度和角度将决定球飞行的轨迹。在 VR 空间中,此对象的运动反映了您手势的速度和轨迹。这种运动类型非常适合体育模拟,如 VR 棒球或篮球,其中玩家的手部速度和方向在游戏动作的执行中起着作用。
您可以通过在您的 VR 头盔上运行演示场景或通过 XR 设备模拟器并导航到抓取交互式对象展台,亲自观察这三种运动类型。
下一节将向您介绍 XR 交互工具包提供的不同类型的用户界面元素。
检查不同类型的用户界面元素
UI 样本预制体在Demo Scene资产中展示了 XR 交互工具包目前提供的不同类型的 UI 元素。您可以在图 3.7中看到它们。

图 3.7 – 示例场景的 UI 样本预制体在场景视图中
在场景层次窗口中点击预制体旁边的箭头以检查其子组件。让我们逐一查看:
-
ModalSingleButton:这个 UI 元素展示了一段简短的文本消息和按钮。这种布局使其成为在需要向 VR 体验用户显示重要弹出通知时理想的 UI 预制体。例如,它可以用来在 VR 会话开始时通知用户他们即将开始一个计时体验。或者,它可以确保用户已经理解了说明或确认了他们对 VR 研究数据使用的同意。
-
交互控件:与ModalSingleButton预制体相比,这个预制体包含多个 UI 元素,为用户提供更详细的输入选项。例如,MinMaxSlider允许用户通过 VR 控制器在最小到最大范围内滑动,以精确指定一个特定状态。Dropdown预制体、Text Toggle预制体和Icon Toggle预制体为用户提供了在 VR 世界中精确表达偏好的方式。这些交互控件预制体的组件在需要复杂用户反馈或指令的上下文中表现突出。例如,用户可以通过Dropdown菜单选择他们想要在 VR 公寓查看体验中看到的房间。他们可以使用MinMaxSlider调整房间照明的强度,并通过Text Toggle和Icon Toggle在地板材料和墙面画作之间切换。
-
滚动 UI 样本:这个预制体包含一个简单的文本块,用户可以使用 VR 控制器滚动浏览。这个元素是 VR 教育部分的一个实用工具,例如在虚拟博物馆游览中深入了解一件艺术品的历程。
通过在场景层次窗口中右键单击 UI 样本预制体并选择 UI 下提供的选项之一,您可以轻松地将更多 UI 元素添加到Canvas组件中,按需操作。
TrackedDeviceGraphicRaycaster脚本是所有使用 XR 交互工具包的 VR 场景中 UI 交互的另一个重要组件。它应该附加到展示 UI 元素的Canvas组件上。在Demo 场景资产的情况下,UI 样本预制件是Canvas组件,因此脚本附加到它上,正如你可以在其检查器窗口中看到的那样。TrackedDeviceGraphicRaycaster脚本给你的Canvas组件提供了 X 光般的视力,以辨别玩家的控制器是否瞄准Canvas组件上的元素。在 VR 环境中,它将控制器动作转换为与Canvas组件上显示的 UI 元素之间的交互。
在下一节中,你将学习如何在与你的 VR 场景中的按钮进行交互。
通过按钮进行交互
我们Demo 场景资产中的Poke 交互样本GameObject 展示了三个独特的按钮,如图3.8所示。

图 3.8 – 演示场景的戳击交互样本中的三个独特按钮
与普通按钮不同,这些按钮被设计成以独特的方式对你的触摸做出反应。左侧的按钮一旦被戳,就会触发粒子动画;中间的按钮会播放声音,而右侧的按钮每次被按下时都会增加其附加到 UI 元素上的数字。
这些按钮都附加了相同的三个脚本:XR 简单交互脚本、XR 戳击过滤器和XR 戳击交互器。尽管它们的风格各不相同,但这些脚本提供了所有这些按钮都需要的重要功能:
-
XR 简单交互脚本:这是使我们的按钮交互式和触摸响应的魔法。没有它,它们在虚拟世界中将仅仅是静态对象,对我们的触摸无动于衷。在场景层次结构窗口中,选择第一个Push按钮并导航到检查器窗口。现在,点击XR 简单交互脚本的交互事件菜单旁边的箭头,以查看与此脚本关联的所有交互事件。向下滚动到选择部分,观察当用户进入或退出此按钮的选择时,粒子系统事件是如何播放或停止的。重复此步骤,查看其他两个按钮的选择部分看起来如何。在本书的后续章节中,你将在交互事件部分创建自己的独特游戏逻辑。
-
XR 戳击过滤器:此脚本评估触摸的真实性。如果触摸不符合其标准,戳击过滤器会阻止其进入。
-
XR 戳击跟随行为:此脚本为按钮提供了逼真的、触觉上的响应。戳击时,相应的按钮被按下,模仿现实世界按钮的运动。释放时,它反弹回原始位置。
在本书的整个过程中,我们将深入探讨创建多样化的 POKE 交互,教你如何自定义这些组件以满足你的特定需求。
在我们探索演示场景资产的最后一步,你将一瞥 XR 交互工具包的更多高级功能。
探索注视交互和攀爬
注视交互是 VR 中的一种沉浸式功能,它允许用户通过指向他们的眼睛或头部注视来触发事件和控制 VR 环境的各个方面。XR 交互工具包的演示场景包含一个专门的展位,用于展示不同类型的基于注视的交互。这些交互类型是 XR 交互工具包中最先进的功能之一,这就是为什么你将在第八章中学习如何将它们实现到你的 VR 场景中,以及其他高级技术。
虽然攀爬在现实生活中是一个要求较高的概念,但在 VR 场景中启用它比人们想象的要容易,尤其是在与注视跟踪等技术相比时。演示场景资产中的攀爬样本预制体展示了两个可攀爬物体:一个梯子和一个攀岩墙。你可以在图 3.9中观察到它们。

图 3.9 – 攀爬样本预制体,包括梯子和攀岩墙等元素
初看之下,它们可能看起来不同,但本质上,它们共享相同的脚本。
要了解如何在你的 VR 场景中使一个物体可攀爬,请按照以下步骤操作:
-
在场景层次窗口中打开攀爬样本预制体。
-
探索梯子和攀岩墙预制体中所有带有可攀爬标签的子组件。在检查器窗口中,你会发现每个这些可攀爬组件都附有 XR 交互工具包的两个相同的脚本:攀爬交互脚本和XR 交互能力状态提供者脚本。
简单地将这两个脚本添加到你的 VR 环境中的任何对象,通过检查器窗口,就可以给它提供可攀爬属性。现在,让我们更深入地探讨这两个脚本的作用:
-
攀爬交互:这个脚本本质上使一个物体可攀爬。当玩家与具有此脚本的物体交互时,他们可以虚拟地攀爬它。
-
XR 交互能力状态提供者:这个脚本有助于微调玩家与可攀爬物体之间的交互。这是一个规定攀爬体验应该如何运作并响应用户交互的系统。
现在我们已经探索了演示场景的所有关键组件,现在是时候让你测试和探索它了。在接下来的部分,我们将讨论几个选项,帮助你开始这段激动人心的旅程。
将 VR 体验部署和测试到不同的 VR 平台或模拟器
创建 VR 场景不仅涉及设计,还包括测试和部署。虽然测试侧重于确保 VR 场景正确运行并提供良好的用户体验,但部署则是将场景传输并优化以在特定的 VR 头戴设备上播放,例如Meta Quest系列、HTC Vive或Valve Index。在早期开发阶段,可能会使用 XR 设备模拟器等工具进行快速测试,但随着项目接近完成,在实际 VR 头戴设备上进行彻底测试变得至关重要。
现在,让我们根据您可用的硬件,逐一介绍测试和部署您 VR 场景的各种选项:
-
没有可用的 VR 头戴设备:在没有 VR 头戴设备的情况下,您可以使用 XR 交互工具包的 XR 设备模拟器来测试您 VR 场景的功能。即使您有可用的 VR 头戴设备,模拟器也可以提供一种比物理连接和测试 VR 头戴设备更快的替代方案,尤其是在您进行简单修改时。
-
自带 VR 头戴设备:大多数自带 VR 头戴设备支持 PC 模式。启用此模式通常是测试您 VR 场景最有效和最强大的方式。然而,有时您可能没有激活 PC 模式的必要电缆。在这种情况下,您有两个主要的测试 VR 场景的替代方案。XR 设备模拟器通常是首选方法,因为直接在自带 VR 头戴设备上测试需要将其部署到设备上。这个过程可能既耗时又费力。在 Android 平台上,这个过程是通过项目的构建设置完成的。因此,如果 PC 模式不可用,您可能需要使用 XR 设备模拟器进行快速调整和场景的微小修改。对于实质性的修改或全面的用户体验测试,直接部署到头戴设备上可能是更可取的。
-
基于 PC 的 VR 头戴设备或启用 PC 模式的自带 VR 头戴设备:如果您拥有基于 PC 的 VR 头戴设备或已启用 PC 模式的自带 VR 头戴设备,您的测试和部署选项将得到扩展。对于您 VR 场景的微小修改,XR 设备模拟器可能就是您所需要的。对于中等至重大的修改,只要 VR 头戴设备连接到SteamVR或Oculus软件,您就可以通过在 Unity 场景中按播放按钮轻松地在头戴设备上测试 VR 场景。对于相当大的修改或分析整体用户体验时,您可以通过在构建设置中连接到SteamVR或Oculus软件的 VR 头戴设备,通过Windows/Mac/Linux部署您的 VR 场景。
您可能对SteamVR或Oculus软件的内容以及何时需要它们感到好奇。简单来说,这两个都是软件平台,不仅让您能够玩 PC VR 游戏,还能在您的耳机上测试和部署 VR 体验。您将在本章接下来的部分中了解更多关于这两个平台的信息。一般来说,我们会根据您拥有的耳机类型推荐以下内容:
-
Meta Quest 系列耳机:在您的电脑上安装 SteamVR 和 Oculus 软件,并学习如何通过这两个 VR 平台将您的 VR 场景部署到 VR 耳机上,因为这些耳机支持两者。这两种部署方式都非常容易操作,但它们不仅让您能够更彻底地测试您的场景,而且可以轻松地触及更广泛的受众。
-
Valve Index、HTC Vive 系列或其他非 Meta 耳机:只需安装 SteamVR,并学习如何将您的 VR 场景部署到 VR 耳机上。
以下章节将更深入地探讨这些选项中的每一个,提供安装 XR 设备模拟器、SteamVR 和 Oculus 软件的详细指南。请随意跳转到与您相关的部分。
安装 XR 设备模拟器
现在,我们将了解安装和使用 XR 设备模拟器的要点,这是 VR 开发工作流程中的一个宝贵工具,它允许您在模拟环境中模拟用户输入以控制 XR 设备。从导入工具包到在 Unity 项目中有效使用它,我们将通过综合示例详细说明每个方面。
作为 XR 交互工具包的一部分,您可以通过 Unity 的包管理器轻松导入 XR 设备模拟器。以下是进行此操作的步骤指南:
-
在您的 Unity 项目中,导航到Windows | 包管理器 | XR 交互工具包。
-
通过选择XR 交互工具包包的样本选项卡,您将在列出的元素中找到XR 设备模拟器。
-
通过点击 XR 设备模拟器旁边的导入按钮,将其导入到您的项目中。
在成功安装 XR 设备模拟器后,让我们使用它来测试 XR 交互工具包的演示场景资产。
使用 XR 设备模拟器
要将 XR 设备模拟器集成到演示场景或您未来的任何 VR 场景中,通过项目窗口的搜索栏搜索XR 设备模拟器。这样,您将找到XR 设备模拟器预制件,这是您需要添加到希望模拟 XR 输入的场景中的资产。现在,只需将这个预制件拖放到您的 VR 场景的场景层次结构窗口中。在继续之前,请确保XR 交互设置预制件也已添加到您的场景中。现在,点击播放按钮以探索 XR 设备模拟器的功能。图 3.10显示了 XR 设备模拟器在播放模式下的外观。

图 3.10 – 当 XR 设备模拟器添加到场景时,XR 交互工具包演示场景的播放模式
您现在已经准备好使用模拟器提供的按键绑定来导航您的场景,特别是WASD键。按下Tab键可以在左侧控制器、右侧控制器和 VR 头盔之间切换活动控制。使用您的鼠标,您可以探索场景或调整控制器的角度,这取决于您是在头盔模式还是控制器模式下操作。按下G键可以使您与场景中的对象进行交互,包括按下按钮。在尝试了 XR 设备模拟器并熟悉了不同的按键后,您将迅速体会到它作为 VR 场景测试工具的简单性和有效性,然后再转向真实 XR 硬件部署。
尽管 XR 设备模拟器可能非常强大和方便,但将您的场景测试和部署到 VR 头盔上的体验没有比这更沉浸的。下一节将解释如何使用 SteamVR 来完成这项工作。
设置 SteamVR
SteamVR 是由Valve Corporation为 VR 应用程序和内容开发的一个平台。它是更大的Steam平台的一部分,这是一个非常流行的游戏和软件在线市场,以其庞大的图书馆和活跃的社区而闻名。对于 VR 开发者来说,使用 SteamVR 可以非常有优势,因为 SteamVR 中的 VR 内容有可能触达全球数百万用户。SteamVR 支持广泛的 VR 头盔,包括HTC Vive、Valve Index、Windows Mixed Reality和Meta Quest系列。在撰写本书时,我们不知道有任何商业上可用的 VR 头盔不支持 SteamVR。它基本上是 VR 头盔市场的一个默认标准。
有趣的是,即使是基于 Android 而非主要基于 PC 的 VR 的Meta Quest系列,也允许开发者将 VR 场景和应用部署到 Meta 的专有 Oculus 平台,以及 SteamVR 平台。这种多功能性非常有益。如果您是Meta Quest系列头盔的拥有者,我们强烈建议您学习在两个平台上测试和部署您的场景。让我们用一个例子来说明这一点。
假设您正在创建一个需要复杂手部交互的 VR 游戏,如物体操作和复杂操作。您的目标是满足HTC Vive、Valve Index和Meta Quest系列头盔的用户。通过利用 SteamVR 及其 SteamVR Unity 插件,您可以一次开发游戏并确保所有这些头盔的兼容性。SteamVR 的精确跟踪系统增强了游戏在各种设备上的沉浸感和响应性。开发完成后,您可以在 Steam 平台上发布您的游戏,从而接触到庞大的用户群,包括使用 SteamVR 的Meta Quest系列头盔的用户。
在下一节中,您将学习如何安装 SteamVR。
安装 SteamVR
要针对 SteamVR 进行开发,你必须首先安装和设置 SteamVR。为此,请执行以下步骤:
-
从官方网站(
store.steampowered.com/about/)下载 Steam 到你的 PC,创建一个 Steam 账户,并通过 Steam 软件登录此 Steam 账户。 -
在 Steam 内,在 Steam 商店中搜索
SteamVR,选择玩游戏按钮,并按照屏幕上的说明开始安装 SteamVR。 -
SteamVR 安装完成后,通过有线连接或无线连接(如Air Link用于Meta Quest系列)将你的头戴设备连接到你的 PC。然后,你可以在 Steam 软件内搜索 SteamVR 插件,并在你的常规 PC 应用中点击
SteamVR,或者以任何方式,你应该很快就能看到你的 VR 头戴设备已连接到你的 PC 上的 SteamVR。在你的 VR 头戴设备内,你现在应该能看到 SteamVR 环境和游戏商店。
虽然一些 VR 头戴设备,如Valve Index,只需要安装 SteamVR 软件来测试和部署 VR 体验,但许多其他头戴设备制造商要求安装额外的软件与 SteamVR 一起使用。例如,Windows Mixed Reality设备,包括HP Reverb系列,也需要安装Mixed Reality Portal。这些安装通常很简单,通常不需要你采取任何其他步骤,除了每次你想将你的 VR 头戴设备连接到 PC 时打开下载的软件。由于这些软件要求可能会随时间变化,我们建议你检查是否需要为你的特定 VR 头戴设备型号安装制造商特定的软件以进行测试或部署。
安装和设置 SteamVR 以及可能的一些制造商特定的软件后,下一节将揭示你如何最终测试和部署你的场景到你的 VR 头戴设备上。
使用 SteamVR 测试和部署你的 VR 场景
在 Unity 中为 SteamVR 开发时,你可以使用播放按钮直接在编辑器中测试你的 VR 场景。安装了 SteamVR 插件后,Unity 编辑器将识别连接的 SteamVR 兼容头戴设备,并将场景以 VR 模式渲染。这使你能够在不离开 Unity 环境的情况下快速评估更改、解决问题和优化你的 VR 内容。
当你准备好部署你的场景时,你可以将项目构建成一个可执行文件,该文件可以在 Unity 之外运行。
在将 VR 头戴设备连接到 SteamVR 后,返回你的 Unity 项目。在这里,在你的 Unity 项目中转到文件 | 构建设置。确保你的首选目标平台字段,例如 Windows,已被选中,并且架构字段设置为 64 位。最后,你可以通过点击构建设置中的构建和运行按钮将你的 VR 场景部署到头戴设备上。一旦构建完成,项目可以通过 Steam 客户端在 SteamVR 中启动,让你像最终用户一样在头戴设备上体验 VR 场景。
如果你拥有Meta Quest系列的 VR 头戴设备,为 Oculus 设置你的 VR 场景对你来说将和为 SteamVR 设置一样重要。下一节将解释如何进行此操作。
设置 Oculus
在本节中,我们将探讨为你的 VR 开发项目设置 Oculus 的步骤。我们将详细介绍在 PC 上安装 Oculus 应用,如何使用 Oculus 测试你的 VR 场景,以及如何使用 Oculus 部署你的 VR 场景。
安装 Oculus
要在 Unity 中使用 Oculus,你首先需要在你的 PC 上下载并安装 Oculus 应用。完成以下步骤:
-
在你的网络浏览器中导航到www.oculus.com/setup。
-
在你选择的 VR 头戴设备,如Meta Quest Pro下方,点击下载软件。
-
打开下载的 Oculus 应用并点击立即安装按钮。
-
按照屏幕上的说明创建 Oculus 账户并设置你的 VR 头戴设备。
安装和设置完成后,终于到了测试和部署你的 VR 场景到 Oculus 的时候。这个过程将在下一节中描述。
使用 Oculus 测试和部署你的 VR 场景
一旦 Oculus 软件安装到你的 PC 上,你就可以直接在 Unity 编辑器中测试你的 VR 场景。以下步骤将指导你如何操作:
-
将你的 Oculus 兼容 VR 头戴设备连接到你的 PC。确保 Oculus 应用识别到它。
-
在 Unity 中打开你的 VR 项目。
-
在 Unity 编辑器中点击播放按钮以开始场景。Unity 将自动在 VR 中渲染场景,允许你使用 Oculus 头戴设备与场景交互。
在测试和改进你的 VR 场景后,你可以构建和部署它,以便在 Unity 之外体验。完成以下步骤:
-
在 Unity 中打开你的 VR 项目,转到文件 | 构建设置。
-
确保你的首选目标平台字段,例如 Windows,已被选中。
-
确保架构设置为 64 位。
点击构建和运行按钮。Unity 将构建你的项目可执行文件并运行它。构建完成后,可执行文件可以通过 Oculus 软件启动。现在,你可以使用 Oculus 头戴设备完全体验你的 VR 场景,就像你的最终用户一样。
摘要
在本章中,您已经探索了 Unity 中 VR 开发的激动人心的领域。您已经学会了从头开始创建基本的 VR 场景,并掌握了在多种设备上的部署过程。现在,您应该已经掌握了 XR 交互工具包及其演示场景中的信息元素,这将使您能够更有信心和熟练地生成基本的 VR 场景。
此外,这些获得的技能并不仅限于特定类型。无论是工业应用还是学术研究,您在 VR 开发方面的新技能应该允许您有效地复制此过程,以适应您遇到的任何用例。
随着我们进入下一章,我们将拓宽我们的视野,包括在 Unity 中创建和部署 AR 场景。
第四章:Unity 中的 AR 开发
在本章中,我们将沉浸在 AR 开发的迷人领域,从在 Unity 中创建我们的第一个 AR 项目到在设备或模拟器上启动我们的第一个 AR 场景。我们将向您介绍 Unity 提供的众多 AR 工具包和插件,并指导您了解它们的独特功能。
我们将逐步讲解在 Unity 中建立 AR 项目的过程,确保它为顺利部署到任何支持 AR 的设备做好准备。
本章将涵盖以下主题:
-
理解 AR 领域
-
使用 AR Foundation 在 Unity 中设置 AR 项目
-
在 Unity 中直接测试 AR 体验
-
将 AR 体验部署到移动设备上
技术要求
在我们深入探讨 Unity 编辑器的实用性之前,确保您的计算机系统能够胜任这项任务是非常重要的。需要Unity 2021.3 LTS或更高版本,才能完成本书中将要探索的练习。通过比较 Unity 网站上提供的系统要求来检查您的硬件兼容性,网址为docs.unity3d.com/Manual/system-requirements.html。
由于我们将在本章中探索 AR 开发,我们需要一个能够支持 ARKit 或 ARCore 的 Android 或 iOS 设备。请查看您的设备是否满足这些要求,网址为developers.google.com/ar/devices。
理解 AR 领域
当我们开始探索 AR 时,首先理解使这项技术成为可能的基础元素至关重要。我们的日常设备是如何如此轻松地将我们的物理现实与数字世界交织在一起的?是什么机制允许您的设备感知、解释和与周围的世界互动?也许最引人入胜的是,一个简单的屏幕如何变成通往增强现实的大门?
在本节中,我们的目标是解开 AR 的复杂原理和机制,将它们提炼成易于理解的形式。
如果 AR、MR 和 VR 等术语对您来说仍然模糊不清或可以互换,请考虑回顾第一章以获得澄清。现在,我们的重点仍然是 AR,它通过叠加数字域的元素来改变我们的世界。让我们看看 AR 提供的不同类型体验。
存在哪些类型的 AR 体验?
AR 领域是多样化的,体验通常通过以下几种媒介之一呈现:手持移动 AR、AR 眼镜或其他类型的 AR,如基于投影的 AR 或空间 AR。每种形式都有其独特的特点,其应用取决于上下文和所需的沉浸程度。让我们了解更多关于这些的信息:
-
手持移动增强现实:手持移动增强现实可能是最普遍的增强现实形式,因为智能手机的普及。想象一下这种类型的增强现实就像是一个通向丰富现实的窗口。通过智能手机或平板电脑的屏幕,用户见证了数字和现实的交织。这种数字内容叠加在实时摄像头流上的做法为原本静态的物理世界注入了活力。这一点的典型例子是流行的游戏宝可梦 GO,其中用户在看似居住在我们自己世界中的数字生物中狩猎。
-
增强现实眼镜:另一方面,增强现实眼镜提供了一种更沉浸式和无手操作的增强现实体验。当用户戴上这些眼镜时,他们直接进入一个增强世界,无需额外的设备。得益于眼镜中集成的透明显示屏、传感器和摄像头,数字信息无缝地融入用户的视野。这项技术的意义深远,潜在应用范围广泛,从制造业和医疗保健到娱乐行业。专为增强现实眼镜设计的游戏示例是名为宝可梦 GO AR+的新版本游戏。宝可梦 GO AR+彻底改变了游戏的原有概念,充分利用了增强现实眼镜的功能。当佩戴增强现实眼镜时,玩家可以更深入地沉浸在宝可梦世界中。他们可以看到在现实世界环境中的宝可梦,就像它们真的在那里一样。宝可梦站和道馆在现实世界的位置可见,玩家可以直接与之互动。例如,如果出现宝可梦,玩家可以伸手触摸它并启动捕捉序列。游戏还允许使用增强现实环境与其他玩家进行实时战斗模拟。
注意
尽管手持移动增强现实和增强现实眼镜都作为进入增强现实的途径,但它们在形态、用户体验和沉浸程度方面存在显著差异。移动增强现实作为通向增强世界的便携式门户,可以通过用户的智能手机或平板电脑访问。另一方面,增强现实眼镜提供了一种完全沉浸式的体验,其中增强世界直接呈现在用户的视野中。鉴于智能手机的普及,本书将主要关注 Android 和 iOS 手持设备的增强现实开发。
然而,这并不意味着增强现实眼镜缺乏潜力或用途。对手持设备的关注主要反映了它们当前的更广泛使用和可及性。尽管如此,增强现实眼镜提供了手持设备无法比拟的显著机会和沉浸程度。尽管本书专注于手持增强现实,但它涵盖的增强现实开发的基本原则,如理解三维空间、用户交互和用户体验设计,在很大程度上也适用于增强现实眼镜。对增强现实眼镜开发感兴趣的读者仍然可以从中获得宝贵的见解,尽管他们可能需要通过专注于增强现实眼镜技术的额外资源来补充他们的学习。
-
基于投影的 AR:基于投影的 AR 将数字图像投射到现实世界的表面上。基于投影的 AR 在汽车行业中有显著的应用,其中 AR 已经开始产生重大影响。如导航、速度和其他重要数据等信息可以投射到车辆的挡风玻璃上,为驾驶员提供实时视觉提示,而无需他们离开路面。
-
空间 AR:空间 AR 使用全息显示屏来创造虚拟对象与我们的物理环境共存的错觉。全息显示屏可以比作数字海市蜃楼,通过结合光投影和光学技术来创建三维虚拟对象,使其看起来像在空间中漂浮。这种形式的 AR 不需要额外的设备或可穿戴设备,使用户能够像它们物理存在一样与全息图进行交互。
在探讨了 AR 体验的类型之后,我们现在将深入研究使虚拟对象在现实世界中叠加的技术和概念。
什么是基于标记和无标记 AR?
AR 建立在一系列基础原则上,这些原则允许虚拟对象在我们的物理世界中准确定位并实现真实交互。这些原则涉及各种技术和方法,例如基于标记的 AR和无标记 AR。
让我们现在更深入地了解这些技术。
基于标记的 AR
基于标记的 AR 依赖于特定的标记或目标来启动 AR 内容的显示。这些标记可以有多种形式,例如具有可识别图案的物理对象、二维码或图像。当 AR 系统检测到标记时,它会在其上叠加数字内容。
在开发 AR 应用时,可以使用多种类型的标记来触发 AR 内容的显示。以下是 AR 中常用的一些标记的概述:
-
图像标记:这些是作为 AR 内容触发器的独特视觉图案或图像。当 AR 系统通过摄像头检测到这些标记时,它会在其上叠加相应的数字内容。
-
二维码:快速响应(QR)码,这是一种包含特定信息的二维条码,也可以作为 AR 标记。当摄像头或二维码扫描库识别这些代码时,它可以触发显示特定的 AR 内容或交互。
-
3D 对象标记:这些标记涉及使用特定的物理对象作为 AR 内容的触发器。AR 系统识别对象的形状和特征,并使用这些数据来叠加数字内容。
-
基于位置的标记器:这些标记器利用用户的地理位置数据来触发 AR 内容。通过利用 GPS 或其他位置跟踪技术,AR 系统可以在与用户当前位置相关的数字内容上叠加。
-
基于代码的标记:这些是专门设计的图案或符号,可以被 AR 系统识别并用作触发器。这些标记使用特定的算法创建和解码,为 AR 体验提供高度的可定制性和灵活性。
要使用的标记类型取决于你的 AR 应用的具体要求。如期望的用户体验、跟踪精度和标记识别的简便性等因素将指导标记的选择。
虽然许多 AR 体验使用标记,但并非所有都如此,你将在下一小节中了解到。
无标记 AR
无标记 AR,也称为基于位置的 AR或同时定位与地图构建(SLAM)-基于 AR,不依赖于预定的标记或视觉线索。它使用机载传感器和复杂的算法将数字信息叠加到物理世界中。传感器可以包括全球定位系统(GPS)、加速度计和摄像头,以确定用户在物理环境中的位置和朝向。了解用户的位置后,这些 AR 系统根据地理坐标在物理周围叠加虚拟内容。
让我们深入了解实现无标记 AR 的各种选项,并探索它们的实际应用:
-
基于地理位置的 AR:这种方法主要使用 GPS,适合在户外环境中将 AR 对象放置在更大规模的位置。
这里的一个例子是 Niantic 的游戏《精灵宝可梦 GO》。使用设备的 GPS,游戏在现实世界中的位置放置虚拟宝可梦生物,允许玩家找到并捕捉它们。
-
Wi-Fi 定位系统(WPS):这种方法根据 Wi-Fi 信号强度和来源确定设备的位置。它对于室内 AR 体验特别相关,因为 GPS 可能不太有效。例如,室内地图提供了一个结合磁性信息和 Wi-Fi 信号的室内导航平台。这已被用于增强购物中心中的 AR 体验,使用数字标记引导用户到特定的商店或景点。
-
蓝牙和超宽带(UWB):这些定位技术旨在为微定位体验而设计,在较小的空间如房间或展览中提供高精度。一个实际的应用案例可以在博物馆和画廊中看到,在那里蓝牙信标被用于增强现实(AR)应用中。这些应用根据访客与特定艺术品或展览的接近程度,向他们提供多媒体内容。
-
SLAM(同步定位与建图):SLAM 是一种更高级的技术,在跟踪用户位置的同时创建环境的数字地图。这项技术涉及复杂的算法,并使用设备的摄像头和其他传感器。想象一下你在一个黑暗的房间里,你打开了一盏手电筒。当你移动手电筒时,你开始看到并记住不同物品的位置,比如椅子或桌子。随着时间的推移,你在脑海中构建了整个房间的地图。SLAM 做的是类似的事情。它最适合需要在小空间内准确放置和交互物体的应用。
这的一个例子是宜家的应用IKEA Place。在应用中,用户可以从宜家目录中选择一件家具,应用将 3D 模型叠加到摄像头视图中,使用户能够看到该物品在家中会是什么样子。
-
深度感应:这涉及到使用高级传感器,如飞行时间(ToF)或光探测与测距(LIDAR)传感器来捕捉周围环境的深度信息。这种方法允许更精确地放置和遮挡虚拟对象,基于深度信息,数字对象可以正确地出现在真实世界物体后面。
这的一个例子是苹果的ARKit 4.0平台,该平台集成了利用某些 iPad 和 iPhone 型号上可用的 LIDAR 扫描器的深度 API。深度 API 使得 AR 体验更加逼真。《Complete Anatomy》应用程序使用 ARKit 的深度感应将详细的 3D 人体解剖模型放置到现实世界中,使用户能够像它真实存在一样探索和与之交互。由于深度感应,这个模型不会意外地出现在你的沙发中间,而是会正确地站在它旁边。
-
机器学习和人工智能:人工智能和机器学习的最新进展为无标记增强现实(AR)开辟了新的可能性。机器学习模型可以被训练以识别不同类型的环境和物体,为更智能和互动的 AR 体验提供上下文。
这的一个例子是谷歌的ARCore平台,该平台使用机器学习来识别和增强特定的物体或物体类型。谷歌的AR Animals功能使用 ARCore 让用户在谷歌上搜索动物,然后通过 AR 在他们的空间中查看该动物的 3D 模型。
无标记 AR 为创建沉浸式和互动的 AR 体验提供了巨大的可能性。无论是在游戏、室内设计、教育还是其他无数的应用中,它都有潜力彻底改变我们与数字世界的互动方式。
理解 AR 交互输入类型
步入增强现实(AR)的领域,人们很快就会意识到,这不仅仅关乎人们所能看到的物理与虚拟现实的迷人融合。它同样关乎人们如何与这些层叠的数字增强进行交互,这是一个由 AR 输入定义的维度。这些输入——用户与 AR 内容交互的模式——作为连接点,塑造了整体的 AR 体验。
随着我们进一步探讨这个话题,让我们聚焦于各种 AR 输入类型以及它们如何为现实世界应用注入活力:
-
触摸输入:触摸输入是 AR 交互的基础。简单来说,用户可以通过在 AR 设备屏幕上触摸手势来与数字叠加层进行交互,无论是智能手机还是平板电脑。AR 中的触摸输入不仅包括点击,还包括其他手势,如滑动、捏合和拖动。可以使用的手势将取决于 AR 应用程序的编程方式。例如,捏合手势可能用于放大或缩小 AR 对象,滑动可能旋转对象,拖动可以在 AR 场景中移动对象。目标是使与 AR 元素的交互尽可能直观和自然。Snapchat 镜头提供了触摸输入在应用中的经典例子。用户只需轻触不同的屏幕区域,就可以使 AR 滤镜动画化或引起变化。
-
设备运动:设备运动是另一个关键的 AR 输入。通过利用设备上的加速度计、陀螺仪和磁力计的数据,AR 应用程序可以将设备的朝向和运动作为输入。这种输入类型对于涉及在环境中导航或控制虚拟元素的用户体验特别有用。以游戏 Pokémon Go 为例,玩家可以通过挥动设备来模拟投掷宝可梦球的行为。
-
语音命令:语音命令为 AR 应用程序注入了免提和易于访问的交互方式。Google Glass这款 AR 眼镜设备将语音命令作为其核心输入方法之一。用户只需说出“好的,Glass”,然后跟上一个命令,如“获取路线”或“拍照”,就可以与设备交互。
-
眼动追踪:眼动追踪通常用于高级 AR 眼镜。通过跟踪用户的眼动,这些系统允许用户仅通过注视即可与 AR 内容进行交互。North Focals AR 眼镜是这一技术在应用中的良好例子。用户只需移动眼睛,就可以控制一个小型的虚拟光标。
-
手势追踪和手势识别:在高度沉浸式的 AR 系统中,手势追踪和手势识别可以用来解释和追踪手部动作,使用户能够直接触摸和与虚拟对象交互。微软的HoloLens 2就是这一技术的例子,它允许用户用手势操作全息图像,捏合来调整大小,或轻触进行交互。
-
物理控制器:物理控制器可以从手持设备到提供触觉反馈和精确控制的可穿戴技术(如手套)不等,适用于特定的 AR 应用。例如,Magic Leap One AR 头戴式设备配有手持控制器,通过允许用户以更细腻的方式与虚拟内容交互,将用户沉浸在 AR 体验中。
正如我们所见,AR 输入可以显著影响 AR 体验的沉浸感。输入方法的选择取决于 AR 应用的具体性质。因此,理解和实施最合适的输入方法可以极大地增强 AR 系统的真实性和可用性。
注意
由于本书主要关注手持式移动 AR 设备,为确保读者能够轻松复制书中展示的所有项目,我们选择将范围限制在触摸输入。
在下一小节中,我们将探讨 Unity 中可用的 AR 工具包,这些工具包可以用来实现我们刚刚讨论的技术。
Unity 的流行 AR 工具包
在本节中,我们深入探讨 Unity 的 AR 工具包系列,为寻求在 AR 开发之旅中导航的新手和经验丰富的开发者提供概述。每个工具包都提供独特的功能,帮助开发者制作引人入胜的 AR 体验。现在让我们看看其中的一些:
-
Vuforia:Vuforia 是一个广泛采用的 AR 平台,提供了一组计算机视觉能力,可以适应基于标记和无标记的 AR 体验。其丰富的功能集包括图像跟踪、物体识别和目标识别,具有广泛的平台支持。另一个值得注意的功能是 Vuforia 的云识别,允许开发者远程托管大量目标图像,进一步扩展 AR 体验的潜力。
-
ARKit:在苹果的游乐场中,ARKit 是针对 iOS 设备体验的最佳工具包。它专门为 iOS 生态系统量身定制,为开发者提供了一系列高级功能,如世界跟踪、面部跟踪和场景理解。这些元素共同丰富了用户的 AR 体验。ARKit 主要使用 Swift 和 Objective-C,这是苹果的专有编程语言。然而,通过 AR Foundation 包与 Unity 集成时,开发者可以利用 C#,从而提供一个更易于访问和熟悉的编程环境。
-
ARCore:谷歌的 ARCore 是 ARKit 的 Android 版本,专为全球最受欢迎的移动操作系统量身定制。ARCore 为开发者提供了环境理解、运动跟踪和光估计等功能,这些都是制作逼真 AR 体验的必要元素。主要来说,ARCore 使用 Java 进行本地开发。但与 ARKit 的集成类似,ARCore 可以通过 AR Foundation 包集成到 Unity 项目中,允许开发者使用 C#。
-
AR Foundation: AR Foundation 是 Unity 的高级 API 包,用于构建 AR 应用程序,统一了 ARKit 和 ARCore 的功能。这个巧妙的包使得创建跨平台的 AR 体验变得单一且流程化,消除了为 iOS 和 Android 编写单独代码库的需要。这就像拥有一本通用的食谱集,而不是每种菜肴的单独食谱书。使用 AR Foundation,开发者可以利用广泛使用、功能多样的 C# 编程语言,使制作 AR 应用的过程更加高效和直观。
如果你分别使用 ARCore 和 ARKit,你需要为每个平台编写不同的代码集。你需要使用 ARCore 在 Android 上构建你的 AR 应用,然后使用 ARKit 重新编写代码,使其在 iOS 上运行。
然而,通过使用 AR Foundation 开发 AR 应用,你只需要编写一套适用于 iOS 和 Android 的代码。AR Foundation 提供了一个统一的 API,与 ARCore 和 ARKit 兼容,这意味着你不需要为每个平台编写不同的代码。它简化了开发过程,节省了大量时间和精力。
注意
在本章中,我们将专注于使用 AR Foundation 创建 AR 应用程序。
然而,重要的是要记住,在特定场景下,使用 ARCore 或 ARKit 可能会提供独特的优势,这得益于每个平台独有的特定功能。例如,从 版本 3.5 开始,ARKit 带来了 LIDAR 支持。这个功能利用了集成到某些 iPhone 和 iPad 模型中的 LIDAR 扫描仪,提供了精细的场景理解和精确的深度估计。另一个 ARKit 独有的功能是从 ARKit 3 开始的 运动捕捉 功能,它允许开发者记录人类动作并将其应用于 3D 角色模型,有效地将设备转变为动作捕捉工作室。
另一方面,ARCore 也为 Android 设备提供了一套独特的功能。其中一个功能是 Depth API,它使用单个 RGB 相机生成深度图。虽然 ARKit 也具有深度感知能力,但 ARCore 的 Depth API 可以在更广泛的设备上运行,甚至在没有专用深度传感器的设备上。ARCore 的另一个独特功能是 增强图像,它允许应用程序在固定位置跟踪和增强图像,为与海报、壁画和类似物品的交互提供了可能性。
重要提示
在本节中提到的示例,在阅读这本书时可能不适用。由于 ARKit、ARCore 和 AR Foundation 不断演变,查阅最新的文档(docs.unity3d.com/Packages/com.unity.xr.arfoundation@5.0/manual/index.html)对于获取最新和最准确的信息非常重要。
现在,我们终于可以开始我们的第一个 Unity AR 项目了。
使用 AR Foundation 在 Unity 中设置 AR 项目
在本节中,您将学习如何使用 AR Foundation 在 Unity 中设置一个简单的 AR 项目。您将了解如何放置简单的对象,如立方体,添加平面检测功能,并将触摸输入和锚点实现到您的 AR 场景中。
然而,在使用 AR Foundation 在我们的第一个 AR 应用程序之前,我们首先必须了解这个包的架构。
理解 AR 基础架构
在本节中,我们将深入探讨 Unity 的 AR 基础架构的激动人心的世界,这是一个使您能够在各种平台上创建 AR 体验的包。无论您旨在为 Android、Apple 还是 HoloLens 创建应用程序,AR Foundation 都极大地简化了这一过程。其广泛的功能包括平面检测、图像和对象跟踪、面部和身体跟踪,以及点云等。图 4.1 将 AR Foundation 的架构分解为组件的层次结构,这些组件无缝协作,为不同设备提供一致的 AR 体验。

图 4.1 – AR 基础架构
AR 应用 代表开发者构建 AR 体验的应用程序。它与 管理器 直接相关联,这些管理器作为特定 AR 功能的主要接口。
AR PlaneManager 对于检测和跟踪现实世界的平面至关重要,例如地板或墙壁。它提供了一个与用户周围物理环境交互的一致方式,向应用提供用户周围表面数据。
同样,ARRaycast 管理器 在理解这个 AR 空间中的用户交互方面发挥着至关重要的作用。它将射线投射到 AR 场景中,确定这些射线与真实世界表面的交点。当用户打算在这些表面上放置虚拟对象或希望与虚拟元素相关联地与真实世界交互时,这一点尤为重要。
深入研究,这些管理器与 子系统 交互,这些子系统是抽象层,与实际的平台特定模块进行通信。XRPlane 子系统 标准化了与平面检测相关的数据,确保无论底层工作是由 ARKit 还是 ARCore 完成,平面相关的事件和数据都是统一的。XRRaycast 子系统 提供了一个一致的射线投射接口,抽象了每个平台方法的细微差别。
最后,提供者 代表为每种设备类型提供 AR 功能的平台特定 SDK。ARKit SDK 是苹果为其 iOS 设备做出的贡献,具有专门的平面检测和射线投射子系统。另一方面,ARCore SDK 是谷歌为 Android 提供的解决方案,与 ARKit 提供的功能类似,但针对 Android 生态系统进行了定制。
如您所见,AR Foundation 通过允许开发者集中精力在他们的 AR 体验上,而不必担心平台特定的复杂性,为 XR 开发者提供了一个统一的框架。通过其分层架构,它确保无论部署在 iPhone 还是 Android 设备上,应用程序都保持一致且高质量。
有了这个理解,现在是时候在 Unity 中创建我们的第一个 AR 项目了。
使用 Unity 的 AR 模板创建 AR 项目
在 Unity 中创建一个 AR 项目相当简单。按照以下步骤开始:
-
根据你的目标 AR 平台——Android 或 iOS——你首先需要导航到 Unity Hub 中的
Installs文件夹,点击你版本旁边的设置图标,选择添加模块,并安装适当的构建支持。要在 AR Unity 模板中展示你的项目,你需要遵循后续的步骤。
-
在 Unity Hub 的项目窗口中,点击右上角的新建项目按钮。
-
选择AR模板,并为你的项目起一个独特的名字,如图图 4.2所示。

图 4.2 – Unity Hub 中可用的 AR 模板
为什么选择 AR 模板?
在 Unity 的世界里,AR 模板就像一个富饶的花园,已经预装了 AR 基础、ARKit Face Tracking、ARKit XR-、ARCore XR-、Magic Leap XR-和 OpenXR 插件等预安装包,更不用说一个示例场景了。然而,你可能会注意到这个茂密的花园里有一些对你目标景观不必要的植物:Android 或 iOS。为了保持花园的整洁,你可以从 Unity 自己的苗圃——包管理器中,有选择地挑选你需要的种子——OpenXR 插件、AR 基础、输入系统和 ARCore XR 插件(用于 Android)或 ARKit XR 插件(用于 iOS),并将它们种植在一个普通的 3D 场景中。
- 最后,点击创建项目。
一旦场景在 Unity 编辑器中加载,它应该看起来像图 4.3所示的那样。

图 4.3 – Unity 的 AR SampleScene
重要提示
如果你没有在 Unity 编辑器中看到图 4.3所示的场景,你可以通过选择资产 | 示例资产 | SampleScene手动打开它。
新打开的场景包含方向光、AR 会话原点和AR 会话GameObject。如果你希望将这些对象带入一个新的场景,你可以在层次结构中右键点击,选择XR | AR 会话来召唤一个AR 会话GameObject。通过选择XR | AR 会话原点,可以以类似的方式召唤AR 会话原点GameObject。这就是最初施展的魔法。
重要提示
在本书出版时,AR 会话原点 和 AR 会话 代表了集成到 AR 基础 模板中的默认 GameObjects。然而,鉴于 AR 基础 的动态特性,预计会有持续更新和修订。有迹象表明,AR 会话原点 将在未来的版本中演变为 XR 原点 (移动 AR)。
如果您遇到此类更改,请不要担心。本章的精髓保持不变,并且可以轻松导航。我们建议访问我们的 GitHub 仓库以克隆我们已工作的特定项目版本,确保与 Unity 兼容。通常,从过时的 GameObjects 转换到它们的较新版本是无缝的,可能需要最少的,如果不是任何,对现有逻辑的调整。
保持适应性,并记住:这里提出的核心概念和基础仍然是您的指南,即使工具在不断发展。
在我们开始检查这些 GameObjects 之前,我们首先需要调整我们 AR 场景的一些项目设置。
修改项目设置
要定义我们想要针对我们的 AR 场景使用的提供者,请转到 编辑 | 项目设置 下的 XR 插件管理。根据我们针对的平台,无论是 Android 还是 iOS 设备,我们激活相应的 ARCore 或 ARKit 复选框。如果您想同时拥抱这两个平台,请启用两个复选框。这将安装提供者包到您的项目中。
重要提示
如果您看不到 Android、iOS 或两者都的选项卡,那么很可能是 Android 或 iOS 构建支持 模块尚未集成到您的编辑器中。让我们看看我们如何解决这个问题。
图 4**.4 显示了在 Unity Hub 中标记的构建支持模块的已安装 Unity 编辑器。

图 4.4 – 已安装的 Unity 编辑器,已标记的构建支持模块
显示的图像表明 Unity 编辑器中缺少 iOS 构建支持 模块。要调整此问题,请转到 Unity Hub 中的 安装 选项卡。点击 Unity 编辑器安装右上角的 设置 图标。然后,选择 添加模块,为 iOS 构建支持 或 Android 构建支持(如果您愿意,也可以两者都选)启用复选框,并安装它们。安装完成后,返回到您项目的 XR 插件 管理 窗口。
现在,您应该在 XR 插件管理 下的 ARCore 和 ARKit 选项卡下找到它们。
现在,选择 ARCore 选项卡以探索与您 Unity 项目中 ARCore 包的配置和设置相关的字段。图 4**.5 显示了带有其默认设置的 ARCore 选项卡。

图 4.5 – 默认设置的 ARCore 选项卡
让我们逐一介绍每个字段的函数:
-
需求:此参数决定了 ARCore 对您应用程序的必要性。如果设置为必需,则将 ARCore 确立为目标设备的一个基本组件。相反,当标记为可选时,ARCore 被视为一个附加功能,当存在时补充应用程序的功能,但不是应用程序核心功能的必需品。
-
深度:这是赋予您的设备在其环境中深度感知能力的工具。对于遮挡和其他高级 AR 效果非常有用,它允许您在 ARCore 中切换深度估计。如果您将深度设置为必需,则您的 AR 应用程序将需要深度估计功能才能运行。另一方面,选择可选意味着如果设备支持,您的 AR 应用程序可以利用深度估计功能,但如果这些功能不存在,也不会影响基本功能。
-
忽略 Gradle 版本复选框:这是您对 Gradle 构建系统的控制,它是构建 Android 应用程序的必备工具。当未选中时,Unity 将遵循项目指定的 Gradle 版本。然而,如果选中,Unity 将获得自主权,忽略指定的版本,并选择使用其默认版本。
虽然默认设置——需求和深度字段都设置为必需,以及忽略 Gradle 版本复选框未选中——适用于大多数项目,但也有一些例外。例如,如果您正在创建一个针对具有不同能力的各种设备的 AR 应用程序,或者如果您的应用程序的主要功能并不严重依赖于 ARCore 的深度感知,您可能希望将深度字段设置为可选。此外,如果您正在处理需要特定 Gradle 版本或与较新版本存在冲突的项目,选中忽略 Gradle 版本复选框将是必要的。然而,对于本章,我们可以保持默认设置。
接下来,我们将注意力转向ARKit选项卡。就像其 ARCore 对应物一样,这些字段与您的 Unity 项目中 ARKit 包的配置和设置相关联。图 4.6显示了具有默认设置的ARKit选项卡。

图 4.6 – 具有默认设置的 ARKit 选项卡
让我们来解码图 4.6中显示的所有字段的含义:
-
需求:与 ARCore 的需求字段作用类似,此指示器宣布 ARKit 是否被认为是您项目的重要部分。
-
面部追踪:作为一个开关,此复选框启用或禁用 ARKit 中的面部追踪功能。当激活时,它允许使用设备的前置摄像头跟踪和识别一系列面部特征和表情。
目前,我们将遵循默认设置——需求字段保持为必需,并且人脸追踪复选框保持关闭状态,因为目前不需要。
在接下来的章节中,我们将深入研究与AR模板一起的 GameObject。我们将探讨它们的作用,并揭示它们为何如此重要。让我们从 AR 会话 GameObject 开始。
理解 AR 会话 GameObject
AR 会话GameObject 管理着你的 AR 应用的生命周期。要了解它,请在场景层次结构中点击它,并导航到检查器窗口。如图图 4.7所示,AR 会话GameObject 包含AR 会话和AR 输入****管理器组件。

图 4.7 – 选择 AR 会话 GameObject 时的检查器窗口
让我们了解图 4.7中显示的每个字段:
-
尝试更新复选框:当勾选此复选框时,这是你对 AR 会话的指示,要求它对保持设备的姿态和追踪状态与每一帧和每一滴答保持更新保持警觉。勾选此框命令 AR 会话勤奋地获取新的追踪数据,确保即使设备的追踪暂时波动,AR 元素也能保持与真实世界的对齐。想象一个 AR 投篮游戏。在这个游戏中,你通过设备的屏幕看到虚拟篮筐叠加在你的真实世界环境中。为了使游戏运行良好,确保你的设备的追踪数据持续更新至关重要。这就是尝试更新复选框的作用所在。
激活尝试更新命令指示游戏持续刷新追踪状态,确保虚拟对象与真实世界环境的和谐,即使出现暂时的追踪损失。
-
匹配帧率复选框:当勾选此复选框时,意味着你要求 AR 会话与设备的相机帧率同步。AR 会话调整其节奏以匹配相机的,最终实现和谐的视觉体验。考虑一个允许用户在他们的实际空间中构想虚拟家具的 AR 应用。
勾选的匹配帧率复选框确保 AR 会话的帧率与相机同步,抑制实际空间和虚拟家具之间的视觉不协调,从而实现精确的美学评估。
-
追踪模式下拉菜单:这是定义你的 AR 会话追踪质量的关键。所选模式决定了 AR 系统对设备在真实世界中的运动和位置的感知和响应。想象一个在物理世界之上叠加虚拟箭头的 AR 导航应用,以引导用户。
在这个导航应用程序中,选择 旋转和位置跟踪 提供了完整的跟踪能力,确保虚拟箭头准确追踪现实世界的轮廓,精确地引导用户沿着他们的路径。
对于我们当前的探索,我们将坚持默认设置 – 两个 尝试更新 和 匹配帧率 复选框都被勾选,并且 跟踪模式 设置为 位置和旋转。在未来,你的这些设置选择应反映你的项目目标和预期的用户体验。为了发现最适合你需求的最佳组合,我们鼓励你尝试不同的设置和配置。
在 AR 会话之下,第二个组件是 AR 输入 管理器组件。
AR 输入管理器组件将用户的 AR 场景交互转换为有意义的输入。它感知和处理各种用户输入,如点击、触摸和手势。它是使你的 AR 应用程序交互性无形之手,允许放置对象或与虚拟元素交互。例如,想象一个 AR 游戏,用户通过点击来消除虚拟目标。AR 输入管理器脚本读取屏幕上的点击,并提供必要的信息来释放游戏中的射击动作。
现在,我们的重点转向 AR 会话起源 GameObject。
探索 AR 会话起源 GameObject
AR 会话起源 GameObject 是控制物理世界与 AR 中投射的虚拟对象之间同步的主要元素。它包含各种组件,如 AR 会话起源、AR 平面管理器、AR 锚点管理器、AR 光线投射管理器和锚点创建器,正如我们在 图 4.8 中所看到的。

图 4.8 – 选择 AR 会话起源时的检查器
对于我们 AR 开发的启动阶段,我们只需要 AR 会话起源组件。因此,你现在可以暂时禁用所有其他组件。
将 AR 会话起源视为你的 AR 体验的支点。它为在 AR 环境中锚定虚拟对象提供了一个基础。让我们想象一个 AR 应用程序,允许用户将虚拟家具放置在他们家中。在这里,AR 会话起源组件正确地安排和定位虚拟家具在用户的物理空间内。
AR 会话起源确保用户的环境与显示的 AR 场景的位置和方向对齐。例如,当用户放置一个虚拟椅子时,此脚本会保持椅子的定位和方向,无论用户在房间内的移动。这就是为什么这个组件对于创建真实的 AR 体验至关重要。
为了将虚拟物体与真实世界的视频混合,AR 会话需要存在一个相机。在你场景中已经存在主相机的情况下,你可以安全地移除它。AR 会话原点集成了自己的子AR 相机。这个相机没有用于单色背景的天空盒,预先配备了必要的组件,如相机、跟踪姿态驱动器、AR 相机管理器和AR 相机背景,如图图 4.9所示。

图 4.9 – 当选择 AR 会话原点的子 AR 相机时的检查器
现在我们来详细了解每一个:
-
就像现实世界的相机一样,相机组件捕捉并显示游戏场景的一部分给玩家看——本质上,就是你在玩 AR 游戏时在设备屏幕上看到的内容。它可以定位和旋转,以捕捉游戏场景中的不同视角。
-
AR 相机管理器组件控制手机相机的设置,如面向方向、光估计和自动对焦。自动对焦使相机自动调整其焦点以保持 AR 物体清晰,就像普通相机中的自动对焦一样。光估计允许你选择 AR 系统如何估计真实世界的光照条件,以使虚拟物体看起来更真实。选项范围从根本不估计光照(无)到估计光照的各个方面,如环境光强度和颜色,以及主光源的方向和强度。面向方向决定 AR 相机面向的方向。世界设置通常是用于后置摄像头(查看环境),而用户是用于前置摄像头(自拍模式)。无禁用此设置。目前,我们可以保持这些设置不变。
-
跟踪姿态驱动器组件获取关于设备物理位置和方向的信息,统称为姿态,并使用这些信息来设置 Unity 游戏场景中相机的位置、旋转和缩放。这被称为相机的变换。这确保了 AR 场景与手机的移动保持一致。为了方便这一过程,跟踪姿态驱动器提供了几个可配置的选项。设备允许你选择正在跟踪的设备类型。姿态源允许你选择提供跟踪数据的设备部分。跟踪类型下拉菜单指示跟踪哪种类型的运动(旋转、位置或两者)。
更新类型决定了跟踪信息何时更新,是在常规更新周期中、在渲染下一帧之前,还是两者都更新。如果勾选了使用相对变换复选框,则跟踪数据基于设备相对于其初始状态的位置和旋转。
最后,可以启用使用姿态提供程序字段以利用外部源进行跟踪数据,这对于专门的跟踪系统可能很有用。这些设置共同赋予跟踪姿态驱动器处理广泛 AR 场景的灵活性。
-
AR 相机背景组件控制您的设备相机捕获的真实世界视图在 AR 场景中的显示方式。使用自定义材质复选框允许您应用自定义材质,例如,为真实世界视图添加特殊视觉效果。如果未选中,则真实世界视图将按原样显示,不添加任何额外效果。
AR 会话原点 GameObject 执行将 AR 会话空间转换为 Unity 世界空间的临界任务。鉴于 AR 中使用的独特坐标系(称为 AR 会话空间),这种转换对于准确定位 GameObject 相对于 AR 相机至关重要。
在心中牢记我们 AR 场景中最重要的 GameObject 的信息,现在是时候在我们的 AR 场景中放置一个简单对象了。
将一个简单的立方体放入 AR 场景
为了开始测试我们的 AR 功能,我们需要在场景中有一个 3D 对象来可视化 AR 效果。为此目的,您可以创建一个简单的立方体对象。在项目层次结构中右键单击,选择0,0,3)并应用旋转(30,0,0),如图图 4**.10所示。

图 4.10 – 立方体的变换值
这些特定的坐标和旋转只是示例,可以根据您的需求进行修改。
关键目标是将对象放置在 AR 相机方向上,并在一个明显的距离处。这种放置将有助于验证 AR 系统是否正确地将虚拟内容叠加到真实世界中,因为它为您与物理环境对齐提供了一个基准。它还允许您评估 AR 系统的深度感知能力。
为了验证立方体是否会在 AR 视图中正确显示,您可以选择层次结构中的 AR 相机 – 这将在场景窗口的右下角显示一个相机视图 – 或者切换到游戏窗口,如图图 4.11所示。11*。

图 4.11 – Unity 项目展示如何验证立方体是否会在 AR 视图中正确显示
在 AR 应用程序中,AR 会话原点通常对应于 AR 体验开始时您的设备相机的起始位置。然而,直接在会话原点放置虚拟对象确实可能引起一些问题。以下是一些可能出现的潜在问题:
-
不准确的缩放比例:如果你将一个虚拟立方体直接放置在会话原点,它相对于现实世界中的物体可能会显得不成比例地很大或很小。这就像将一个真实物体非常靠近你的眼睛看——即使是小物体也会显得很大。
-
跟踪干扰:会话原点作为跟踪设备在现实世界中的运动的参考点。如果你在这个确切点放置一个虚拟物体,AR 系统可能难以准确跟踪物体和设备的运动。
-
不愉快的用户体验:如果一个虚拟物体直接放置在会话原点,它可能会显得离用户太近,甚至遮挡用户对其他 AR 场景的视线,从而造成不愉快的体验。
小贴士
为了避免这些问题,通常建议将虚拟物体放置在会话原点的合理距离之外。确切的定位将取决于你的 AR 体验的具体要求。例如,如果你正在创建一个 AR 家具摆放应用,你可能根据检测到的现实世界表面(如地板和桌子)来定位虚拟家具。这样做可以确保虚拟家具以适当的比例出现,不会干扰跟踪,并在现实世界中出现在正确的位置,从而提供愉快的用户体验。
在放置你的立方体后,你可以按照本章“将 AR 体验部署到移动设备”部分中概述的说明进行测试。目前,你的 AR 应用很简单,只在前方用户面前放置了一个静态对象。然而,我们希望提供更互动的体验,因此将在下一节深入探讨锚点和平面检测功能。
在 AR Foundation 中实现平面检测
在本节中,我们将利用 AR Foundation 的平面检测功能。AR Foundation 的平面检测通过提供对现实世界环境的基石理解,为众多实际应用奠定了基础。它识别和解析平坦表面的能力使得数字对象能够与物理空间进行有意义的、真实的交互,从而增强整体增强现实体验。
在零售和电子商务领域,平面检测对于准确的产品可视化至关重要。它确保虚拟沙发被放置在你的客厅墙壁前,而不是在你房间中的随机位置。
这种技术也为 AR 游戏中的沉浸式体验奠定了基础。通过识别现实世界表面,如《精灵宝可梦 GO》等游戏可以准确放置虚拟元素,增强追逐的乐趣。其他游戏使用这项技术来在你的咖啡桌上创建世界,通过确保虚拟对象与物理平面进行令人信服的交互来维持这种错觉。
要使用平面检测,启用在探索 AR 会话原点 GameObject部分中禁用的AR Plane Manager组件。然后,您还可以删除立方体,因为我们不再需要它了。现在,选择AR Session Origin并检查层次结构中的AR Plane Manager组件。
Unity 的 AR Foundation 中的AR Plane Manager组件负责通过您的设备摄像头检测和跟踪现实世界表面或平面。它利用 AR 技术来理解物理环境,创建可以与虚拟对象交互的数字表示。
下面是AR Plane Manager所做的工作的分解:
-
平面预制件:这实际上是用于表示检测到的平面的数字模板或蓝图。当AR Plane Manager在现实世界中识别到一个平坦的表面(一个平面)时,它会在 AR 空间中创建一个Plane Prefab实例。每个预制件实例对应于一个特定的现实世界平面,提供了一个可以放置或与之交互的虚拟对象的表面。
假设,例如,您正在创建一个 AR 游戏,其中虚拟猫四处游荡。Plane Prefab实例可以是一个猫可以行走的平坦表面。如果您的客厅地板被检测为一个平面,将创建一个Plane Prefab实例,为您的猫提供嬉戏的表面。
-
检测模式:此设置确定AR Plane Manager应检测的平面的方向。以下是检测模式中一些对您有用的组件:
-
一切:此设置通过AR Plane Manager结合了水平和垂直平面的检测。如果您正在创建一个 AR 家具放置应用,您可能会使用此设置。该应用可以检测地板(水平平面,用于放置椅子)和墙壁(垂直平面,用于挂画)。
-
水平:AR Plane Manager将仅检测水平方向的平坦表面,例如地板和桌面。例如,如果您正在创建一个 AR 游戏,其中角色在地板上跑来跑去,您可能会使用这种模式。
-
垂直:相反,此设置将仅检测垂直方向的表面,例如墙壁和门。这可能在允许用户在墙上放置虚拟画作或墙纸的 AR 室内设计应用中使用。
-
由于我们想要检测水平和垂直平面,下拉选择可以保持在一切。
接下来,您会注意到 AR 模板已经分配了一个ARPlane预制件。这个预制件就是您将在检测到的表面上方看到的。由于这个预制件已经配置好了,您可以使用ARPlane预制件。然而,您也可以创建您定制的平面预制件。这可以通过在层次结构窗口中右键单击并选择XR | AR 默认平面来完成。
Unity 的 AR Foundation 中的 AR 默认平面 GameObject由各种组件组成,每个组件在整体系统中执行特定功能。以下是每个组件所做工作的分解:
-
AR 平面:此脚本控制 AR 环境中平面的基本行为。此脚本中有两个值得注意的字段如下:
-
移除时销毁复选框:如果选中,当检测到的飞机被移除或不再需要时,相应的平面GameObject 将被销毁或从 Unity 场景中移除以释放资源。想象一下,这就像在玩完玩具后打扫玩具,为其他活动腾出空间。
-
顶点变化阈值:此字段控制飞机对其检测到的形状变化的敏感度。如果现实世界表面发生变化,飞机的网格顶点需要更新。此阈值确定在更新发生之前需要多少变化。这就像决定何时调整拼图,因为拼图已经移动——太频繁可能是不必要的,而太稀少则图片可能没有意义。
-
-
AR 平面网格可视化器:此脚本负责渲染检测到的平面的视觉表示。想象一下,你正在使用手机上的 AR 应用来预览在购买之前房间里的家具。当你用手机的摄像头指向地板时,应用检测到一个平坦的表面——一个平面。AR 平面网格可视化器随后在你的手机屏幕上创建一个可见的网格或图案叠加,代表这个检测到的平面。
-
跟踪状态可见性下拉菜单(无,有限,跟踪):此设置确定飞机何时应该可见,基于跟踪质量。例如,你可能只想在飞机完全被跟踪(高质量)时看到它,或者当跟踪有限(低质量)时也看到它。这就像决定何时显示图片——如果它模糊不清,你可能更喜欢等待它加载到清晰为止。
-
隐藏包含复选框:如果选中,当一个检测到的平面被另一个平面包含(即完全被更大的平面覆盖)时,较小的平面将被隐藏。这可以使 AR 场景更简洁、更高效。想象一下,这就像在放下一个完全覆盖它们的更大地毯时移除较小的地毯。
-
网格碰撞器:此组件允许虚拟对象以固体表面的方式与飞机进行物理交互。例如,如果你将一个虚拟球体扔到平面上,网格碰撞器确保球体弹回而不是穿过表面。
-
网格过滤器和网格渲染器:它们共同创建并显示平面的 3D 网格。网格过滤器生成平面的形状(网格),而网格渲染器应用材质和纹理并在屏幕上渲染它。它们分别像雕塑家和画家一样,共同工作以创建逼真的雕像。
-
线渲染器:这个组件通常用于绘制检测到的平面的边界,帮助用户看到平面的范围。就像在某个区域周围画上粉笔轮廓来指示其边界一样。
所有这些组件协同工作,以检测、表示和与你的 AR 应用程序中的真实世界表面进行交互,确保虚拟对象与物理环境的无缝融合。你可以保留我们场景的默认设置。
在创建 Prefabs 后,接下来拖动 Prefabs 文件夹。这样做将自动将其创建为预制件。现在选择 AR 会话原点,将 AR 默认平面 预制件拖动到检查器中 AR 平面管理器 组件的适当 平面预制件 字段,如图 图 4.12 所示。

图 4.12 – 分配给 AR 平面管理组件适当平面预制件字段的 AR 默认平面预制件
现在,你的应用程序将能够检测你环境中的平面,并将你选择的平面预制件放置在其上方。
图 4.13 展示了 Unity AR 模板的默认平面预制件。

图 4.13 – Unity AR 模板的平面预制件检测公寓的木地板
如我们所见,使用 AR 基础库,将平面检测集成到项目中并将图案投影到检测到的表面上非常简单。在下一节中,我们将结合使用锚点和触摸输入来合并这些概念。这种组合将使我们能够通过在屏幕上轻触来简单地放置一个对象到检测到的表面上。
实现触摸输入和锚点
要开始使用触摸输入和锚点,当选择 AR 会话原点 时,在检查器中启用 AR 锚点管理器、AR 光线投射管理器 和 锚点创建器 组件。这些组件就是我们需要的,以便使触摸输入和锚点工作。让我们逐一分析它们:
-
AR 锚点管理器 脚本:AR 锚点管理器作为你 AR 空间中对象稳定性的守护者。当你在你 AR 场景中为虚拟对象指定位置时,锚点管理器确保对象始终与该特定真实世界位置相连,无论设备视角如何变化。它就像一个监管者,保持每个虚拟对象相对于真实世界坐标的正确位置。
-
AR Raycast Manager脚本:作为您 AR 应用的触觉感知,AR Raycast Manager从您的设备向场景发射不可见的射线。当这些射线遇到表面时,它们会返回有关其位置和方向的数据。这个过程对于放置虚拟对象在现实世界表面上的交互等操作至关重要,因为它使您的应用能够感知和理解环境的拓扑结构。
-
Anchor Creator脚本:此脚本作为一个高效的工具,简化了在场景中创建和放置新锚点的过程。鉴于锚点对于在一致的现实世界位置固定虚拟对象至关重要,Anchor Creator简化了生成这些锚点的过程。这可以包括放置新的虚拟对象到使正在运输的对象固定不动。
尽管所有组件都有一个Prefab字段,但我们只需要将一个预制体分配给AR Anchor Manager组件。当我们在屏幕上点击时,这个预制体会被实例化。
当您点击屏幕时,AR Raycast Manager通过从屏幕触摸点向 AR 场景发射射线来确定您在现实世界中的指示位置。如果这个射线击中了一个检测到的表面,AR Anchor Manager就会在这个现实世界位置创建一个锚点,并将预制体与之绑定。这个过程确保了您的虚拟对象在 AR 场景中的稳定定位。
附在AR Anchor Manager上的预制体本质上充当了您想在 AR 环境中实例化(或创建)的对象的模板,无论何时屏幕被点击。这就是为什么将预制体分配给AR Anchor Manager至关重要的原因。
其他组件不需要预制体,因为它们不直接负责在您的 AR 场景中创建对象。AR Raycast Manager负责检测您与之交互的现实世界表面,而Anchor Creator则促进锚点本身创建和放置。这些任务都不需要从预制体中创建新对象。
为了演示目的,我们使用了一个简单的胶囊原形。只需在层次结构中右键单击,然后选择0.2,0.2,0.2)。现在,在Project文件夹中创建一个名为Prefabs的新文件夹(右键单击 + 创建 | 文件夹),并将胶囊拖入此文件夹。这将自动创建一个胶囊的预制体,您可以将它拖入AR Anchor Manager组件的Anchor Prefab字段。
现在,当您触摸屏幕时,您的应用应该会在触摸输入处实例化胶囊。图 4.14显示了部署的应用。

图 4.14 – 部署的应用
上一张图片说明了屏幕点击后实例化的胶囊预制件。这些胶囊位于检测到的表面之上,证实了 AR 系统的有效运行。具体来说,AR Raycast Manager 准确地将射线从屏幕触摸点投射到检测到的表面,作为回应,AR Anchor Manager 成功创建锚点,将预制件锚定在指示的位置。现在一切应该都运行得很好,是时候将场景构建到您的设备上了。根据您是否使用 Android 或 iOS 设备,您可以在下一节的相关子节中导航。
在 Unity 中直接测试 AR 体验
自 AR Foundation 5.0 以来,开发者可以使用 XR 模拟 功能方便地在 Unity 编辑器中测试 AR 场景,而无需不断在移动设备上部署。到您阅读这本书的时候,这个功能可能已经预先安装。让我们通过以下步骤快速检查:
-
导航到编辑 | 项目设置。
-
选择XR 插件管理。
-
在插件提供者下查找XR 模拟选项并启用它。
如果您看不到XR 模拟选项,您需要手动安装 AR Foundation 5.0 或更高版本。下一节将解释如何进行此操作。
安装 AR Foundation 5.0 或更高版本及相关包
当您编辑项目清单时,您控制着 Unity 将哪些包版本加载到您的项目中。有两种方法可以编辑项目清单:在包管理器中按名称添加包,或手动编辑项目清单文件。让我们在包管理器中完成它:
-
选择窗口 | 包管理器以打开包管理器窗口。
-
点击小图标
com.unity.xr.arfoundation。这将自动添加最新版本。在撰写本文时,这是版本 5.1.0。如果您想使用特定版本,您可以在版本(可选)字段中输入您想要的版本。
-
继续更新
com.unity.xr.openxr。此操作将导入 OpenXR 插件的最新版本。 -
如果您是从 AR Foundation 4 升级到较新版本,请卸载
com.unity.xr.arkit-face-tracking和com.unity.xr.arsubsystems。如果它们出现在搜索结果中,请继续卸载;否则,它们不在您的项目中。 -
接下来,根据您目标移动设备平台,更新 ARCore 或 ARKit 包非常重要。导航到
com.unity.xr.arcore并确保其版本与 AR Foundation 保持一致。对于 iOS 平台,输入com.unity.xr.arkit,确保其版本与 AR Foundation 匹配。
注意
总是记得查阅 AR 基础 文档以获取最新版本细节和编辑器兼容性:docs.unity3d.com/Packages/com.unity.xr.arfoundation@5.0/manual/project-setup/install-arfoundation.html。
现在,如果你通过上述快速检查重新访问XR 插件管理,XR 模拟选项应该会在Windows、Mac、Linux 设置标签页中可见,如图 4.15 所示。

图 4.15 – 启用 XR 模拟复选框的 XR 插件管理窗口的 Windows、Mac、Linux 设置标签页
此功能激活后,你就可以选择一个环境并在 Unity 中测试 AR 场景了。
选择环境和测试场景
要在 Unity 中测试 AR 场景,你需要一个模拟真实世界设置的环境。为了找到正确的模拟设置,请转到 窗口 | XR | AR 基础 | XR 环境。在 XR 环境 界面的中间位置,有一个 环境 下拉菜单。最初,你的项目将只提供一个环境选项。虽然可以通过导入示例环境来添加更多选项,但 DefaultSimulationEnvironment 通常足以满足大多数测试需求。只需选择此选项。一旦做出选择,点击播放按钮以激活播放模式并开始模拟。现在你将能够实时查看你的场景,如图 4.16 所示。

图 4.16 – 运行时的 XR 模拟
按下播放按钮会将你切换到 XR 模拟 的 游戏 模式,展示模拟的 AR 场景(如图 4.16 中的 1 所示)。在此模式下,你可以根据需要调整视角,实时见证如平面检测等特性。一旦对视角满意,你可以通过左上角的下拉菜单从 游戏 模式切换到 模拟器 模式(如图 4.16 中的 2 所示)。切换到 模拟器 模式对于访问 XR 模拟 的功能,如触摸输入,非常重要。观察图 4.16 中显示为 2 的场景,你会注意到如独特的白色点图案,指示检测到的平面,以及白色胶囊,标记鼠标点击的位置。
然而,了解XR 模拟的限制至关重要。一些元素可能看起来比预期的要小,分辨率可能不是最清晰的。尽管XR 模拟提供了一个方便的测试途径,但它并不是在真实设备上部署 AR 场景的完整替代品。将其视为在您对部署到目标移动设备有信心之前进行迭代测试的工具。
现在,让我们继续在智能手机上启动场景并观察结果。
将 AR 体验部署到移动设备上
现在是时候将您的 AR 体验部署到智能手机或平板电脑上了。主要来说,您有两个途径来完成这个任务:部署到 Android 或 iOS 设备。
对于个人项目,如果 AR 应用程序仅用于个人使用,您可以选择仅部署到 Android 或 iOS,具体取决于您的设备操作系统。然而,对于涉及多个用户的更大规模项目——无论是学术的、工业的还是任何其他规模的组织——建议在 Android 和 iOS 平台上部署和测试 AR 应用程序。
这种策略有多个好处。首先,如果您的应用程序获得动力或其使用范围扩大,它将已经与两个主要平台兼容,从而消除了以后进行耗时移植的需要。其次,从一开始就在两个平台上提供您的应用程序可以吸引更多用户,并可能吸引更多的资金或支持。
这还有另一个关键优势,那就是 Unity 提供的跨平台兼容性。这使您可以为两个平台维护一个单一的代码库,简化了应用程序的管理和更新过程。任何修改都需要在一个位置完成,然后部署到两个平台。
在下一节中,我们将深入探讨将您的 AR 场景部署到 Android 设备上所需的步骤。
部署到 Android
本节概述了将您的 AR 场景部署到 Android 设备上的步骤。过程的前一部分涉及在您的手机上启用一些设置,以准备测试。以下是一个逐步指南:
-
确认您的设备与 ARCore 兼容。ARCore 是 AR Foundation 正确工作的必要条件。您可以在
developers.google.com/ar/devices找到支持的设备列表。 -
安装 ARCore,这是 AR Foundation 用来在 Android 设备上启用 AR 功能的应用。ARCore 可以从 Google Play Store 下载,链接为
play.google.com/store/apps/details?id=com.google.ar.core。 -
激活开发者选项。为此,打开您的 Android 设备上的设置,向下滚动,并选择关于手机。找到构建号并连续点击七次,直到出现消息提示您现在是开发者!
-
返回到主设置菜单后,你现在应该会看到一个名为开发者选项的选项。如果它不存在,请进行在线搜索以了解如何为您的特定设备启用开发者模式。虽然前一步中描述的方法是最常见的,但可用的各种 Android 设备可能需要略微不同的步骤。
-
在开发者选项启用后,打开USB 调试。这将允许您通过 USB 电缆将您的 AR 场景传输到您的 Android 设备。导航到设置 | 开发者选项,向下滚动到USB 调试,并将其打开。确认任何弹出提示。
-
根据您的 Android 版本,您可能需要允许安装来自未知来源的应用:
-
对于 Android 7(牛轧糖)及更早版本:导航到设置 | 安全设置,然后勾选未知来源旁边的框以允许安装来自 Google Play Store 之外的应用。
-
对于 Android 8(奥利奥)及更高版本:选择设置 | 应用与通知 | 特殊应用访问 | 安装未知应用并激活未知来源。您将看到一个可以授予安装未知来源权限的应用列表。这就是您选择文件管理器应用的地方,因为您正在使用它从 Unity 下载未知应用。
-
-
使用 USB 电缆将您的 Android 设备连接到您的计算机。通常您可以使用设备的充电电缆进行此操作。您的 Android 设备上会出现提示,要求允许计算机进行 USB 调试。确认它。
在您的 Android 设备为测试 AR 场景做好适当准备后,您现在可以继续部署您的 Unity AR 场景。这涉及到在 Unity 编辑器的构建设置和玩家设置中调整几个参数。
这里有一个逐步指南,说明如何进行此操作:
- 选择文件 | 构建设置 | Android,然后点击切换平台按钮。现在,您的构建设置应该看起来像图 4.17中所示。17*。

图 4.17 – Unity 为 Android 的构建设置配置
-
接下来,点击
Android 7.0 Nougat (API level 24)或更高版本。这是至关重要的,因为 ARCore 至少需要 Android 7.0 才能正常工作。 -
保持处于
com.company_name.application_name。这种模式是 Android 中广泛采用的命名应用包的惯例,用于确保每个应用在 Google Play Store 中的唯一标识。 -
返回到
构建。选择此文件夹后,Unity 将在新创建的构建文件夹中构建场景。
这就是如何设置您的 Android 设备以部署 AR 场景到它。在下一节中,您将学习如何将您的 AR 场景部署到 iOS 设备,例如 iPhone 或 iPad。
部署到 iOS
在我们深入讨论将 AR 场景部署到 iOS 设备的过程之前,讨论某些硬件先决条件是很重要的。遗憾的是,如果你正在使用 Windows PC 和 iOS 设备,这并不像部署在 Unity 中制作的 AR 场景那样简单。原因在于,苹果以其特有的风格,要求使用Xcode,其专有开发环境,作为中间步骤。这只能在 Mac 设备上使用,不能在 Windows 或 Linux 上使用。
如果你没有 Mac,仍然有方法将你的 AR 场景部署到 iOS 设备上。以下是一些替代方案:
-
借用 Mac:获取 Xcode 并部署你的应用程序到 iOS 设备的最简单方法是向朋友或同事借用 Mac。也值得检查当地图书馆、大学或共享工作空间是否提供对 Mac 的公共访问。对于商业或学术项目,强烈建议投资购买 Mac 以测试你的 AR 应用程序在 iOS 上的运行情况。
-
使用虚拟机:另一个无需成本的替代方案是在你的非苹果 PC 上建立 macOS 环境。然而,由于潜在的法律问题和稳定性问题,苹果既不推荐也不建议这种方法。因此,我们不会进一步阐述或推荐它。
-
使用 Unity 插件:幸运的是,一个广泛使用的 Unity 插件可以相对轻松地将 AR 场景部署到你的 iOS 设备上。通过 Pierre-Marie Baty 的
iOS Project Builder for Windows导航。尽管这个插件需要 50 美元,但它比购买 Mac 便宜得多。购买插件后,将其导入到 AR 场景中,并按照插件的文档(www.pmbaty.com/iosbuildenv/documentation/unity.html)正确配置一切。
在这本书中,我们专注于使用 Mac 运行 Unity 和 Xcode 将 AR 应用程序部署到 iOS 设备上。这是由于其他上述方法可能存在的不一致性和维护问题。
在开始部署设置之前,请确保你的 Mac 和 iOS 设备已安装必要的软件和设置。以下步骤详细说明了这个准备过程:
-
确保你的 MacOS 和 iOS 设备上安装了最新版本的软件。通过在每个设备上导航到设置 | 通用 | 软件更新来检查更新,并安装任何可用的更新。
-
确认你的 iOS 设备支持 ARKit,这对于 AR Foundation 的正确运行至关重要。你可以在
developer.apple.com/documentation/arkit/检查兼容性。一般来说,任何运行 iPadOS 11 或 iOS 11 及更高版本的设备都是兼容的。 -
你将需要 Apple ID 来完成以下步骤。如果你没有,你可以在
appleid.apple.com/account创建一个。 -
从 Apple 的开发者网站
developer.apple.com/xcode/下载Xcode软件。 -
通过前往设置 | 隐私与安全 | 开发者模式,启用开发者模式,然后重新启动你的设备。如果你找不到开发者模式选项,请使用数据线将你的 iOS 设备连接到 Mac。打开Xcode,然后导航到窗口 | 设备和模拟器。如果你的设备没有在左侧面板中列出,请确保你在设备上信任该计算机,通过连接设备到 Mac 后出现的提示进行确认。随后,你可以在 iOS 设备上启用开发者模式。
在正确设置好你的 Mac 和 iOS 设备后,现在让我们继续了解如何将你的 AR 场景部署到 iOS 设备上。每次你想将你的 AR 场景部署到 iOS 设备上时,请按照以下步骤操作:
-
使用 USB 线将你的 iOS 设备连接到你的 Mac。
-
在你的 Unity 项目中,导航到文件 | 构建设置,从平台选项中选择iOS,然后点击切换平台按钮。
-
在 iOS 的构建设置中检查开发构建选项。这使你能够将应用用于测试目的部署到 iOS 设备。这一步对于避免每年 Apple 开发者账户的订阅费用至关重要。
注意
使用免费 Apple 开发者账户将应用部署到 iOS 设备有一定的限制。你一次只能部署最多三个应用到你的设备,并且由于免费配置文件到期,它们需要每 7 天重新部署。出于工业或学术目的,我们建议在彻底使用开发构建功能测试后订阅付费开发者账户。
-
保持处于
com.company_name.application_name。 -
返回到构建并选择它。
-
Xcode会打开并显示构建,由于需要签名证书而显示错误消息。要创建此证书,请点击错误消息,导航到签名和功能选项卡,并选择复选框。在团队下拉菜单中,选择新建团队,创建一个仅由你自己组成的团队。现在,从下拉菜单中选择这个新创建的团队。确保捆绑标识符字段中的信息与在编辑 | 项目设置 | 玩家中找到的 Unity 项目相匹配。
-
在Xcode中,点击任何 iOS 设备菜单,并选择你的特定 iOS 设备作为输出。
-
在Xcode的左上角点击播放按钮,等待显示构建成功的消息。现在,你的 AR 应用应该已经在你的 iOS 设备上了。然而,你将无法打开它,直到你信任开发者(在这种情况下,即你自己)。在你的 iOS 设备上导航到设置 | 通用 | VPN 与设备管理,点击你的Apple ID下的开发者应用证书,然后点击信任(你的 Apple ID)**。
-
在你的 iOS 设备主屏幕上,点击你的 AR 应用的图标。授予必要的权限,例如相机访问权限。恭喜你,你已经成功将你的 AR 应用部署到你的 iOS 设备上!
你现在已经知道了如何将你的 AR 体验部署到 Android 和 iOS 设备上。
在继续创建交互式 XR 体验之前,让我们回顾一下本章到目前为止所学的内容。
摘要
在本章中,我们深入探讨了围绕 AR 眼镜的复杂性和微妙之处,探讨了为什么这些设备在得到公众广泛接受之前面临许多物理和技术挑战。我们检查了在你的 AR 应用中基于标记和无标记方法之间的关键选择,并讨论了这一看似简单的决策如何显著影响你的应用程序的开发旅程,以及其可访问性、多功能性和用户参与度。
通过探索和安装 Unity 的 AR Foundation 包,你现在可以创建自己的简单 AR 体验,并准备好将它们部署到广泛的、兼容 AR 的手持移动设备上。
我们还发现,将 AR 场景部署到 iOS 设备上可能是一个复杂且耗时的工作,这主要归因于苹果生态系统相对于安卓生态系统的各种限制。然而,这些限制不应阻止你为你的 AR 应用追求跨平台的方法。通过旨在跨两个操作系统部署,你确保了更大的可访问性,并增加了触及更广泛受众的潜力。
通过通过 Unity 理解 AR 开发的各个方面,你正朝着创建真正引人入胜的 AR 体验迈进。在下一章中,你将学习如何使用 C#脚本和其他技术给你的 VR 应用程序添加复杂逻辑。
第五章:构建交互式 VR 体验
在本章中,我们深入到更复杂的 VR 应用领域,让您能够为各种用例创建沉浸式和交互式体验。您将学习如何使用强大的 Unity 引擎来创建无代码的交互式 VR 应用和 C#。
本章的美丽之处在于其实用性。您将获得实际操作技能,以构建一个反映我们自然世界响应性和真实性的 VR 环境。尽管一些 C#的背景知识可能有益,但这绝对不是先决条件。我们的教程旨在面向初学者,让任何对 XR 应用感兴趣的人都能舒适地跟随。
本章分为以下主题:
-
无代码构建交互式 VR 体验
-
使用 C#构建交互式 VR 体验
技术要求
在我们开始这段激动人心的旅程之前,让我们确保您满足完成本章所需的技术要求。除了安装最新的 Unity 版本外,您还需要根据您的 VR 设备是独立运行还是基于 PC 的 VR 模式,启用Windows/Linux/Mac或Android Build Support。如果您不确定您的 PC 或笔记本电脑是否满足 Unity 的硬件要求,请查看此页面:docs.unity3d.com/Manual/system-requirements.html。
无代码构建交互式 VR 体验
在探索了第三章中的演示场景后,让我们自己构建交互式 VR 体验,从虚拟车展开始。在我们将要构建的体验中,用户应该能够通过连续移动(使用摇杆行走)和传送(仅限于传送锚点)在地面周围走动。
为了开始我们的体验,请按照第三章中的“在 Unity 和 XR 交互工具包中设置 VR 项目”部分创建一个新的项目。如果您已经按照第三章中的步骤操作,您可以直接打开本章的现有项目并按照以下步骤进行。
一旦您的项目加载完成,首先创建一个新的空场景。这可以通过导航到CarExhibition来完成。
通过双击它,您现在已进入新创建的场景,该场景仅包含一个主相机和一个方向光。您可以删除主相机,因为它不是必需的。
在我们深入 VR 设置之前,我们必须首先为我们的交互设置舞台。在这种情况下,这意味着创建一个专门区域来容纳我们的两个汽车展览。为了简化,我们将从简单的立方体原形制作展览场地。通过在场景层次结构中右键单击并选择20, 0.1, 20)来实现。现在,将立方体重命名为ground。这将形成我们汽车展览的基础。
下一个部分详细说明了如何从 Asset Store 导入汽车。
从 Asset Store 导入汽车
在我们的场景中动画化汽车需要先导入它们。让我们一步步来导入 Unity Asset Store 中的simple cars pack:
-
前往 Unity Asset Store (
assetstore.unity.com/)。搜索simple cars pack,或者,为了更直接的方式,通过此链接访问包页面:assetstore.unity.com/packages/3d/vehicles/land/simple-cars-pack-97669。 -
在将包添加到你的资产后,找到在 Unity 中打开按钮并点击它。
-
此操作应提示 Unity 应用程序打开,并为你提供导入包的选项。请继续进行导入操作。
-
导入成功后,前往项目窗口中包的目录。你正在寻找的路径是Assets | Simple Vehicle Pack | Prefabs。
-
将出租车放置在坐标(
-6,0,0)处,并调整其缩放到(2,2,2)。
有时,你可能会在物体上遇到一种奇特的洋红色调。这通常意味着相关的材料缺失或不兼容当前的渲染管线。为了解决这个问题,请按照以下步骤操作:
-
URP 安装:在继续之前,请确保你已经安装了 URP,因为它默认不包括在 VR 模板项目中。如果没有安装,请转到窗口 | 包管理器。然后,搜索 URP 并安装它。
-
打开
Assets|Simple Vehicle Pack|Materials|Cars_1。 -
在选择
Cars_1材质后,在检查器窗口的着色器下拉菜单中选择URP | Lit。 -
然后,点击
cars_albedo旁边的较小圆环符号到cars_metallic,再到金属贴图,以及将cars_AO到遮挡贴图。这应该恢复汽车的正常外观。
-
对于
Bus_1、Bus_2和Cars_2材料,重复此过程,确保相应的bus_albedo、bus_albedo_2、bus_metallic、bus_AO和cars_albedo_2纹理分配到相关贴图。
注意
你可能已经注意到,手动调整可能相当耗时。幸运的是,Unity 为这种场景提供了一个更简化的解决方案。渲染管线转换器旨在处理大量资产和着色器的批量转换为 URP 格式。以下是使用方法:
-
前往窗口 | 渲染 | 渲染管线转换器。
-
在打开的窗口中,选择您想要转换的材质或着色器。
-
点击转换。工具将尝试自动调整您选择的材质或着色器以与 URP 兼容。
请记住,虽然这对于批量操作来说很方便,但您可能仍然需要验证每个材质,以确保其正确转换。
完成此任务后,请回到Assets | Simple Vehicle Pack | Prefabs,并发挥您的创造力,将所有车辆资产放入我们的场景中。请注意,除了出租车外,我们特别感兴趣的是位于(6,0,0)的Police_car。
现在我们已经将汽车运送到场景中,我们准备在下一节添加玩家和按钮预制体。
将玩家、传送锚点和按钮添加到场景中
在我们将游戏逻辑实现到 VR 体验之前,我们必须首先向场景中添加一些额外的 GameObject 和预制体,它们的功能与汽车本身一样重要。让我们从添加玩家开始。
添加玩家
让我们想象我们的场景就像一个舞台,而我们自己是导演。在我们的工具箱中,我们有这个可爱的 XR 交互设置预制体,这是一种我们可以在虚拟舞台上进行动画的木偶。我们强烈建议您按照第三章中的[安装 XR 交互工具包和示例]部分,使用建议的 XR 交互工具包版本2.5.1。虽然工具包会持续更新,但新版本可能包含不同的预制体。让我们按照以下步骤添加和配置此预制体:
-
XR 交互设置预制体很容易找到;它位于
Assets|Samples|XR Interaction Toolkit文件夹中。搜索您拥有的版本,可能是建议的2.5.1,或者可能是更新的版本。然后,在起始资产中查找预制体。 -
获取
Prefabs文件夹,并将其直接拖放到场景中。根据需要调整,使其正好位于中心,坐标为(0,0,0)。
成功地将玩家集成到我们的场景中。现在,让我们通过在环境中的各个兴趣点设置传送锚点来增强体验。
设置两个传送锚点
对于刚开始接触 VR 的用户来说,防止运动病的一个好方法是将移动限制在传送。XR 交互工具包为我们提供了三个传送预制体选项:传送锚点、吸附传送锚点和传送区域。将吸附传送锚点想象成我们舞台上的一个特定点,传送射线会吸附到这个点上。相比之下,使用传送锚点时,传送射线会滑动而不会吸附。然而,这两个锚点本质上都服务于相同的目的:它们是用户可以传送的指定地点。另一方面,传送区域是广阔的区域,允许用户在其边界内进行传送。
对于这个特定的场景,我们将使用两个吸附传送锚点来确保用户只能传送到特定位置。以下是设置它们的方法:
-
在我们的项目窗口中,导航到
资产|示例|XR 交互工具包|2.5.1|起始资产|演示场景资产|预制体|传送。在这个位置,你会遇到刚才描述的传送 锚点、吸附传送锚点和传送区域。 -
将吸附传送锚点从“传送”文件夹中拖出,并将其放入“Taxi 传送锚点”。将其放置在坐标(
-2,0,0),并调整其大小为(2,1,2)。 -
将另一个吸附传送锚点拖放到“Police_car 传送锚点”中。将其放置在(
2,0,0),并调整其大小与之前的锚点相同:(2,1,2)。
一旦设置好,你的场景应该看起来像图 5.1.*所展示的那样。

图 5.1 – 出租车和警车及其传送锚点
接下来,我们将通过在Taxi 传送锚点上直接添加一个按钮来增强Taxi 传送锚点。
添加出租车动画的按钮
为了使出租车动画的按钮突出并易于访问,我们将将其放置在一个使用圆柱体创建的底座上。这个圆柱体将作为按钮的专用支架:
-
要创建这个底座,在“出租车按钮支架”上右键点击。调整其大小为尺寸(
0.2,0.5,0.2),并将其放置在(-2.7,0.55,0)的位置。 -
要找到
资产|示例|XR 交互工具包|2.5.1|起始资产|演示场景资产|预制体|交互式对象。一旦找到,将其拖放到5,5,5)的“出租车按钮支架”上,并调整其 y 坐标到1.075,使其正确地放置在底座上。
参考图 5.1.2*,确保新添加的按钮使场景看起来符合预期。在下一节中,我们将专注于设置用于警车动画的文本按钮。

图 5.2 – 我们刚刚添加到场景中的出租车按钮支架
为警车动画添加文本按钮
对于我们的警车,我们将创建一个包含两个按钮的画布,使用户能够缩小或放大警车。
设置画布
-
首先创建一个画布:在层次结构中右键单击并选择XR | UI Canvas。
-
调整其尺寸。我们用于此目的的正确尺寸是(
0.001,0.001,0),使其成为一个正方形。这种缩放对于在 VR 环境中的最佳观看至关重要。 -
将画布定位在坐标(
3,1,-1)并绕玩家方向旋转(0,90,0)。 -
如果你遇到困难,无法更改 UI Canvas 属性,请转到画布组件的检查器窗口。在这里,将Render Mode从Screen Space – Overlay更改为World Space。
调整画布组件
-
在场景层次结构中选择画布,打开检查器窗口。单击添加组件以将新组件附加到画布上。
-
首先,添加一个
5。 -
将Child Alignment选择为Middle Center。
-
对于宽度和高度都检查Child Force Expand。
-
为了视觉效果,向画布添加一个Image组件。在Image组件的设置中,将源图像设置为UISprite,并选择一个与场景相协调的背景颜色。
添加按钮
-
导航到
Assets|Samples|XR Interaction Toolkit2.5.1|Starter Assets|Prefabs|DemoSceneAssets|Prefabs|UI。在这里,你应该找到TextButton预制体。 -
将此预制体拖放到画布上两次。这将自动在画布下方放置两个TextButton预制体作为子对象。由于Vertical Layout Group,它们将整齐对齐。
-
将它们缩放到(
0.4,0.4,0),并将第一个按钮重命名为Scale Big Button,第二个按钮重命名为Scale Small Button。
标记按钮
通过展开两次修改每个按钮的子文本对象。选择Text GameObject 后,转到检查器窗口并搜索文本组件。将一个按钮标记为Scale Big,另一个标记为Scale Small。
通过遵循这些步骤,你将有一个整齐组织的 UI,准备好你的警车动画,如图图 5.3所示。

图 5.3 – 警车动画的文本按钮
现在我们已经布置好舞台,准备表演,应该看起来像图 5.4。

图 5.4 – CarExhibition 场景的当前状态
接下来,我们将了解提线木偶,或者说,在 Unity 中我们可以操作的按钮事件。
可交互事件
可交互事件,尤其是在XR Simple Interactable组件中找到的事件,在增强用户体验方面发挥着关键作用。这些事件通常与推按钮相关联,在 VR 环境中促进多样化的交互。有众多不同的可交互事件选项。想象你在一个虚拟现实汽车展览中,你可以与每辆车旁边的推按钮进行交互。以下是如何将这些事件应用于此场景的示例:
-
First Hover Entered: 你第一次接近一辆车并指向其信息按钮。此事件触发按钮周围微妙的发光,表明它已被选中。
-
Hover Entered: 每次你指向按钮时,事件会更新光泽,显示按钮目前是您注意力的焦点。
-
Hover Exited: 当你的手或指针从按钮移开时,光泽消散,表明按钮不再被选中。
-
Last Hover Exited: 最后一次你从按钮移开时,光泽消散,按钮似乎微妙地回到了原始位置,表明它不再在焦点上。
-
First Select Entered: 第一次你按下信息按钮时,此事件被触发。它可能会使汽车的信息面板以平滑的动画出现。
-
Select Entered: 每次你按下按钮,无论是否是第一次按下,汽车的信息面板都会出现。
-
Select Exited: 当你释放按钮时,面板开始淡出,表明交互结束。
-
Last Select Exited: 最后一次你释放按钮时,面板不仅淡出,还似乎缩回到按钮中,标志着交互的结束。
-
Activated: 此事件可能与汽车上的一个按钮相关联,该按钮可以启动引擎。按下后,你会听到汽车引擎轰鸣着启动。
-
Deactivated: 当你按下按钮关闭汽车的引擎时,此事件被触发。你会听到引擎逐渐减速至停止。
这一系列事件为用户提供了一种自然直观的交互流程,增强了 VR 汽车展览的沉浸感。
在下一节中,我们将深入探讨如何编排这些交互并使动画生动起来,而无需编写任何代码。
理解动画和动画师系统
Unity 的动画系统通过控制 GameObject 的运动、旋转、大小、颜色等来操纵 GameObject,就像一个机制。它通过定义关键帧(特定时间点的特定状态)来工作,并从这些关键帧中构建动画剪辑。
考虑虚拟门的例子。一个动画剪辑可以展示门从关闭到打开的运动,另一个剪辑可以描绘门返回到关闭位置。
为了确保这些剪辑之间的平滑过渡,使用 Unity 的动画控制器。这是一个控制系统,它指导动画剪辑的时间安排和顺序,根据特定条件在它们之间进行切换。
对于门示例,动画控制器将管理开门、关门以及在这些状态之间切换的剪辑,可能基于用户输入在正确的时间进行。
这里是使用 Unity 的动画系统可以制作的其它示例:
-
对象移动:对于在屏幕上移动的对象,动画系统可以创建移动,但可能需要额外的脚本根据用户交互来控制它。
-
对象旋转:可以动画化一个持续旋转的齿轮,但玩家控制的旋转则需要代码。
-
对象缩放:缩放动画可以描绘对象的生长,但将其与其他因素(如能量水平)关联起来则需要编写脚本。
-
颜色变化:可以为变化的光颜色制作动画,但与游戏条件同步则需要编码。
-
摄像机移动:可以使用关键帧在角色之间创建摄像机移动,但与玩家移动的复杂交互可能需要额外的代码。
-
混合形状:可以使用混合形状来控制面部表情,但可能需要编写脚本来使其与特定的游戏对话相匹配。
-
UI 动画:可以动画化图形 UI 元素,如闪烁的按钮,但当满足某些条件(例如,比赛开始)时停止动画则需要脚本。
如这些示例所示,Unity 中的动画系统为使对象和场景生动提供了强大的工具。然而,向这些动画添加脚本或编码可以解锁更高层次的精炼和交互性。
通常,编码使我们能够在 Unity 中创建可以响应各种输入和游戏状态的动画,使它们更加动态。编码还提供了对动画的精确控制,允许实现仅使用 Unity 的动画系统无法实现的复杂逻辑和定制交互。
虽然 Unity 的动画系统可能没有编码提供的相同复杂性和精细控制,但它仍然在 Unity 内创建交互的主要工具中占据着重要的位置。直观的视觉界面和直观的控制允许快速且用户友好的方式来动画化 GameObject,即使不深入脚本。这使得它既适合新手也适合经验丰富的开发者,使他们能够为游戏场景添加生命和动作。
在本章的下一节中,我们只将使用动画系统,展示它单独使用时的强大和实用性。通过实际示例,您将看到如何在不依赖编码的情况下实现引人入胜和交互式的动画,以及这个工具如何成为您 XR 开发工具包的重要组成部分。
动画 360 度汽车旋转。
让我们深入动画的世界。想象一个旋转的陀螺:它一圈又一圈地旋转,当我们按下按钮时,我们希望我们的出租车也能这样做。转折在于,当我们松开按钮时,出租车应该停止旋转。听起来很有趣吗?我们将如何利用 Unity 动画系统和 UnityEvents 的魔力来实现这一点,而无需编写一行代码。
首先,我们需要为我们的出租车编排这个旋转。想象它就像一个旋转,在出租车 y 轴上的 360 度旋转。按照以下步骤将这个舞蹈变成现实:
-
在
Assets文件夹中右键单击并选择Create | Folder。 -
在你的场景中选择出租车对象,转到
RotateCar,并将其保存在我们新创建的Animations文件夹中。 -
通过选择Transform | Rotation并修改你的关键帧,为 y 轴定义 360 度旋转,如图 5.5所示。

图 5.5 – 定义 y 轴 360 度旋转的修改后的关键帧
在0:00处设置初始关键帧,旋转为0;这是我们的出租车起始姿势。然后,跳到0:10并给予355度的旋转。为什么不旋转 360 度?那就像转动一枚硬币,对我们温柔的旋转来说太突然了。
-
在项目窗口中单击
RotateCar动画剪辑以在检查器中查看其设置。在检查器中,勾选Loop Time框,让我们的出租车持续重复其旋转。 -
将
RotateCar动画剪辑附加到Animator组件的Controller字段。
这将使我们的出租车旋转在我们进入虚拟世界时立即开始。但记住,我们希望旋转只在按下按钮时开始。是时候让它发生:
-
首先,我们需要打开 Animator Controller。选择我们的出租车Animator Controller,双击以打开 Animator Controller 窗口。
-
就像一张空白画布,在
Idle上右键单击;这是出租车旋转风暴前的平静。 -
接下来,在
Idle状态上右键单击,将其设置为Layer Default State。这告诉 Animator Controller 从该状态开始,当场景开始时什么都不做。 -
然后,我们从
Idle状态到RotateCar状态建立一座桥梁:这个状态启动我们的出租车旋转。为此,在Idle上右键单击,选择RotateCar。 -
现在,让我们导航到
Rotate。这个参数将启动从Idle状态到RotateCar状态的过渡。 -
单击表示从
Idle到RotateCar过渡的箭头。在刚刚创建的Rotate参数中,如图 5.6所示。

图 5.6 – 显示新添加条件的检查器窗口:旋转触发器
-
接下来,我们需要在按钮释放时停止出租车的旋转。在
RotateCar状态上右键单击,选择Idle状态。 -
返回到
StopRotation。这将启动从RotateCar状态回到Idle状态的过渡。现在,你的参数应该与图 5.7中显示的相匹配。

图 5.7 – 动画器窗口的参数选项卡,显示了新添加的参数
- 点击从
RotateCar到Idle状态的转换箭头。在StopRotation参数下,就像我们之前对Rotate参数所做的那样。现在,你的Animator窗口应该类似于图 5.8。

图 5.8 – 显示当前状态及其转换的动画器窗口
- 选择
Animator.SetTrigger()。将其视为我们的出租车开始或停止舞蹈的提示。当按钮被按下时(Rotate),当按钮被释放时(StopRotation)。如果设置正确,你的事件将反映在图 5.9中。

图 5.9 – 选择进入和选择兴奋事件
干得好!你的出租车现在可以随着按钮的节奏跳舞了,每次按下按钮都会旋转一整圈。别忘了试试:用力按下按钮,看看出租车如何完成 360 度的旋转。
在下一节中,我们将深入了解画布上 2D 文本按钮的魔法,学习它们如何通过按按钮来改变警车的大小,使其缩小或放大。
缩放警车
想象一下在我们的 VR 汽车展览中加入两个额外交互功能的迷人可能性:一个按钮可以缩小汽车,另一个按钮可以放大它。类似于我们之前的交互,我们将使用一系列程序,但这次是在画布上的 2D 按钮上。首先,我们创建两个动画剪辑,捕捉汽车缩放上下时的本质变化。接下来,我们创建一个动画控制器:这是一个关键组件,用于定义和管理动画状态。最后,我们将相应的触发事件分配给按钮。
让我们按照以下步骤将这个魔法变为现实:
-
在层次结构中选择警车。打开动画窗口(
ScaleCar)并将其存储在Animations文件夹中。 -
现在,让我们编排这个变换。在动画窗口的时间轴上,用关键帧(菱形图标)标记开始(
0:00)和结束(1:00)。开始时,汽车的缩放比例(0)。结束时,缩放比例应该是最大尺寸;让我们使用3。这样我们就得到了一个动画,展示了汽车从微小到巨大的缩放过程。 -
我们不希望我们的汽车持续地缩小和放大。所以,在检查器中取消选择Loop Time框。
-
我们的警车需要一个
ScaleCar动画剪辑放入Animator Component的Controller字段中。 -
我们已经掌握了增长的部分,现在让我们来处理缩小部分。创建一个名为
ShrinkCar的第二个动画片段。 -
与步骤 2类似,用关键帧标记开始和结束。这次,在开始时,汽车的缩放比例应该是其最大尺寸(
3)。在结束时,缩放比例应该是其最小尺寸(0)。我们现在已经反转了变形,创建了一个从巨大到微小缩小的动画。
到目前为止,我们已经成功创建了两个动画片段和一个动画控制器。如果我们播放场景,由于未勾选“未检查循环”复选框以及我们的动画控制器中没有缩小动画,警车会因循环而放大一次。我们离我们的变形车又近了一步。准备好下一部分了吗?让我们深入探讨。
现在,是我们让我们的警车按照我们的曲调跳舞的时候了。我们希望它在需要时改变大小,在我们不需要时处于空闲状态。这就是动画控制器发挥作用的地方。它是我们的指挥家,决定汽车何时增长、缩小或休息。以下是我们将它实现的方法:
-
首先,我们需要打开动画控制器。在项目窗口中找到分配给警车的动画控制器,并双击打开它。
-
记得我们的缩小舞蹈吗?将
ShrinkCar动画片段拖放到动画控制器窗口中。它现在既有增长也有缩小的程序。 -
现在,我们需要一个休息状态,在舞蹈序列之间的喘息。在
Idle上右键单击。就像暴风雨前的平静。 -
我们不希望汽车在帷幕升起时立即开始跳舞。因此,将
Idle状态设置为默认状态。这确保了当场景开始时,我们的汽车静止不动,等待其提示。 -
我们的指挥家已经准备好指挥了。在
Idle状态上右键单击,选择ScaleCar,然后再次选择ShrinkCar状态。现在,我们已经为我们的汽车从静止不动过渡到变大和变小做好了准备。 -
但是,是什么触发了过渡?我们需要为此设置触发参数。在
ScaleBig和ScaleSmall中。 -
选择过渡箭头。在
ScaleBig中触发从Idle到ScaleCar的过渡,而ScaleSmall触发从Idle到ShrinkCar的过渡。舞蹈永远不会是单向的。我们的汽车需要从增长到缩小,反之亦然,平滑地移动。因此,从
ShrinkCar到ScaleCar创建过渡,为下方的过渡箭头设置ScaleBig触发器,为上方的过渡箭头设置ScaleSmall触发器,如图图 5.10所示。

图 5.10 – 警车的动画控制器
哇!我们的警车现在可以按照我们的指令旋转了。尝试这个场景,并观察它如何在你意愿下优雅地放大和缩小,方法是将场景测试或部署到你的 VR 头盔上,如第三章中“将 VR 体验部署和测试到不同的 VR 平台或模拟器”部分所述。这不是一件令人愉快的事情吗?
使用 C#构建交互式 VR 体验
到目前为止,我们只是通过使用 Unity 的动画系统,没有写一行代码,就为我们的场景添加了交互。在接下来的章节中,你将学习如何使用 C#脚本为你的 GameObject 和场景添加更复杂的交互。
我们将要回答的第一个问题是:我们何时需要为动画和交互编写 C#代码?
理解何时使用 C#进行动画和交互
理解 Unity 的动画和动画师系统以及 C#脚本的使用不是相互排斥的非常重要。它们经常一起使用,其中动画师控制预定义的动画,而 C#根据用户输入或其他游戏事件添加交互性。
在上一节中,我们使用 Unity 的动画和动画师系统旋转和缩放了汽车。这些系统主要用于创建预定义的动画。我们可以将这个过程分为以下三个步骤:
-
初始化事件:首先,必须发生一个事件来启动动画。这可以是一个按钮按下、游戏事件、碰撞或其他触发器。在我们的例子中,为了缩放和旋转汽车,我们使用了一个物理按钮和一个 2D UI 按钮。Unity 内置的动画和动画师系统主要是围绕预定义的动画在特定条件下触发的理念设计的。这些条件通常在 Animator Controller 本身中定义,并且通常基于你事先设置的参数,例如一个布尔值来跟踪角色是否在跳跃,或者当按钮被按下时激活的触发器。这意味着,使用内置系统,我们没有能力根据游戏中的任何事件或条件触发动画,而必须与可用的事件一起工作。
-
动画:使用 Unity 的动画系统,我们通过创建关键帧来定义动画期间发生的变化(位置、旋转、缩放等)。例如,我们使用关键帧改变了汽车的旋转和缩放。
-
将
ShrinkCar状态转换为ScaleCar状态。
这个系统非常适合创建预定义的动画,这些动画在特定条件下发生;例如,角色动画(行走、跑步、跳跃)或环境动画(门打开、电梯移动)。
虽然 Unity 的内置系统在预定义动画方面表现出色,但当动画需要动态响应用户输入或其他游戏事件时,C#就派上用场。在这里,我们遵循与之前类似的步骤:
-
初始化事件:启动动画的事件可以是任何东西,例如按钮点击、用户输入或游戏状态的变化。与 Unity 内置系统最大的不同之处在于,使用 C#脚本,你对动画的初始化事件有更大的灵活性和控制力。例如,你可以响应复杂的输入序列,如格斗游戏动作连招。你可以基于游戏逻辑或游戏状态来创建动画,例如敌人的健康水平或玩家的当前得分。你可以根据碰撞、进入/退出特定区域或其他物理事件来触发动画。
-
AI 决策:你可以根据 AI 系统做出的决策来启动动画。在多人游戏中,你可以根据网络事件(如其他玩家的动作)触发动画。
-
动画:动画可以通过两种方式创建:
-
你可以使用动画系统创建关键帧,就像之前一样,然后使用 C#来控制这些动画的播放(例如,播放、暂停、停止或改变速度)。
-
或者,你可以使用 C#直接修改 GameObject 的属性,以编程方式创建动画。
-
-
状态控制:使用 C#,你可以更直接地控制动画和过渡何时以及如何发生。你可以根据游戏状态的任何方面创建条件,而不仅仅是动画控制器中的参数。例如,你可以根据玩家的健康或库存更改 NPC 的动画。
当动画需要以复杂的方式对游戏状态或用户输入做出响应时,使用 C#进行动画是理想的。这在以下场景中尤其如此:
-
实时用户输入:你通常使用 C#来根据实时用户输入动画 GameObject。例如,在飞行模拟器中,你可能根据玩家的操纵杆输入来动画化飞机的控制面(如副翼、升降舵和方向舵)。由于这些表面的确切位置取决于玩家的输入,这不是可以通过关键帧预先确定的事情。
-
基于物理的动画:如果你的动画需要包含或响应物理效果,通常通过编程方式动画化是合理的。例如,在台球游戏中,球体的移动和旋转是基于物理计算而不是预定义路径。
-
程序生成内容:当你的游戏内容是程序生成时,通常需要通过编程方式动画化事物,因为动画的确切性质无法预先确定。例如,在类似《暗黑破坏神》的地下城探险游戏中,地下城的布局和敌人的位置是即时生成的,因此与这些元素相关的任何动画也必须在运行时生成。
-
复杂 AI 行为:在创建复杂 AI 行为时,你可能使用 C#来根据 AI 的决策过程来动画化 GameObject。例如,一个敌人角色可能有一个空闲动画、一个行走动画和一个攻击动画,你可以使用 C#来决定根据 AI 的当前状态和玩家的位置播放哪一个。
现在我们已经了解了在哪些场景下使用 C#进行动画和交互是有用的,让我们在下一节通过使用滑块缩放汽车来应用我们的新知识。这属于“实时用户输入”类别。当我们想使用滑块缩放汽车时,是用户输入(移动滑块)在驱动动画(汽车的缩放)。这种交互不能通过关键帧预先定义,因为汽车的精确缩放取决于玩家在任何给定时刻的输入。但在我们将这些添加到场景之前,我们首先需要了解 C#语言的基础知识,这些知识将在下一节中解释。
在 Unity 中使用 C#进行脚本编写理解
在 Unity 中进行 VR 开发的脚本创建涉及使用 C#。作为一种高级语言,它简化了许多计算复杂性,与 C++等语言相比,它更加用户友好。
通过其强大且静态的类型系统,C#可以帮助你在 Unity 中运行游戏之前发现编程错误,这对开发者来说非常有帮助。此外,它擅长管理内存使用,因为它最小化了内存泄漏的风险——一种游戏消耗越来越多的内存,可能引起崩溃的情况。
C#由微软支持,这确保了你能够获得可靠的帮助、大量的工具以及访问一个庞大的开发者社区。而且,重要的是,就像 Unity 一样,C#支持多个平台。
当在 Unity 中使用 C#时,你的编码主要是基于事件的。这意味着你覆盖了某些在特定时间被触发的 Unity 函数,例如游戏的Start()或Update()函数。
现在,当谈到在 Unity 中使用 C#进行 VR 开发时,有三个关键的对象导向编程概念你需要理解:变量、函数和类。让我们更深入地了解这些概念。
变量
变量就像是你的脚本用来存储数据的存储盒。每个变量都有一个类型,它告诉你它可以存储什么类型的数据。例如,如果你正在使用 XR 交互工具包,你可能会有变量来存储诸如 VR 控制器位置、虚拟世界中的对象状态等数据。让我们看看以下代码片段中我们如何使用变量在 Unity 的 C#脚本中的例子:
public class XRGrab : MonoBehaviour
{
public XRGrabInteractable grabInteractable;
private bool isGrabbed = false;
}
在前面的代码中,grabInteractable是一个XRGrabInteractable对象,它代表了一个可以与之交互的 VR 对象。isGrabbed是一个私有的布尔变量,用于跟踪对象是否当前被抓住。
函数
将 C#中的函数(或方法)想象成烹饪食谱。就像食谱提供一步步的指导来烹饪一道特定的菜肴一样,C#中的函数由一组执行特定任务的指令组成。你可以多次重用这些食谱,无论是在同一脚本中还是在不同的脚本中。
在 Unity 中,有一些特殊函数,如独特的烹饪食谱,在脚本的生命周期中的特定时间被触发。以下是它们的概述:
-
Awake(): 这就像是你脚本的闹钟。当脚本首次唤醒(或加载)时,这个函数会响起。通常,它用于设置变量或游戏的状态。 -
Start(): 这就像是在起跑线上准备起跑的运动员。在游戏的第一帧显示之前,这个函数会被调用。它也用于设置事物,但与Awake()不同,如果脚本未启用,则不会运行。 -
Update(): 这个函数是游戏的心脏,每帧跳动一次。它通常用于需要定期执行的任务,例如移动对象、检查用户输入等。 -
FixedUpdate(): 这就像Update(),但它以恒定的速度运行,不受帧率的影响。它通常用于与物理相关的任务。 -
LateUpdate(): 这是一个在其他人之后整理的函数。它在所有Update()函数执行完毕后运行,执行所有其他任务。 -
OnEnable(): 这是一个特殊的 Unity 方法,当脚本附加的对象在游戏中变为活动状态时会被调用。
现在,当涉及到 VR 交互时,Unity 的 XR 交互工具包提供了一组自己的特殊函数,这些函数会对 VR 动作做出反应。以下是一些你想要了解的重要函数:
-
OnSelectEntered(): 当你在 VR 中选择一个可交互对象时,会调用这个函数。想象一下,当你用 VR 控制器指向一个虚拟对象的那一刻。 -
OnSelectExited(): 这个函数是在你停止选择一个可交互对象的那一刻。想象一下,就像是你放开了你指向的对象。 -
OnActivate(): 这是在你激活一个可交互对象时发生的。这有点像在你已经拿着对象的同时按下按钮。 -
OnDeactivate(): 这是在你停用对象时发生的。这就像是你放开了你刚刚按下的按钮。 -
OnHoverEntered(): 当你开始悬停在可交互对象上时,会调用这个函数。这可以用来使对象发光,例如。 -
OnHoverExited(): 这个函数是在你停止悬停在某个对象上时触发的。
这些函数可以通过不同的方式组合起来,以在虚拟世界中创建各种交互。这就像堆叠积木来创建更复杂的东西。
类
使用MonoBehaviour、ScriptableObject或其他类来展示 C#中类的特性。让我们通过一个名为XRGrab的示例类来了解,它继承自基类MonoBehaviour。这个类的第一部分包括以下内容:
public class XRGrab : MonoBehaviour
{
public XRGrabInteractable grabInteractable;
private bool isGrabbed = false;
在前面的例子中,XRGrab类包含两个字段。public XRGrabInteractable grabInteractable是对XRGrabInteractable对象的引用。这个脚本通常附加到你想要在 VR 或 AR 环境中使其可交互的 GameObject 上;例如,用户应该能够抓取的对象。isGrabbed是一个布尔变量,用于跟踪可交互对象是否当前被抓取。
我们类的下一部分是方法。我们类中的第一个方法是OnEnable():
void OnEnable()
{
grabInteractable.onSelectEntered
.AddListener(Grabbed);
grabInteractable.onSelectExited
.AddListener(Released);
}
OnEnable()方法将Grabbed()和Released()方法作为监听器添加到grabInteractable对象的onSelectEntered和onSelectExited事件。这意味着当用户通过选择在 VR/AR 世界中与对象交互时,将调用Grabbed()方法,而当用户停止与它交互并取消选择时,将调用Released()方法。
让我们看看这两个方法可能的样子:
-
下面是
Grabbed()方法:void Grabbed(SelectEnterEventArgs args){isGrabbed = true;}Grabbed()方法将isGrabbed设置为 true,表示对象已被抓取。 -
下面是
Released()方法:void Released(SelectExitEventArgs args){isGrabbed = false;}}Released()方法将isGrabbed设置为 false,表示对象已被释放。
正如你所见,在 Unity 中使用 C#进行脚本编写涉及定义变量来存储数据,实现函数来操作这些数据或实现游戏玩法,并将这些变量和函数组织成代表游戏中对象或概念的类。然后 Unity 引擎使用这些脚本来驱动场景中 GameObject 的行为。
在 C#的领域里,类名通常遵循PascalCase约定,即每个单词以大写字母开头,且没有下划线。你可以自由选择任何你喜欢的名字,只要它符合 C#的一般命名约定。以下是命名指南:
-
名称应该以大写字母开头,而不是下划线或数字。
-
名称可以包含字母和数字,但不能包含下划线。
-
空格或特殊字符不应成为名称的一部分。
-
最后,名称不能是 C#中的保留词。例如,“class”、“int”、“void”等都是保留的,不能用作名称。这是因为它们在 C#中有特定的含义,作为其语法的一部分。编译器期望它们以特定的方式使用,因此将它们用作标识符会导致混淆并导致编译错误。
这就是 Unity 中用于 VR 开发的脚本编写的温和介绍。如果它听起来仍然有点复杂,请不要担心;就像任何语言一样,熟能生巧,这正是您将在下一节中要做的!
使用滑块和 C#缩放公交车
我们即将开始一项令人兴奋的任务:通过向公交车添加动态缩放功能来丰富我们的汽车展览体验。之前,我们使用固定动画来缩放警车。然而,这次,我们将根据用户与滑块的交互实时缩放公交车。
通过这些步骤,我们将实现我们的目标。所以,让我们开始吧:
-
首先,我们需要将公交车带入我们的场景。转到
Assets|Simple Vehicle Pack|Prefabs,将Bus_2拖放到场景中。将其定位在坐标(0,0,-6),y 轴上有一个-90度的旋转。 -
接下来,我们需要一个滑块和一个描述性文本,表明可以通过滑块调整公交车的大小。为了完成这个任务,我们首先需要创建一个画布。在层次结构中右键单击,选择
0.01,0.01,0),将其定位在(0,1.5,-5),并旋转到(0,180,0)。现在它面向玩家的方向。请注意,您必须设置Bus Scale Canvas以提高清晰度。在向画布添加 UI 元素之前,还缺少一件事情:垂直布局组组件。让我们在检查器中添加这个组件,并将子对齐属性更改为上居中。这确保了滑块和文本都将垂直对齐在画布的上居中位置。
-
接下来,我们可以添加滑块。在
0和5上右键单击,允许公交车在这两个值之间缩放。让我们将滑块重命名为Bus Scale Slider以区分。 -
为了增强用户体验,我们还将滑块上方放置一个文本。通过在
Bus Scale Slider上右键单击,选择BusScale Text来添加一个Slider游戏对象。
我们现在已经设置了滑块,它作为我们的初始化事件,如图 5**.11所示。

图 5.11 – 公交缩放滑块
在此之后,我们将通过单个 C#脚本将缩放动画和状态控制链接起来。想法是将滑块的值绑定到公交车的缩放。
在进行脚本编写之前,建议通过创建一个新的文件夹来保持组织:
-
在
Assets文件夹中右键单击,选择Scripts。 -
在这个新文件夹内,创建一个新的 C#脚本并将其重命名为
BusScaler。这个脚本将是我们将动态缩放变为现实的主要工具。 -
现在双击脚本。这将打开您计算机上安装的 IDE。这是我们将要开发的代码。
编写动画脚本
以下说明指导您了解BusScaler脚本的主要组件如何相互交互:
-
从以下两行代码开始,定义您的命名空间:
using UnityEngine;using UnityEngine.UI;任何 Unity 中的 C#脚本的第一步是使用
using关键字来包含命名空间。UnityEngine包含创建 Unity 游戏所需的所有类,而UnityEngine.UI包含创建和操作 UI 元素的类。 -
类声明接下来。在我们的脚本中,让我们声明一个新的类
BusScaler,以下代码序列:public class BusScaler : MonoBehaviour此类从
MonoBehaviour继承,它是所有 Unity 脚本的基础类。 -
接下来,声明
BusScaler类的变量,以下代码序列:public GameObject bus;public Slider slider;public关键字表示这些变量可以从其他脚本访问,也可以从 Unity 的bus变量中设置,它将在场景中持有公共汽车对象,而slider变量将在场景中持有滑块 UI 对象。 -
接下来,让我们重写
Awake()函数,在游戏开始之前设置初始设置和引用。这包括将公共汽车的初始比例在 x、y 和 z 轴上设置为1。我们使用以下代码片段来完成:private void Awake(){bus.transform.localScale = new Vector3(1f, 1f, 1f);} -
我们的最后一步是重写
Update()函数。输入或粘贴以下代码行:private void Update(){float scaleValue = slider.value;bus.transform.localScale = new Vector3(scaleValue, scaleValue, scaleValue);}此代码检索滑块的值(该值在 Unity 的 Inspector 中设置的滑块最小值和最大值之间),并将公共汽车在 x、y 和 z 轴上的比例设置为该值。这意味着如果滑块的值为
0.5,公共汽车将变为原来大小的一半。
测试我们的动画
现在我们已经完成了 C#脚本,只剩下几个步骤就可以完成测试我们的动画:
-
在我们的 C#脚本中,
BusScaler类从MonoBehaviour派生。为了使用此脚本,它需要在 Unity 编辑器中的 GameObject 中关联。为此,在层次结构中右键单击并选择BusScaler Controller。 -
接下来,你可以将你的脚本拖放到新 GameObject 的Inspector面板中。这个动作将把你的脚本附加为一个组件。
-
完成此操作后,你会在 Unity 编辑器中的脚本组件中注意到公共字段
bus和slider变得可见。这些字段需要填充实际的busGameObject 和此脚本将要与之交互的滑块对象。为此,只需将这些对象拖放到相应的字段中,如图图 5**.12所示。

图 5.12 – 将公共汽车缩放器脚本中的公共汽车和滑块对象放入相应字段的公共汽车缩放器控制器的 Inspector 窗口
-
在你可以测试你的交互式滑块之前,最后的步骤是在它前面放置一个传送锚点。这可以通过回到我们的工具箱,导航到
Assets|Samples|XRInteraction Toolkit来完成:-
在这里,你可以找到
BusTeleport Anchor。 -
将此锚点放置在坐标(
0,0,-2.5)处,并调整其大小为(2,1,2)。使用这种设置,用户现在可以传送到滑块前方的一个位置,使他们能够交互式地缩放公交车,如图 图 5.13 所示。
-

图 5.13 – 用户在 VR 中与滑块交互时公交车如何缩放
欢呼,你已经成功完成了制作此动画所需的所有步骤。现在,是时候再次探索你的交互式 VR 场景了。为此,请遵循第三章中“将 VR 体验部署和测试到不同的 VR 平台或模拟器”部分所描述的步骤。
摘要
在本章中,你学习了如何在 Unity 中为 VR 场景添加交互性,使用代码依赖和无代码方法。到目前为止,通过成功完成本章提供的步骤,你应该已经让你的 Unity 场景变得生动,并获得了对何时选择 Unity 的动画系统以及何时利用 C# 的力量来满足你的交互场景创建需求的理解和舒适度。
我们深入探讨了触发按钮事件和利用动画系统,从而为你提供了在 VR 场景中创建简单而有效的交互技能,而不必编写一行代码。对于更复杂的交互设计,你现在应该非常熟悉 Unity 中 C# 的基本功能,并且熟悉 XR Interaction Toolkit 提供的强大功能。
不论是工业应用还是学术项目,这些技能和技术应该能够让你利用 XR Interaction Toolkit 和其演示场景在 Unity 中创建沉浸式 VR 场景。你应该准备好将所学知识应用到你的独特用例中。
但我们的旅程并未结束。在接下来的章节中,我们将通过探索在 Unity 中创建交互式 AR 和 MR 体验来拓宽我们的视野。这将确保你能够全面地添加 XR 场景中的交互。让我们继续我们激动人心的探索,进入沉浸式技术的世界。
第六章:构建交互式 AR 体验
在第四章中掌握了在 Unity 中为 Android 和 iOS 平台制作和实现 AR 体验的基础知识后,我们现在将开始一段有趣的旅程,通过引人入胜的交互来增强您的 AR 场景。随着我们努力通过基于实用性的叠加来增强现实,这一章节将为您开启一个全新的用户体验世界。
利用 C#强大的功能,我们的冒险将转向创建一个针对食品行业的创新 AR 应用程序。这个应用程序将彻底改变客户选择的方式,提供一种前所未有的点餐方法。
在我们揭开这个 AR 应用程序的创建过程时,您将发现如何将 3D 模型锚定和缩放在现实世界中,促进用户与 AR 应用程序元素的交互,并理解在构建自己的 AR 应用程序时需要考虑的广泛原则。这次沉浸式的旅程将为您配备一套丰富的技能,提供对 AR 无限可能性的更深入理解。
本章节涵盖了以下主题:
-
理解交互式 AR 应用程序的设计模式和核心组件
-
构建我们的 AR 菜单应用程序的基础
-
为我们的 AR 菜单应用程序添加交互性
技术要求
要充分参与并从本章详细介绍的 AR 应用开发过程中受益,您的硬件必须满足以下技术要求。如果您跟随我们在第四章中构建的项目,您可以跳过这些要求,只要您的 Unity 设置没有改变。
为了确保您能够跟随本书中的内容和示例,请确认您的计算机系统可以处理Unity 2021.3 LTS 或更高版本,包括 Android 或 iOS 构建支持。
此外,随着我们深入探索 AR 的迷人世界,拥有一个可以支持ARKit或ARCore的 Android 或 iOS 设备将非常有帮助。您可以在developers.google.com/ar/devices检查您的设备兼容性。
然而,如果您没有符合这些要求的设备,您仍然可以参与这些教程,并在您的 PC 上测试您的应用程序。第四章中的将 AR 体验部署到移动设备部分详细说明了如何做到这一点。
理解交互式 AR 应用程序的设计模式和核心组件
在本节中,我们将深入研究 AR 常用的设计模式和应用程序,为您提供选择您 AR 应用程序适当用例的知识。这包括熟悉我们将在本章中构建的 AR 菜单应用程序的核心概念和基本组件。
在开始开发你的第一个完整 AR 应用之前,理解互动 AR 应用的正确应用至关重要。让我们来看看目前存在的各种 AR 应用类型,突出它们增强用户体验的不同方式。这不仅会给你一个关于当前 AR 应用状态的清晰图景,还会揭示哪些类型的 AR 体验最能引起用户的共鸣。
让我们来看看这些不同种类的应用:
-
增强现实游戏应用:例如《精灵宝可梦 GO》和《我的世界地球版》这样的游戏是 AR 应用的流行例子。它们将虚拟对象如生物或方块放置在用户的真实世界环境中。交互通常通过触摸屏命令完成,游戏会响应设备 GPS 提供的物理位置数据。
-
AR 导航应用:例如 Google Maps Live View 和 CityViewAR 这样的应用将方向提示和兴趣点叠加到现实世界的图像上。这些应用使用 GPS 数据和设备方向来决定显示哪些 AR 元素以及在哪里显示。这些元素可以包括箭头、标签,甚至建筑的 3D 模型。用户主要通过移动和环顾四周进行交互。一些应用还允许用户触摸屏幕元素以获取更多信息。
-
AR 购物应用:IKEA Place 和 Amazon AR View 允许用户在购买前在自己的家中可视化产品。这些应用访问用户的摄像头流,以便将产品的 3D 模型放置在他们的房间里。高级应用使用环境理解将对象放置在表面上并正确缩放。用户四处走动以从不同角度查看产品,并使用触摸命令选择不同的项目、更改颜色或功能,并完成购买。
-
AR 教育应用:例如 Star Walk 2 和 AR 解剖学习这样的应用旨在提供沉浸式、互动的学习体验。这些应用通常使用图像识别将如星系或人体器官的 3D 模型锚定到现实世界中的特定位置。用户可以通过触摸命令与 3D 模型交互,例如旋转模型或激活动画。用户还可以四处走动以从不同角度查看模型。
这些不同的 AR 应用可能针对不同的用户群体和行业,但它们有一个共同的模式:使用 AR 将 3D 模型投射到现实世界环境中。这些应用使用摄像头流、设备方向和 GPS 数据来定位和缩放 3D 模型。用户交互通过触摸命令或物理动作实现,交互通常集中在操纵 3D 模型的特定功能上。这种强调简单和专注的模式是当前 AR 应用开发的标准,也将成为我们本章讨论的交互式 AR 应用的蓝图。它也是我们推荐用于我们自己的 AR 项目的模式。
注意
记住,目标不是将 AR 功能强行嵌入到应用中,而是要在增强用户体验的地方使用它。例如,使用 AR 在桌子上显示餐厅菜单可能看起来很新颖,但并不一定能为用户提供价值。传统的 2D 应用或实体菜单也能达到同样的目的。然而,如果你创建一个 AR 体验,让用户能够可视化桌子上每一道菜,并按实际份量缩放,用户就能清楚地了解可以期待什么。这增强了用餐体验和整体满意度,展示了 AR 如何通过适当的应用创造有意义的和有益的交互。这正是我们在后续章节中将要创建的内容。
基于这种理解,让我们继续前进,构建我们 AR 菜单应用的基础。
构建我们 AR 菜单应用的基础
当我们开始制作这个 AR 菜单应用时,您将通过组装基本组件来为您的 AR 项目打下基础。以下章节将指导您通过 Unity Asset Store 获取和导入各种菜肴,并将 UI 按钮和文本元素添加到场景中,为您的交互式 AR 菜单应用提供基础。
定义我们 AR 应用的关键组件
在本章中,我们将构建一个 AR 应用,允许用户将他们的移动设备摄像头检测到的食物 3D 模型放置到现实世界的表面上。在我们进入项目之前,可视化我们即将创建的应用的功能总是很好的。我们的 AR 应用将包括几个关键组件:
-
AR 会话和 AR 会话原点:这些是任何 AR Foundation 应用的主要组件。它们构成了我们表演的舞台。为了深入了解 AR 会话原点和 AR 会话,您被邀请重新阅读第四章中的探索 AR 会话原点 GameObject和理解 AR 会话 GameObject部分。
-
AR 射线投射管理器和 AR 平面管理器:这些组件默认与 AR 会话原点一起提供。AR 射线投射管理器会对跟踪的 AR 特征和几何形状执行射线投射,例如检测到的平面。我们将使用它来找到我们可以在现实世界中放置 3D 模型的位置。另一方面,AR 平面管理器允许您检测和跟踪现实世界中的水平和垂直表面。
-
食物预制件:这些是用户可以在现实世界中放置的食物的 3D 模型。它们是用户将与之交互的有形对象。
-
UI 按钮和文本元素:这些 UI 元素用于指导用户了解应用的工作方式,切换当前食物预制件到下一个或上一个,以及显示每道菜的营养成分信息。将这些 UI 元素视为我们应用的交互元素,用户可以参与其中。
-
ARPlacePrefab 脚本:这是我们主要的脚本,负责管理 3D 模型和 UI 按钮在 AR 空间中的放置。它还处理放置对象的用户交互,并根据 AR 射线结果更新放置指示器。
-
SwapPrefab 脚本:此脚本与 ARPlacePrefab 脚本协同工作,当 UI 按钮被点击时,在不同的食物预制件之间切换。
-
Food,它使我们能够创建具有特定特征或属性(如名称、成分、卡路里和饮食类型)的Food对象。
通过实现这些组件,我们将拥有一个可工作的 AR 应用程序,允许用户使用智能手机代替传统的打印菜单,在他们的真实世界环境中放置、查看和交换不同的 3D 食物模型。为了确保用户理解在这个应用程序中他们应该做什么,将在应用程序的开始场景中添加专门的 UI 元素。通过使用如网格等视觉提示,将有助于用户找到放置菜肴的最佳位置。通过添加缩放功能,用户将能够调整显示菜肴的大小,以增强用户体验。
在下一节中,我们将设置我们的 AR 应用程序,以便我们更接近构建一个交互式 AR 应用程序。
设置环境
为了开始我们的旅程,让我们首先创建一个新的项目,正如在 第四章 中 使用 Unity 的 AR 模板创建 AR 项目 部分所解释的那样。如果您已经完成了这些步骤,您可以简单地打开本章的现有项目。在项目加载后,按照以下步骤逐步设置您的环境:
-
让我们通过创建一个新的空场景来启动这个过程。这可以通过转到
ARFoodMenu来实现。 -
快速双击将带您进入您新创建的场景,该场景目前仅包含 主相机 和 方向光。主相机 可以被移除,因为它将不再需要。
-
在深入到 AR 设置之前,为我们的 AR 应用程序打下基础是很重要的。在我们的情况下,这意味着要整合 AR Session Origin 和 AR Session。您可以通过在 场景层次 窗口中右键单击,选择 XR | AR Session Origin,然后为 AR Session 重复相同的步骤来完成此操作。
-
一旦
AR Plane Manager脚本加载,并选择它。为 AR Raycast Manager 脚本重复此过程。 -
在
ARPlane中拖动预制件到 Inspector 窗口中 AR Plane Manager 脚本组件的 Plane Prefab 单元格。由于我们只想检测用于我们的 AR 菜单应用程序的水平平面,因此将 Detection Mode 设置为 Horizontal。我们不需要为 AR Raycast Manager 分配任何预制件,因为我们只需要计算射线何时遇到表面的功能。
就这样!通过几点击,我们已经将AR 会话、AR 会话原点、AR 射线管理器和AR 平面管理器添加到了我们的场景中。我们的下一步是导入来自 Asset Store 的食品模型,这将展示我们打算向用户展示的餐点。
设计 3D 食品模型
作为一家餐厅的业主,您需要在这个阶段制作您餐点的 3D 模型。以下是一些您可以采用的策略来设计食品或菜肴的 3D 模型:
-
3D 建模软件:有许多 3D 建模软件工具可以帮助您创建 3D 模型。这些包括Blender、3ds Max、Autodesk Maya和SketchUp。在这些工具中,Blender是一个流行的选择,因为它免费且开源。有许多在线教程可以帮助初学者开始使用Blender,例如CGFastTrack的 YouTube 频道(
www.youtube.com/@CGFastTrack/featured)。 -
摄影测量法:摄影测量是一种技术,您需要从不同的角度拍摄多个物体的照片,然后使用软件将它们拼接成一个 3D 模型。像Luma Labs、Reality Capture、Meshroom和Agisoft Metashape这样的工具可以帮助您完成这项工作。对于食品模型,这可以产生非常逼真的效果,但可能也更复杂,尤其是对于颜色或纹理均匀的食品。
-
下载预制 3D 模型:如果您觉得创建模型太耗时或超出了您当前的技术范围,您可以从像Sketchfab、TurboSquid或Unity Asset Store这样的网站上下载预制模型,这是我们在这个项目中将要做的。只需确保您检查许可条款,看看它们是否符合您的需求。
-
聘请 3D 艺术家:如果您为项目预留了预算,您可能考虑聘请 3D 艺术家为您创建定制的食品模型。这可以为您提供完全符合您规格的模型。
正如我们之前指出的,为了这个增强现实菜单应用,我们将通过 Unity Asset Store 导入我们的模型。按照以下说明进行操作:
-
前往 Unity Asset Store(
assetstore.unity.com/)并搜索French Fries – Free包。或者,您也可以通过此链接访问French Fries包页面:assetstore.unity.com/packages/3d/props/food/french-fries-free-164017。 -
在将包添加到您的资产后,点击现在出现在 Asset Store 网站上的在 Unity 中打开按钮。
-
您的 Unity 项目应该已经打开,您应该会看到一个选项提示您导入包。点击导入按钮继续。
-
一旦包成功导入到您的项目中,重复之前的三个步骤,用于日本食物豆腐 – 免费包(
assetstore.unity.com/packages/3d/props/food/japanese-food-tofu-free-203533)和日本食物 Kashipan – 免费包(assetstore.unity.com/packages/3d/props/food/japanese-food-kashipan-free-210938)。
现在我们已经将适当的食物餐点导入到我们的场景中,我们已经满足了食物预制件的要求。在下一节中,我们将添加 UI 按钮和文本组件,以引导用户通过 AR 菜单应用程序。
向我们的 AR 菜单应用程序添加 UI 按钮和文本元素
在本节中,我们将专注于将三个按钮和两个文本元素集成到我们的场景中。这些按钮分为一个用于启动应用程序和一个用于在菜品之间切换的两个按钮。第一个文本元素用于指导用户通过 AR 菜单应用程序,而第二个则用作占位符,以包含有关显示菜品的详细信息,例如其名称、成分、卡路里含量和饮食类型。
除了第二个文本元素外,这些 UI 元素应始终位于用户的视野内,无论设备如何旋转。这可以通过将它们分配为 AR 摄像机的子对象来实现。
让我们从两个交换菜品的按钮开始。按照以下步骤操作:
-
导航到场景层次结构窗口,右键点击AR Camera组件,选择UI | Canvas。此操作将Canvas添加为AR Camera的子对象。Canvas组件对于所有 UI 元素都是必要的。
-
将 Canvas 的
0.01、0.01、0.01调整到480和90。将0,0,1定位。 -
通过右键点击
ButtonNext和ButtonPrevious创建按钮。将两个按钮缩放调整为0.07、0.32、1,并定位到10、40、0和-10、40、0)。 -
对于两个按钮的子对象,在检查器窗口中输入箭头,如
->和<-作为文本输入。这些箭头告诉用户哪个按钮切换到下一道或上一道菜。
在这个阶段,两个按钮已经完全初始化。接下来,我们需要创建一个指导性文本,以指导用户如何使用 AR 菜单应用程序。为了实现这一点,请按照以下逐步说明操作:
-
右键点击
0.17、0.17、0.17。调整面板顶部为-46.5,面板底部为-3.4。这个面板将作为我们的文本的背景。您可以选择其颜色;在我们的案例中,我们选择了红色。将此面板重命名为InfoPanel。 -
对于指导性文本,右键点击
InstructionText。将其缩放调整为0.7、0.7、0.7,并定位到600和150;然后,将其定位到0、0、0。 -
输入以下文本:
等待蓝色表面可见。这显示了放置食物的区域。这条指令对于用户来说至关重要,因为我们将在场景中实现一个蓝色网格区域,以指示食物预制件将被放置的位置。 -
为了防止用户在应用程序启动时直接看到一顿饭,在说明文本下方创建另一个按钮。这个按钮负责生成第一道菜。为此,右键点击
PlaceFirstMealButton,将其缩放至 (2.2,2.2,2.2),并将其定位在 (0,-292,0),宽度为160,高度为30。 -
在 检查器 窗口中打开
Place First Meal的子文本组件作为文本输入。激活 活动自动大小 复选框以确保文本与按钮一起调整。InstructionText 和 PlaceFirstMealButton 都是 InfoPanel 的子对象。它们被设计为在放置第一顿饭之后消失。这意味着我们只需要在我们的代码中针对 InfoPanel 而不是三个对象分别进行操作。
最后,我们还需要另一个文本元素,但这次它不应是 AR 相机 的子对象。这个文本需要生成在盘子上方并保持一致。
为了完成这个任务,让我们执行以下步骤:
-
创建另一个 (
0.1,0.1,0.1) 并将其定位在 (0.3,0.3,1),宽度为480,高度为90。将此重命名为FoodInfoCanvas。 -
右键点击
FoodInfoText,将其缩放至 (0.005,0.005,0.005),并将其定位在 (-3.4,0,31,0),宽度为200,高度为50。FoodInfoText 不需要文本输入,因为这将通过程序与显示的菜肴相对应。
在这一点上,你的 场景层次结构 窗口应该看起来像 图 6.1 中所示的那样。

图 6.1 – 我们项目的场景层次结构窗口,展示了场景中的所有组件
同样,你所有的 UI 元素都应该在游戏视图中对齐,如图 图 6.2 所示。

图 6.2 – 我们项目的游戏视图,展示了场景中不同 UI 元素的排列
请注意,所有 UI 元素都是根据 Canvas 组件进行定位和缩放的。如果你的 UI 元素与 图 6.2 中显示的对齐方式不同,你可以手动调整你的 Canvas 组件的位置和缩放。
通过这样,我们已经成功地将所有必要的 UI 元素添加到我们的场景中,因此完成了添加 UI 按钮和文本元素以创建一个交互式 AR 应用程序。接下来,我们将向场景添加脚本以引入一些交互性和活力。
为我们的 AR 菜单应用程序添加交互性
为了给我们的当前简陋的 AR 场景注入活力,我们必须将一些 C#脚本整合到我们的项目中。这一关键步骤将赋予我们 AR 应用的用户动态且吸引人的交互能力。
在下一节中,你将概述简短但决定性的Food脚本。
将 Food 脚本添加到场景中
在我们深入脚本编写之前,让我们首先组织我们的项目工作空间,以便我们可以通过快速找到所需组件来更有效地工作。
首先,在Scripts目录下的Assets目录中添加一个新的文件夹,并进入该文件夹。在这个空文件夹中右键点击,选择Food。双击这个脚本后,它应该会在你偏好的集成开发环境(IDE)中打开。
创建的Food对象将具有某些特性或属性,就像每辆车都有品牌、型号和颜色一样。
下面是这个脚本的简单分解:
[System.Serializable]
public class Food
{
public string name;
public string ingredients;
public string calories;
public string dietType;
public GameObject prefab;
}
[System.Serializable]是一个指令,告诉 Unity 使这个类可序列化。这意味着 Unity 将能够保存和加载Food对象,你将能够在 Unity 编辑器中直接编辑Food对象。
在定义一个新的公共类Food之后,声明了一个名为name的公共属性。这个属性代表食物的名称,例如French Fries。接下来,我们声明了额外的属性,如ingredients、calories和dietType。后者属性存储食物适合的饮食类型,如Vegetarian、Vegan或Paleo。
最后,声明了一个公共属性,它将持有代表将在 AR 环境中显示的 3D 模型的GameObject。
当我们进入下一节时,我们将通过整合场景中最关键的 C#脚本——ARPlacePrefab脚本,继续我们的旅程。正是这个关键组件将真正打开我们 AR 菜单应用中的交互之门。
将 ARPlacePrefab 脚本添加到场景中
与本章中我们创建的先前脚本类似,导航到ARPlacePrefab中的Assets文件夹。
注意
我们强烈建议你克隆本书 GitHub 仓库中的第六章项目,并在并行打开它,这样你可以更容易地回顾并模仿本项目教程中描述的步骤。
我们可以通过双击来打开刚刚创建的ARPlacePrefab脚本。
小贴士
脚本将在你通常使用的默认 IDE 中启动。如果你希望切换到不同的 IDE,只需在 Unity 编辑器中转到编辑 | 首选项。在新打开的首选项窗口中,导航到外部工具选项卡,并将外部脚本编辑器更改为你偏好的 IDE。
如前所述,ARPlacePrefab脚本将作为我们的主要脚本。它执行处理 3D 模型和 UI 按钮在 AR 空间内放置的关键角色。此外,它管理用户交互,以便它可以定位对象并根据 AR 射线投射结果动态更新放置指示器。
接下来,让我们看看ARPlacePrefab脚本中的各种方法和函数。
理解ARPlacePrefab脚本
由于ARPlacePrefab脚本是我们 AR 菜单应用的核心,我们必须了解它的每一个方法,才能真正掌握交互式 AR 体验的机制,并在各种项目和环境中成功复制脚本的功能。
在下面的代码片段中,您会注意到一些被注释掉的行。这是因为它们引用了尚未创建的SwabPrefab脚本,如果取消注释,将导致编译错误。
在ARPlacePrefab脚本顶部,声明了各种公共和私有变量:
public class ARPlacePrefab : MonoBehaviour
{
public GameObject ObjectToPlace;
//public SwapPrefab SwapPrefabScript;
public GameObject NextPrefabButton;
public GameObject PreviousPrefabButton;
public TextMeshProUGUI InfoText;
public Button PlaceFirstMealButton;
public GameObject InfoPanel;
private ARRaycastManager _arRaycastManager;
private Pose _placementPose;
private bool _placementPoseIsValid = false;
private GameObject _placedObject;
private GameObject _nextButton;
private GameObject _previousButton;
private Vector2 _oldTouchDistance;
private GameObject _placementIndicator;
private GameObject _placementGrid;
ARPlacePrefab脚本的公共变量允许用户与 AR 空间交互,例如定位ObjectToPlace或使用NextPrefabButton和PreviousPrefabButton在 3D 模型之间循环。它们还允许用户通过InfoText和InfoPanel查看详细信息,以及使用PlaceFirstMealButton激活特定的 AR 放置。此外,它们为扩展的详细信息或选项提供了空间。
另一方面,私有变量控制着 AR 体验的内部机制。_arRaycastManager处理真实世界环境中的表面检测,而_placementPose表示 AR 对象的期望位置。其有效性通过_placementPoseIsValid跟踪。一旦对象放置在 AR 空间中,它就被称为_placedObject。触摸手势使用_oldTouchDistance。最后,_placementIndicator和_placementGrid为用户提供视觉提示,指示 AR 对象将放置的位置。
重要提示
一些与尚未引入的SwapPrefab脚本相关的行已被注释掉,以防止任何编译问题。我们将在脚本编写过程的最后取消注释它们。
ARPlacePrefab脚本的第一种方法是Start()方法:
void Start()
{
_arRaycastManager =
FindObjectOfType<ARRaycastManager>();
//_nextButton = InstantiateButton(NextPrefabButton,
//SwapPrefabScript.SwapFoodPrefab);
//_previousButton =
//InstantiateButton(PreviousPrefabButton,
//SwapPrefabScript.SwapToPreviousFoodPrefab);
_placementGrid = CreatePlacementGrid();
PlaceFirstMealButton.onClick
.AddListener(PlaceObjectIfNeeded);
}
当程序首次启动时,会调用此函数。这是脚本初始设置的地点,例如找到被注释掉的_nextButton和_previousButton,因为它们引用了尚未创建的SwapPrefab脚本。此脚本与两个按钮相关联,允许用户在各种食物选择之间循环。
在ARPlacePrefab类中调用的下一个方法是Update()方法:
void Update()
{
if (Input.touchCount == 2)
{
PinchToScale();
}
UpdatePlacementPose();
UpdatePlacementIndicator();
if (_placementPoseIsValid && Input.touchCount > 0
&& Input.GetTouch(0).phase == TouchPhase.Began)
{
PlaceObject();
}
}
Update() 方法就像是脚本的脉搏,在游戏运行时的每一刻都在不断检查事物。如果检测到两指触摸输入,它会根据手指之间距离的变化调整放置对象的缩放,类似于捏合或拉伸动作。它还会更新放置姿态和指示器,这决定了对象将被放置的位置,并监听单一触摸输入。如果检测到单一触摸输入,它会放置对象。
PlaceObject() 方法紧随 Update() 方法之后,其形式如下:
public void PlaceObject()
{
if (_placedObject != null)
{
Destroy(_placedObject);
}
_placedObject = Instantiate(ObjectToPlace,
_placementPose.position,
_placementPose.rotation);
_placedObject.transform.localScale = new
Vector3(0.5f, 0.5f, 0.5f);
PositionButton(_nextButton, new Vector3(0.5f, 0f,
0f));
PositionButton(_previousButton, new Vector3(-0.5f,
0f, 0f));
UpdateFoodInfoText();
_placementGrid.SetActive(false);
}
当在 Update() 函数中检测到单一触摸输入时,此函数会被调用。它将选定的对象放置在现实世界中,位置由放置姿态确定。然后,它定位并激活下一个和上一个按钮。接着,它获取有关当前选定食物项目的某些信息,并使用这些信息更新 InfoText UI。
ARPlacePrefab 类中的下一个方法是 UpdatePlacementPose() 方法:
private void UpdatePlacementPose()
{
var screenCenter =
Camera.current.ViewportToScreenPoint(
new Vector3(0.5f, 0.5f));
var hits = new List<ARRaycastHit>();
_arRaycastManager.Raycast(screenCenter, hits,
TrackableType.Planes);
_placementPoseIsValid = hits.Count > 0;
if (_placementPoseIsValid)
{
_placementPose = hits[0].pose;
PositionGrid(hits[0].pose.position,
hits[0].pose.rotation);
}
else
{
_placementGrid.SetActive(false);
}
}
此方法在 Update() 函数中被调用。它就像脚本的眼睛,因为它总是在屏幕中间寻找,并确定在现实世界中对应于虚拟世界中的哪个位置。该方法更新放置姿态,即新对象将被放置的位置和方向。它是通过从屏幕中心发射一条射线并检查它是否击中 AR 环境中的平面来做到这一点的。
UpdatePlacementIndicator() 方法与 UpdatePlacementPose() 方法类似,其形式如下:
private void UpdatePlacementIndicator()
{
if (_placementPoseIsValid)
{
_placementIndicator.SetActive(true);
_placementIndicator.transform
.SetPositionAndRotation(
_placementPose.position,
_placementPose.rotation);
}
else
{
_placementIndicator.SetActive(false);
}
}
此函数也在 Update() 函数中被调用。它简单地移动和旋转放置指示器以匹配放置姿态,向用户显示对象将被放置的位置。它还根据是否找到了放置对象的合适位置来打开或关闭 LineRenderer。
下一个方法被称为 InstantiateButton(),其形式如下:
private GameObject InstantiateButton(GameObject
buttonPrefab, UnityEngine.Events.UnityAction onClickAction)
{
var button = Instantiate(buttonPrefab);
button.SetActive(false);
button.GetComponent<Button>().onClick
.AddListener(onClickAction);
return button;
}
InstantiateButton 方法在 ARPlacePrefab 类中扮演着至关重要的齿轮角色。其主要作用是创建并设置用户与之交互以在食物选择之间导航的按钮。当被调用时,该方法接收两个参数:一个按钮预制件和一个在点击按钮时要执行的操作。
该方法首先使用提供的预制件创建一个新的按钮实例。一旦实例化,按钮最初被设置为不活动状态,确保它不会立即出现或干扰用户界面。然后,该方法获取按钮内置的 On Click 事件并将其指定操作附加到它,确保在按下按钮时执行所需的函数。最后,该方法返回新创建和配置的按钮,以便在 AR 界面中使用。
脚本中的下一个两个方法充当辅助函数。它们被命名为 CreatePlacementGrid() 和 PlaceObjectIfNeeded():
private GameObject CreatePlacementGrid()
{
var grid =
GameObject.CreatePrimitive(PrimitiveType.Plane);
grid.transform.localScale = new Vector3(0.01f,
0.01f, 0.01f);
grid.GetComponent<Renderer>().material =
Resources.Load<Material>("GridMaterial");
grid.SetActive(false);
return grid;
}
private void PlaceObjectIfNeeded()
{
if (_placementPoseIsValid)
{
PlaceObject();
InfoPanel.SetActive(false);
}
}
CreatePlacementGrid() 方法在虚拟世界中创建一个小网格,帮助你看到你的菜肴将被放置的位置。如果一切设置正确,PlaceObjectIfNeeded() 方法将在虚拟世界中放置食物预制件,然后隐藏 InfoPanel,清理你的屏幕。注意 CreatePlacementGrid() 方法中的以下行:
grid.GetComponent<Renderer>().material =
Resources.Load<Material>("GridMaterial");
在这里,我们分配一个 grid,以便用户看到食物预制件将被放置的视觉提示。除了使用 Unity 编辑器的界面外,C# 脚本还为我们提供了另一种将材料分配给 GameObject 的方法——即通过定义我们想要使用的材料的精确路径和名称。在这种情况下,一个名为 GridMaterial 的材料预计将位于我们项目的 Resources 文件夹中。
在继续介绍接下来的几种方法之前,让我们快速在我们的项目“资源”文件夹中创建一个名为 GridMaterial 的材料。只需前往 Assets 文件夹,选择 Resources 并进入。在文件夹内右键点击,选择 GridMaterial 并选择你喜欢的蓝色漫反射颜色。
现在,回到 ARPlacePrefab 类,让我们看看 PinchToScale() 和 ScalePlacedObject() 方法,它们看起来是这样的:
private void PinchToScale()
{
Touch touchZero = Input.GetTouch(0);
Touch touchOne = Input.GetTouch(1);
if (touchZero.phase ==
TouchPhase.Moved || touchOne.phase ==
TouchPhase.Moved)
{
Vector2 touchDistance =
touchOne.position - touchZero.position;
float pinchDistanceChange =
touchDistance.magnitude –
_oldTouchDistance.magnitude;
float pinchToScaleSensitivity = 0.001f;
if (_placedObject != null)
{
ScalePlacedObject(pinchDistanceChange,
pinchToScaleSensitivity);
}
_oldTouchDistance = touchDistance;
}
}
private void ScalePlacedObject(float pinchDistanceChange, float pinchToScaleSensitivity)
{
Vector3 newScale =
_placedObject.transform.localScale + new
Vector3(pinchDistanceChange,
pinchDistanceChange, pinchDistanceChange) *
pinchToScaleSensitivity;
newScale = Vector3.Max(newScale, new Vector3(0.1f,
0.1f, 0.1f));
newScale = Vector3.Min(newScale, new Vector3(10f,
10f, 10f));
_placedObject.transform.localScale = newScale;
}
如这两个方法的名称所暗示的,它们启用了食物预制件的缩放功能。PinchToScale() 方法检查你是否正在使用两只手指捏屏幕,如果是,它通过调用 ScalePlacedObject() 方法来改变你放置对象的大小。这种功能在我们的 AR 菜单应用程序的上下文中非常有用,因为它使用户能够将显示的食物预制件缩放到所需的大小。
PositionButton() 方法为应用程序用户提供了另一个有用的功能。它由以下组件组成:
private void PositionButton(GameObject button,
Vector3 offset)
{
button.transform.position =
_placedObject.transform.position + offset;
button.SetActive(true);
}
PositionButton() 方法确保下一个和上一个按钮始终靠近你的放置对象,这样你可以轻松地按下它们。因此,这个方法对于确保在不同设备上提供令人满意的 AR 菜单应用程序的用户体验是基本的。
UpdateFoodInfoText() 方法是 ARPlacePrefab 类的另一个重要部分。让我们看看这个方法的样子:
private void UpdateFoodInfoText()
{
/*Food currentFood =
SwapPrefabScript.GetCurrentFood();
InfoText.text = $"<b>Name:</b>
{currentFood.name}\n<b>Ingredients:</b>
{currentFood.ingredients}\n
<b><color=red>Calories:</color></b>
{currentFood.calories}\n<b>Diet Type:</b>
{currentFood.dietType}";*/
InfoText.transform.position =
_placedObject.transform.position + new
Vector3(-0.2f, 0.3f, 0f);
InfoText.transform.rotation =
_placedObject.transform.rotation;
}
一旦你在环境中放置了一个食物预制件,UpdateFoodInfoText() 方法会告诉你更多关于这个特定菜肴的信息,例如它的名称、成分、有多少卡路里以及它符合哪种饮食。与之前一样,由于它们引用尚未创建的 SwapPrefab 脚本,初始行已被注释掉。
最后,在 ARPlacePrefab 类中,你还需要理解一个小脚本。它是 PositionGrid() 方法,看起来是这样的:
private void PositionGrid(Vector3 position,
Quaternion rotation)
{
_placementGrid.transform.SetPositionAndRotation(
position, rotation);
_placementGrid.SetActive(true);
}
这个方法简单地将放置网格移动到虚拟世界中的正确位置,以便它与你在现实世界中的指示器所指的位置相匹配。
这样,您就成功理解了 ARPlacePrefab 脚本,这是我们 AR 菜单应用中使用的首要脚本。在下一节中,您将学习如何将此脚本作为组件附加到 AR Session Origin。
将 ARPlacePrefab 脚本作为组件分配
在 Unity 编辑器的 Inspector 窗口中,在进入下一步之前,将任何 AR 应用程序的主脚本作为组件附加到 ARPlacePrefab 脚本。为此,只需遵循以下步骤:
-
选择
ARPlacePrefab脚本。通过选择它,脚本的可公开字段将在 Inspector 窗口中显示。 -
对于 Object to Place 字段,您可以通过从 Project 窗口中将其拖放到相应的单元格来分配一个食物预制件,例如 Tofu。
-
按照同样的原则,您可以将 ButtonNext 拖放到 Next Prefab Button 单元格,ButtonPrevious 拖放到 Previous Prefab Button 单元格,FoodInfoText 拖放到 InfoText 单元格,PlaceFirstMealButton 拖放到 Place First Meal Button 单元格,以及 InfoPanel 拖放到 Info Panel 单元格。
重要提示
SwapPrefab 单元格期望的是 SwapPrefab 脚本,我们将在接下来的章节中创建并分配它。
恭喜您 – 您已成功完成我们路线图上创建交互式 AR 菜单应用的 ARPlacePrefab 脚本要求!在下一节中,您将通过深入研究交换我们的食物预制件的脚本:SwapPrefab 脚本来更接近最终应用。
将 SwapPrefab 脚本添加到场景中
要将 SwapPrefab 中的 Assets 文件夹添加到场景中,双击脚本以在您首选的 IDE 中打开它。
SwapPrefab 脚本与允许用户循环选择不同食物选项的两个按钮相关联。它看起来是这样的:
public class SwapPrefab : MonoBehaviour
{
public Food[] AvailableFoods;
private int CurrentFoodIndex = 0;
private ARPlacePrefab ARPrefabPlacement;
在前面的代码片段中,您可以看到名为 AvailableFoods 的 Food 对象列表的声明,一个用于跟踪当前食物的变量 currentFoodIndex,以及一个指向 ARPlacePrefab 脚本的引用 ARPlacePrefab。
接下来,让我们看看 SwapPrefab 类的方法,以了解用户如何循环选择不同的菜肴。
与此相关的第一个方法是 Start() 方法。它看起来是这样的:
void Start()
{
ARPrefabPlacement =
FindObjectOfType<ARPlacePrefab>();
if (AvailableFoods.Length > 0)
{
ARPrefabPlacement.ObjectToPlace =
AvailableFoods[0].prefab;
}
}
此方法在场景开始时被调用。它获取 ARPlacePrefab 脚本的引用并将列表中的第一个食物对象设置为在 AR 环境中放置的对象。
接下来,是 SwapFoodPrefab() 方法,它看起来是这样的:
public void SwapFoodPrefab()
{
CurrentFoodIndex = (CurrentFoodIndex + 1) %
AvailableFoods.Length;
ARPrefabPlacement.ObjectToPlace =
AvailableFoods[CurrentFoodIndex].prefab;
ARPrefabPlacement.PlaceObject();
// Update the InfoText
ARPrefabPlacement.InfoText.text = $"<b>Name:</b>
{AvailableFoods[CurrentFoodIndex].name}\n
<b>Ingredients:</b>
{AvailableFoods[CurrentFoodIndex].ingredients}\n
<b><color=red>Calories:</color></b>
{AvailableFoods[CurrentFoodIndex].calories}\n
<b>Diet Type:</b>
{AvailableFoods[CurrentFoodIndex].dietType}";
}
此方法与一个按钮相关联。当按钮被点击时,它将 currentFoodIndex 进度推进到列表中的下一个食物,或者如果它在末尾则回到开始,并在 ARPlacePrefab 脚本中更新 objectToPlace 到新的食物。然后,它立即在 AR 环境中放置新的食物对象并更新显示的食物信息。
SwapPrefab类中的SwapToPreviousFoodPrefab()方法由以下代码行组成:
public void SwapToPreviousFoodPrefab()
{
CurrentFoodIndex--;
if (CurrentFoodIndex < 0)
{
CurrentFoodIndex = AvailableFoods.Length - 1;
}
ARPrefabPlacement.ObjectToPlace =
AvailableFoods[CurrentFoodIndex].prefab;
ARPrefabPlacement.PlaceObject();
// Update the InfoText
ARPrefabPlacement.InfoText.text = $"<b>Name:</b>
{AvailableFoods[CurrentFoodIndex].name}\n
<b>Ingredients:</b>
{AvailableFoods[CurrentFoodIndex].ingredients}\n
<b><color=red>Calories:</color></b>
{AvailableFoods[CurrentFoodIndex].calories}\n
<b>Diet Type:</b>
{AvailableFoods[CurrentFoodIndex].dietType}";
}
此方法与SwapFoodPrefab()类似,但它会回到列表中的上一个食物,而不是向前移动。如果它已经在列表的起点,它会循环回末尾。像SwapFoodPrefab()一样,然后它会立即放置新的食物对象并更新显示的信息。
最后,还有一个简短的GetCurrentFood()方法:
public Food GetCurrentFood()
{
return AvailableFoods[CurrentFoodIndex];
}
这是一个简单的辅助方法,其他程序部分可以调用它来找出当前的食物是什么。
记得我们在ARPlacePrefab脚本中注释掉的那些行吗?因为它们引用了SwapPrefab脚本?现在是我们回到ARPlacePrefab脚本并取消注释那些行的时候了。一旦完成,我们就可以深入到最后缺失的 AR 菜单应用程序片段。
为按钮设置点击事件
现在,我们需要通过为两个添加点击事件来链接SwapPrefab脚本。按照以下步骤进行操作:
-
我们需要将
SwapPrefab脚本附加到场景中的GameObject对象上。我们可以在GameObject到PrefabManager中创建一个空的GameObject对象,并将SwapPrefab脚本附加到它上面。 -
现在,我们必须链接
SwapPrefab脚本。让我们从将PrefabManagerGameObject拖放到对象单元格开始。在下拉菜单中,选择SwapPrefab|SwapFoodPrefab()函数。这将在ButtonNext被按下时调用SwapPrefab脚本的SwapFoodPrefab()函数。图 6**.3显示了ButtonNext的点击事件应该看起来像什么。

图 6.3 – ButtonNext 的点击事件
- 重复此过程,从下拉菜单中选择
SwapPrefab|SwapToPreviousFoodPrefab()函数。
你还记得在将 ARPlacePrefab 脚本作为组件分配部分中的要点吗?即SwapPrefab脚本是附加到SwapPrefab脚本的ARPlacePrefab脚本中最后缺失的单元格输入。你可以通过以下几个简单的步骤来完成:
-
在场景****层次结构窗口中选择AR Session Origin。
-
通过项目窗口的搜索栏搜索
SwapPrefab。 -
现在,将脚本拖放到 AR Session Origin 的
ARPlacePrefab脚本组件的相应单元格中。ARPlacePrefab脚本组件现在应该看起来像这样。

图 6.4 – 当所有单元格都正确分配后,AR Session Origin 的 ARPlacePrefab 脚本组件
在在您的 PC 上测试场景或将其部署到手机之前,您必须采取最后一步:为我们的食物预制件添加一些营养信息。这可以非常容易地完成:
-
在场景层次结构窗口中选择PrefabManager,然后导航到检查器窗口。
-
在
SwapPrefab脚本组件中,点击+按钮三次,将三个菜品添加到我们的 AR 菜单应用中。 -
将我们三个菜品的名称、营养成分信息、饮食类型和预制件,即薯条、豆腐和咖喱饭,插入到相应的单元格中,如图图 6.5所示。

图 6.5 – 在 PrefabManager 的 SwapPrefab 脚本组件中插入的三个菜品的名称、营养成分信息、饮食类型和预制件
有了这些,您已经完成了创建交互式 AR 菜单应用的路线图中的最后一步。为了庆祝这一里程碑,下一节将解释您如何在您的移动设备上探索您新开发的 AR 应用的不同功能。
在移动设备上探索完成的交互式 AR 菜单应用
要在您的 PC 上测试您的交互式 AR 菜单应用或将它部署到您的移动设备上,请参阅第四章中“将 AR 体验部署到移动设备”部分提供的逐步说明。图 6.6展示了您成功将 AR 菜单应用部署到您的移动设备并打开后屏幕上应该显示的内容。

图 6.6 – 在移动设备上新部署的 AR 菜单应用的初始屏幕
注意我们如何看到说明文本,它使用户熟悉应用的本质,以及应用底部的按钮,用户必须按下此按钮才能将第一道菜放置在检测到的平面上。您还可以看到用户可以按下的两个按钮,用于查看下一个或上一个预制件。如果您的场景中有一个水平平面,您将在屏幕中央看到蓝色的放置网格元素。
图 6.7 展示了您按下放置第一餐按钮后,设备屏幕应该看起来是什么样子。

图 6.7 – 按下“放置第一餐”按钮后,移动设备上的 AR 菜单应用屏幕
通过用两个手指触摸屏幕并将它们靠近或分开,您可以调整薯条的大小,使其变大或变小。在放置第一个食物预制件后,更改您的移动设备的旋转并点击->按钮,下一个食物预制件应该放置在新的位置,如蓝色放置网格元素所示。
即将到来的部分为您在 Unity 中创建 XR 应用之旅中获得的宝贵技能提供了一个总结。具体来说,您已经利用 C#脚本来制作交互式 AR 应用。这种新获得的专业技能对您的技能组合是一个重大的提升,扩大了您开发复杂 XR 体验的能力。
摘要
在本章中,您开始了构建您第一个交互式 AR 应用的激动人心的旅程,并在您的移动设备上对其进行了细致的测试。这次经历应该使您能够从实用性角度批判性地评估潜在的 AR 应用想法。
利用直观的设计模式,您现在应该感到有足够的装备来创建引人入胜的 AR 应用,使用户能够无缝地在现实世界环境中与虚拟对象互动。从建立 AR 应用的核心组件,如用户界面和文本元素,到通过 C#脚本调用它们的交互性,您现在已经准备好创建各种交互式 AR 应用。
这些应用将为放置在现实世界环境中的虚拟对象注入生命,邀请用户以重要且引人入胜的方式与之互动。恭喜您在 AR 开发之旅中达到这一里程碑。您现在完全有能力将您的创意 AR 想法变为现实。
展望未来,下一章将承诺将您的 VR 开发技能提升到新的水平。这全部都是为了通过音效和视觉效果为您的 VR 场景增添魔力。即将到来的章节将深入探讨 Unity 中音频的理论,引导您通过整合音频源和混音器的过程,并揭示将粒子效果和动画添加到您的 VR 体验中的秘密。前方的道路注定是一场激动人心的发现与应用之旅。
第七章:添加声音和视觉效果
创建沉浸式 XR 体验不仅需要导入 3D 资产和编写交互脚本。为了实现真正自然和吸引人的体验,我们需要整合声音和视觉效果。想象一下一个 AR 怪物狩猎游戏。您已经构建了逻辑,但没有声音和视觉效果,现实世界与虚拟现实的感觉就会失调。添加微妙的怪物声音可以提供方向和距离线索。整合如灰色雾气这样的粒子效果可以增强神秘、恐怖的氛围。通过刺激多种感官并调整这些元素以适应用户的动作,我们可以显著增强 AR 怪物狩猎游戏的整体沉浸感和用户体验。
本章旨在提高您的 XR 设计技能,针对更多用户感官以实现自然、沉浸式的体验。我们将深入研究声音理论和粒子行为的基础知识,使这些物理概念对所有用户都易于理解。我们将深入研究 Unity 的音频和粒子系统,了解它们如何帮助我们重现现实世界现象。按照我们的动手实践方法,您将在 Unity 中应用这些概念,创建您迄今为止最沉浸式的 VR 体验。
让我们深入探索创建逼真 XR 体验的激动人心之旅!本章将引导您通过以下四个部分:
-
理解声音理论和 Unity 的音频系统
-
准备 VR 鼓场景并添加音效
-
理解粒子行为和 Unity 的粒子系统
-
在具有不同属性的 VR 场景中添加粒子
技术要求
为了充分参与并从本章概述的 VR 应用开发过程中受益,您的硬件必须满足某些技术规格。如果您遵循了第三章中的教程,并且您的 Unity 设置保持不变,您可以跳过本节。
要跟随本书的内容和示例,请确保您的计算机系统可以容纳Unity 2021.3 LTS或更高版本,以及Android或Windows/Mac/Linux 构建支持,具体取决于您的 VR 头盔和 PC 的性质。
理解声音理论和 Unity 的音频系统
在接下来的章节中,我们将深入研究声波的迷人物理特性,并探讨 Unity 强大的音频系统如何通过其多样化的音频组件来操纵这些属性。我们的旅程从声音的基本原理开始,声音的本质及其定义特征——频率和振幅。
频率和振幅是什么?
从本质上讲,声音是一种机械能,它以波的形式通过介质传播——最常见的是空气。简单来说,机械能是与物体运动相关的能量。当一个物体振动时,它会移动周围的空气粒子,引发一系列粒子位移的连锁反应,这些反应以声波的形式向外传播。
描述声音波的两个主要参数是频率和振幅。
频率是每秒完成的波周期数,以赫兹(Hz)为单位测量。它决定了声音的音调——频率越高,音调越高;频率越低,音调越低。在游戏开发中,理解频率至关重要。例如,像小鸟这样小而轻的动物会有高音调(高频)的啁啾,而像大象这样大的动物会有低音调(低频)的吼叫。
振幅指的是声波推动粒子的最大位移。简单来说,就是当波通过时粒子被推得有多远。它对应于声音的响度——振幅越大,声音越响;振幅越小,声音越轻。在游戏和 XR 应用中,振幅可以用来创造距离感。远离玩家的声音源会有较小的振幅,因此听起来较轻,而靠近玩家的声音源听起来较响。
理解声音的其他特性
虽然频率和振幅是基本的,但还有其他几个特性可以增加 XR 中声音体验的深度。这些包括音色(发音为tamber)、包络、空间音频、混响和回声。让我们一步一步地了解它们:
-
音色:这描述了声音的颜色或质量,使我们能够区分具有相同音调和响度的不同声音源。在这里,“颜色”指的是声音的独特特征和音调细微差别,使其与其他声音区分开来。这就是我们能够区分小提琴和长笛,即使它们在相同的音量和音调下演奏同一音符的原因。在游戏开发中,音色可以用来给不同的角色或环境赋予它们独特的声音特征。
-
包络:声音的包络指的是它随时间的变化。传统上,它被分为四个部分——攻击、衰减、持续和释放(ADSR)。ADSR 描述了声音的初始峰值(攻击),随后降至稳定水平(衰减),在该水平上维持一段时间(持续),以及声音最终逐渐消失(释放)。在 XR 中,修改 ADSR 包络可以使声音听起来更真实,或者可以创造性地使用,给声音带来一种风格化的感觉。
-
空间音频:这指的是对声音源方向和距离的感知。我们的大脑使用几个线索来确定声音源的位置,例如声音到达我们两只耳朵之间的时间差(双耳线索)、耳朵形状引起的频率变化(频谱线索),以及我们移动头部时声音的变化(动态线索)。游戏和 XR 开发者可以模拟这些效果来创建沉浸式的 3D 声音景观,玩家可以在游戏环境中定位声音源。例如,在 VR 恐怖游戏中,你可以使用空间音频让玩家听起来像是从玩家肩膀上方传来的诡异低语,或者像怪物逼近的脚步声越来越近。这些技术可以显著增强沉浸感和游戏体验,因为玩家可以利用声音来导航环境或检测威胁。
-
混响或回声:这是在原始声音移除后,特定空间中声音的持续存在。它是由声音波在环境中的表面(如墙壁和地板)反射造成的,产生了众多逐渐消失的回声。这可以让玩家感受到他们所在空间的大小和材质——一个大型、石墙的大教堂会有长而明亮的混响,而一个小型、地毯覆盖的房间则会有短而暗淡的混响。
-
回声:这是可以清楚识别为原始声音重复的明显延迟声音反射。它发生在声音波从远处障碍物反弹回来,并在明显的时间间隔后到达听者时。反射返回所需的时间可以让听者对反射表面的距离有印象——山脉会产生长延迟的回声,而较近的建筑可能会产生更快、更直接的回声。不同的表面也会影响回声的音调质量,硬表面如混凝土产生的回声比软表面如茂密的植被更清晰。
理解和操作这些声音方面的特性,可以使你在 XR 应用程序中创建丰富、沉浸和交互式的声音景观。通过精心设计,声音不仅可以作为视觉体验的伴奏,还可以成为游戏玩法和沉浸感的关键元素。以下部分将向您介绍 Unity 的音频系统,我们将在本章中多次使用它,为我们的 XR 体验注入更多生命力和沉浸感。
探索 Unity 的音频系统
声音设计是创建沉浸式 XR 体验的重要组成部分。使用 Unity 的音频系统,你可以创建动态、空间化的音频,它会对玩家的动作和移动做出反应,增强沉浸感甚至引导游戏玩法。
例如,在 VR 恐怖游戏中,您可以使用空间化声音来创造一种不祥的氛围并建立紧张感。远处的诡异声音可能暗示着看不见的危险,而突然的近距离声音可能提供跳跃惊吓。随着玩家在环境中导航,声音根据他们的位置和方向变化,使虚拟世界感觉生动且反应灵敏。
理解并有效地使用 Unity 的音频系统是任何 XR 开发者必备的关键技能。声音不仅仅是视觉的附属品;它也是叙事、玩家指导和世界构建的强大工具。
现在让我们更详细地看看 Unity 音频系统的三个核心组件——AudioClips、AudioSources 和 AudioListeners。
-
AudioClip代表一个可以在您的应用程序中播放的声音文件。它包含声音数据,但单独的AudioClip文件实际上不能产生声音。将AudioClip文件想象成一张 CD——它包含音乐,但您需要一个 CD 播放器才能真正听到音乐。AudioClip文件非常灵活——您可以用它们来制作短声音效果,如角色的脚步声,或者用于较长的音频片段,如背景音乐或对话。Unity 支持多种音频文件格式,包括.wav、.mp3和.ogg。在设计 XR 的声音时,请记住,音质对于沉浸感非常重要。高质量的AudioClip文件可以使虚拟环境感觉更加真实。 -
AudioSource就像是您的AudioClip文件的 CD 播放器。它是一个可以附加到 GameObject 上的组件,用于播放声音。您可以将其视为您 3D 空间中声音起源的点。在 Unity 应用程序中听到的每一个声音都源自AudioSource组件。AudioSource组件在场景中播放AudioClip文件,并控制声音的播放方式。AudioSource组件提供了一些您可以操作的属性:-
将要播放的
AudioClip文件。 -
AudioSource组件将在场景开始时立即播放其AudioClip文件。 -
AudioSource组件将循环其AudioClip文件,一旦结束就重新开始播放。 -
AudioSource组件,并且可以用来淡入或淡出声音。 -
AudioSource。值越高,音调越高;值越低,音调越低。这可以用来创建 多普勒效应,即观察者相对于其源移动时波频率或波长的变化——例如,行驶的汽车的声音从高音调变为低音调。 -
3D 声音设置:这些设置控制声音如何受到距离的影响。您可以设置声音随着距离变远而变弱,改变音调,等等。这对于 XR 应用程序至关重要,因为它有助于创造空间感和现实感。
-
-
场景中的
AudioSource组件被处理以创建玩家最终听到的混合声音。在大多数游戏和 XR 应用中,AudioListener连接到主相机或玩家的化身。当玩家在环境中移动时,根据它们与AudioListener的距离和方向,不同的声音会变得更大或更小,从而创建一个动态的声音景观。
重要提示
重要的是要注意,您通常只应在场景中有一个AudioListener。拥有多个可能会导致声音重复,这可能导致失真和其他音频伪影。
以下部分将指导您如何通过一个新的、动手的 VR 项目将这些组件集成到您的 Unity 场景中。
准备 VR 鼓场景并添加音效
在探索声音波动的物理特性和 Unity 的音频系统之后,您最终将把理论知识应用于构建自己的 VR 鼓场景。
一旦您创建了一个包含各种鼓的 VR 场景,玩家可以用双手的 VR 鼓槌击打这些鼓,您将发现如何通过为每个被击打的鼓分配不同的声音文件来增强您的设置。此外,您还将学习如何根据 VR 鼓槌施加的打击强度调整声音音量,增加额外的真实感。这个经过优化的 VR 鼓击环境将使用户沉浸在令人印象深刻且引人入胜的鼓击体验中。现在让我们设置并准备我们的 VR 鼓场景。
设置和准备您的 VR 鼓场景
以下步骤将指导您如何创建项目、在 Unity 编辑器中设置所需的 VR 设置,并添加一个带有地面层的玩家。
-
使用 URP 创建一个新项目,选择
Drum Scene。 -
场景加载完成后,导航到编辑 | 项目设置 | XR 插件管理并点击安装按钮。安装完成后,启用OpenXR复选框。如果您被提示重新启动编辑器,请按照指示操作。
-
在编辑 | 项目设置 | XR 插件管理下,进入OpenXR子菜单。在Windows/Linux/Mac选项卡下,选择与您的头戴设备相匹配的交互配置文件。
-
要将所需的预制件添加到我们的 VR 玩家场景中,我们需要安装 XR 交互工具包。为此,请转到
com.unity.xr.interaction.toolkit和2.5.1,然后点击添加按钮。这将自动将 XR 交互工具包安装到您的场景中。安装过程完成后,在包管理器窗口中选择XR 交互工具包,并点击Starter Assets和XR 设备模拟器旁边的导入按钮,如图图 7.1所示。

图 7.1 – XR 交互工具包成功安装在包管理器窗口中,与导入的起始资源和 XR 设备模拟器一起
- 在层级中删除现有的主摄像机,因为我们将要添加的 VR 玩家自带一个视角摄像机。现在,导航到
floor下的Assets文件夹,并将其放置在原点(0,0,0)。
哈喽!你已经在 Unity 中为 VR 鼓场景搭建了框架!接下来的部分将指导你如何将鼓和鼓槌添加到你的场景中。
为你的 VR 鼓场景创建和导入 3D 模型
虽然 Unity Asset Store 提供了大量的不同 3D 模型,但它不提供适合我们项目的免费鼓模型。因此,我们将利用在Sketchfab上可用的 3D 模型,这是一个丰富的平台,允许你从广泛的创作者那里下载免费和付费的 3D 模型。
本章所选的鼓模型可在skfb.ly/o8QvS找到,由 Bora Özakaltun 创建。打开链接,并按图 7.2所示下载免费的.fbx格式模型。

图 7.2 – 下载鼓模型为.fbx 文件所需的鼠标点击(以黄色突出显示)
重要提示
如果在阅读时模型不可用,你可以从本书的 GitHub 仓库克隆整个项目,并从那里提取资产。
下载完文件夹后,解压缩所有子文件夹。然后,将解压缩的鼓文件夹拖入你的项目窗口,完成模型导入。现在,是时候将鼓整合到你的虚拟环境中了。按照以下步骤将鼓放置在你的场景中:
-
在
Assets文件夹中,然后到drum| “源目录”。在这里,你可以找到你之前导入的鼓模型。 -
选择鼓文件并将其拖入你的场景。这样做后,你可能观察到鼓在环境中显得不成比例地大。
-
为了纠正尺寸问题,在层级中选择鼓并将其缩小到尺寸(
0.02、0.02、0.02)。将鼓放置在原点坐标(0、0、0),使其在虚拟空间中完美对齐。
完成这些调整后,你的场景应该类似于图 7.3中的描述。

图 7.3 – 你的鼓场景在 Unity 编辑器的游戏视图中当前应该看起来是什么样子
现在,我们需要鼓槌来与鼓进行交互。通过以下步骤,我们将在 Unity 中创建自己的鼓槌:
-
在场景层级中右键单击,导航到
0.01、0.2、0.01)。将此 GameObject 重命名为Drum Stick。 -
如您在Inspector窗口中所见,鼓棒自动包含一个Capsule Collider组件。Capsule Collider是 Unity 中用于模拟胶囊或药丸形状的 3D 形状,用于检测物体之间的碰撞。此外,向鼓棒添加一个Rigidbody组件也是必不可少的。这允许物体在 Unity 环境中受到力和物理的影响,实现如沉浸式鼓击体验所需的动态交互。选择鼓棒后,转到其Inspector窗口并选择Add Component按钮。现在,通过搜索并选择它来添加一个Rigidbody组件。此组件允许 Unity 的物理引擎将鼓棒视为物理对象,模拟对力的交互和反应,这对于在打击鼓时真实地模拟鼓棒的行为至关重要。
-
将Rigidbody组件的Collision Detection设置为Continuous Speculative。此模式可以更准确、更高效地处理鼓棒与其他物体之间的碰撞,尤其是在处理鼓击时典型的快速动作。
-
在
Assets文件夹中创建一个新的材质,命名为Drum Stick Material。从commons.wikimedia.org/wiki/File:Balsa_Wood_Texture.jpg下载Balsa_Wood_Texture.jpg并将其导入到项目中。选择Drum Stick Material,在Base Map字段中选择Balsa_Wood_Texture.jpg。将此材质应用到鼓棒上。 -
选择
Drum Stick,点击Drum,并保存标签。我们稍后将需要此标签来引用场景中的鼓棒。 -
在
Prefabs中,将鼓棒拖入其中。这将创建一个预制体,允许轻松复制和修改。 -
最后,根据图 7.4的详细说明,将预制体作为子对象附加到左侧控制器和右侧控制器上。

图 7.4 – 在场景层次结构窗口中,每个鼓棒成功附加到 XR Origin 的相应控制器上
您已成功完成设置和准备 VR 鼓场景的所有步骤。在下一节中,您将学习如何利用 Unity 的音频系统为场景添加音效。
为您的 VR 鼓场景添加音效
本节将指导您通过添加音效到您的 VR 鼓场景的过程。第一步涉及在击打乐器时触发音频,为场景增添真实感和参与感。
在 VR 鼓场景中为碰撞触发声音播放的脚本编写
为了在鼓棒与鼓碰撞时触发声音播放,我们必须使用 C#脚本。按照以下步骤正确准备您的鼓:
-
在 Unity 编辑器中,按键盘上的 Ctrl / Cmd,然后 左键点击 以选择场景层次结构中的所有鼓。
-
选择鼓后,通过检查器窗口点击添加组件按钮,搜索并选择盒子碰撞体组件来添加一个盒子碰撞体组件。
-
然后,我们必须确保碰撞体作为触发器工作,允许它启动动作而不是物理交互。为此,在检查器窗口中,为每个鼓的盒子碰撞体组件选择是触发器复选框。此选项将碰撞体转换为一个非物理边界,可以检测物体通过时的情况,使其在碰撞时触发声音变得至关重要。
-
选择场景层次结构中的所有鼓,点击
PlaySoundOnCollision,然后点击新建脚本。此操作自动将脚本与所有选定的鼓关联起来。 -
在检查器窗口中,双击
PlaySoundOnCollision脚本来打开它。
一旦脚本在您首选的 IDE 中打开,定义以下三个变量:
public AudioClip soundClip;
private AudioSource _soundSource;
public string tag;
我们将使用公共的 AudioClip 变量来播放音频,使用私有的 AudioSource 变量来播放剪辑,并将公共的 tag 变量分配给鼓槌,以便只有这些 GameObject 可以触发声音。
重要提示
tag variable to trigger sound.
在 PlaySoundOnCollision 脚本的 Start() 函数中,添加以下代码行以在体验开始时访问 AudioSource:
_soundSource = GetComponent<AudioSource>();
由于我们不是持续检查变化,因此在这个脚本中不需要 Update() 函数。相反,我们将实现一个 OnTriggerEnter() 方法,该方法在某个物体与触发器碰撞时被调用:
private void OnTriggerEnter(Collider other) {
if (other.CompareTag(tag))
{
_soundSource.PlayOneShot(soundClip);
}
}
OnTriggerEnter() 是一个 Unity 引擎在发生触发器碰撞时自动调用的特殊 Unity 方法。这也是为什么我们不需要在我们的脚本中调用此函数,以及为什么我们在之前的设置中选择了是触发器复选框的原因。
在 OnTriggerEnter() 方法中,我们调用 CompareTag(),这是一个来自 GameObject 类的内置 Unity 函数。通过在 if 语句中调用它,我们将碰撞对象的标签与一个字符串进行比较。使用标签有助于确保只有在鼓槌与鼓碰撞时才播放声音,而不是其他物体可能与之碰撞时。通过为鼓槌分配一个唯一的标签,类似于我们使用的 Drum 标签,我们可以在 OnTriggerEnter() 方法中轻松高效地识别它们,并且只在它们与鼓的碰撞时播放声音。
重要提示
到目前为止,您可能想知道为什么我们使用CompareTag()而不是直接使用相等运算符(==)来比较标签。这样做的原因是使用CompareTag()在计算上更高效。在 Unity 中,标签存储在一个内部哈希格式中,CompareTag()比较这些哈希值,而相等运算符会首先将哈希值转换为字符串,这使得比较速度变慢。
如果标签比较返回true,则执行下一行。_soundSource变量指的是我们稍后将要附加到鼓上的AudioSource组件。PlayOneShot()方法是AudioSource组件的另一个 Unity 函数。这种功能对于我们鼓场景的真实性至关重要。我们不是单独听到每个鼓的敲击声,而是希望创造一个连续的声音流。能够叠加单个敲击声使得体验更加沉浸和真实,反映了鼓快速连续敲击时自然发生的重叠。使用PlayOneShot()方法确保声音和谐融合,捕捉到现场鼓演奏的精髓。
通过结合这些元素,OnTriggerEnter()方法确保当鼓槌接触到鼓时,播放指定的声音,在虚拟环境中产生即时的真实反应。这是一种强大的方式,可以增加沉浸感和交互性到您的 VR 体验中。在完成PlaySoundOnCollision脚本后,现在终于可以给每个鼓添加声音文件了。
为您的 VR 鼓场景添加声音文件
在本节中,您将学习如何导入声音文件并为每个鼓分配AudioSource组件。让我们一步一步地完成这个过程:
-
下载 Unity 场景中每个鼓的适当声音文件。您可以在
www.freesoundslibrary.com/或pixabay.com/sound-effects/等网站上找到免费的.mp3声音文件。或者,您可以选择使用与本章链接的 Unity 项目中提供的声音文件。这些文件可以在本书的 GitHub 仓库中找到。 -
一旦您在本地系统上有了必要的声音文件,请转到 Unity 编辑器的
Assets|Import New Assets。导航到您的声音文件位置,并选择您想要导入的文件。点击Import按钮,现在这些声音文件将可用在您的 Unity 项目中。 -
在Hierarchy窗口中选择所有鼓(Ctrl / Cmd + 左键点击)。在Inspector窗口中,点击Add Component按钮,搜索Audio Source组件,并选择它。
-
现在,在场景层次结构中选择每个鼓,并在检查器窗口中导航到它们的
PlaySoundOnCollision脚本。点击我们之前定义的声音剪辑字段旁边的小圆圈,并为每个鼓选择一个合适的音频文件。
在测试后,你会发现鼓场景已经相当沉浸。然而,一些调整可以进一步提高其真实感。以下部分将指导你如何微调你的鼓场景。
微调 VR 鼓场景以增强其真实感
当前设置在鼓敲击的力度无论轻重时都播放恒定音量的声音。为了增强真实感,我们需要根据碰撞速度调整音量。为此,我们可以利用 Valve 公司的一个现有脚本,名为VelocityEstimator。如果您不熟悉,Valve 是 Steam 游戏平台背后的主要视频游戏开发商和发行商,他们为 Unity 提供了 SteamVR 插件,并在 GitHub 上提供了有趣的 VR 脚本。VelocityEstimator脚本可在 SteamVR Unity 插件的 GitHub 仓库中找到,链接如下:github.com/ValveSoftware/steamvr_unity_plugin/blob/9442d7d7d447e07aa21c64746633dcb5977bdd1e/Assets/SteamVR/InteractionSystem/Core/Scripts/VelocityEstimator.cs#L13。
小贴士
当处理复杂的物理计算(如音量和碰撞之间的关系)时,在互联网上搜索现有解决方案或脚本可以节省时间和精力。在 XR 开发中,理解物理的每一个方面并不总是必要的,但知道如何准确实现物理计算是至关重要的。
Valve 的VelocityEstimator脚本的目的在于计算和估算我们附加到其上的 GameObject 的速度和方向 – 在这种情况下,是鼓棒。当应用于我们的 VR 鼓场景时,此脚本将根据鼓棒的敲击速度调整音量,从而模仿鼓击力度与产生的音量之间的自然相关性。要将VelocityEstimator脚本添加到我们的鼓棒上,请按照以下步骤操作:
-
从 GitHub 下载
VelocityEstimator脚本(通过选择Cmd / Ctrl + Shift + S)。 -
在
Scripts文件夹中,将您从本地文件管理器下载的文件拖放到其中。 -
现在,通过点击检查器窗口中的
VelocityEstimator脚本组件,将其作为组件添加到两个鼓棒上。

图 7.5 – 鼓棒的完全配置好的 VelocityEstimator 脚本组件在检查器窗口中的样子
为了利用我们现有的PlaySoundOnCollision脚本中的鼓槌速度,我们必须对其进行一些修改。在 IDE 中,例如 Visual Studio,再次打开脚本,并将以下三行代码添加到脚本中:
public bool enableVelocity = true;
public float minimumVelocity = 0;
public float maximumVelocity = 3;
第一个变量允许我们决定是否在播放声音时考虑速度。通过将其设置为true,我们启用此功能。minimumVelocity变量定义了速度的下限阈值,允许我们指定将影响音量的最小速度。任何低于此值的速度都不会导致音量降低。相反,maximumVelocity参数设置了将影响音量的速度上限。高于此阈值的速度不会导致音量进一步增加。
这些新参数使我们能够控制鼓槌速度如何影响产生的声音的音量。通过调整最小和最大速度值,我们可以微调鼓声音响的响应性,以创建细腻且逼真的击鼓模拟。
现在,我们必须修改OnTriggerEnter()方法,以便在enableVelocity变量设置为true时使用VelocityEstimator脚本组件,如下所示:
private void OnTriggerEnter(Collider other) {
if (other.CompareTag(tag))
{
VelocityEstimator velEstimator = other.GetComponent<VelocityEstimator>();
if (velEstimator && enableVelocity)
{
float v = velEstimator.GetVelocityEstimate().magnitude;
float soundVolume = Mathf.InverseLerp(minimumVelocity, maximumVelocity, v);
_soundSource.PlayOneShot(soundClip, soundVolume);
}
else
_soundSource.PlayOneShot(soundClip);
}
}
让我们通过OnTriggerEnter()方法的新增部分进行说明。通过调用other.GetComponent<VelocityEstimator>(),我们尝试从带有Drum标签的对象中获取VelocityEstimator类型的组件。如果找到VelocityEstimator组件并且enableVelocity变量设置为true,则if语句内的代码将被执行。在这种情况下,代码首先从VelocityEstimator组件调用GetVelocityEstimate方法以获取速度估计值,然后取该向量的模以获得速度作为一个单独的浮点值。然后,根据速度计算音量并将其存储在soundVolume变量中。InverseLerp()方法返回一个介于0和1之间的值,表示v的值在minimumVelocity和maximumVelocity之间的位置。在下一行调用_soundSource.PlayOneShot(soundClip, soundVolume)时,将以计算出的音量播放一次性声音。
在OnTriggerEnter()函数末尾的else语句会在之前的if语句未满足条件时执行。如果找不到VelocityEstimator脚本组件,或者enableVelocity变量设置为false,则if语句将不会满足。由于没有考虑物体的速度,因此这个代码块内的代码将以默认音量播放声音。
如果我们现在运行场景,当我们用鼓槌敲击鼓面时,我们将完全听不到任何声音。这是因为,在 Valve 的原始VelocityEstimator脚本中,速度估计例程原本打算通过调用BeginEstimatingVelocity()来启动。然而,在我们的PlaySoundOnCollision脚本中,这个函数根本没有被调用;因此,没有进行速度估计。这就是为什么我们在测试场景时始终得到零速度,并且听不到任何声音。
为了解决这个问题,我们需要确保在脚本启动时调用BeginEstimatingVelocity()。这可以通过将以下代码行添加到我们的VelocityEstimator脚本的Start()方法中来实现:
private VelocityEstimator velocityEstimator;
{
private void Start()
{
velocityEstimator = GetComponent<VelocityEstimator>();
if (velocityEstimator != null)
{
velocityEstimator.BeginEstimatingVelocity();
}
}
}
通过将BeginEstimatingVelocity()的调用放在Start()方法中,我们确保了速度估计在鼓槌对象准备好后立即开始,这正是我们想要的。
我们已经成功执行了所有必要的步骤,为每个鼓添加了反映每次敲击强度的声音。现在,是时候戴上你的 VR 头盔,对最终场景进行测试了。请密切关注每个鼓声音的音量变化,这取决于鼓槌与鼓的碰撞速度。同时,仔细观察当你同时敲击两个鼓或连续快速敲击几个鼓时的声音动态。你会对我们的 VR 鼓场景变得多么逼真而感到惊讶。
下一节将教你另一个非常有价值的技能,让你的场景更加自然和沉浸——添加粒子!
理解粒子行为和 Unity 的粒子系统
在设计沉浸式 XR 体验时,理解粒子行为的物理学起着重要作用。通过利用 Unity 的粒子系统和粒子物理的基本原理,你可以创建丰富、动态和逼真的效果,从而增强虚拟环境的沉浸感。在本节中,你将了解关于现实世界粒子行为所需了解的一切。
理解现实世界中粒子的行为
物理世界中粒子的行为指的是物质的小片段或数量如何根据力、环境条件和内在属性移动和相互作用的方式。自然环境中的粒子遵循某些定律和原则。关键因素包括重力、空气阻力、寿命和碰撞行为。以下是所有这些术语的含义概述:
-
重力:粒子受到重力的影响,被拉向质量中心。然而,需要注意的是,并非所有粒子都以相同的方式受到重力的影响。考虑两种常见的粒子系统——从天空落下的雨和从火中升起的火花。在雨的情况下,重力将雨滴拉向地面。相反,火花的上升是因为热量减少了它们的有效重力,热空气上升。
-
空气阻力:空气阻力,也称为阻力,是粒子在通过空气等介质移动时遇到的阻力。它影响粒子的速度和方向,通常导致运动轨迹不那么线性,看起来更自然。例如,火焰或烟囱冒出的烟雾就是一个很好的例子。虽然热量和上升气流最初可能将烟雾推向空中,但空气阻力和风力可以使其膨胀、弯曲和摇摆。同样,考虑一个表示风中飘落的树叶的粒子系统。空气阻力使树叶飘动和旋转,而不是直接随风移动。
-
生命周期:每个粒子都有一个生命周期,即存在一段时间后消失或改变状态。这个生命周期以及在此期间发生的变化,有助于提高粒子效果的真实感。考虑萤火虫效果,其中每个萤火虫都是一个粒子,它会出现,亮光几秒钟(在其生命周期中达到峰值亮度),然后逐渐消失。雪花粒子系统也是一个例子。当雪花(在 Unity 场景中以粒子表示)向地面落下时,它们可能会逐渐消失或缩小,以产生雪花在接触较暖的地面时融化的错觉。
-
碰撞行为:当粒子接触到表面或另一个粒子时,它们会以依赖于其性质和碰撞表面的方式反应。这被称为碰撞行为。例如,雨滴在击中硬表面时会溅起并消失,形成更小的水滴粒子。相反,当纸屑击中表面时,它们会弹跳和散开,而不是溅起。
将粒子物理学的这些原理融入你的 Unity 粒子系统中,将显著增强你的 XR 体验的真实感和沉浸感。你将在下一节中学习 Unity 的粒子系统。
探索 Unity 的粒子系统
Unity 的粒子系统是 XR 开发者的一项强大工具,它为用户体验增添了另一个层次的真实感。它用于创建各种特殊效果,如火焰、烟雾、火花和魔法咒语,以及更抽象的视觉元素。理解和有效利用 Unity 的粒子系统可以显著增强应用程序的视觉吸引力,并加深虚拟环境中的存在感。
以下是对 Unity 粒子系统核心组件的详细探讨——特别是粒子系统组件和粒子系统渲染器组件。这两个组件在我们向鼓场景添加粒子系统时将至关重要:
-
粒子系统组件是 Unity 中粒子系统的主引擎。粒子系统组件本身附加到一个 GameObject 上,并控制粒子在其生命周期内的生成和行为。它提供了多种模块,每个模块控制粒子行为的不同方面:
-
发射模块:此模块控制新粒子的生成速率。无论你需要粒子的持续细流还是突然爆发,此模块都能满足你的需求。
-
形状模块:此模块定义了粒子诞生的区域和形状。这可能是一个简单的点,一个复杂的网格,或者两者之间的任何东西,为你的粒子生命旅程提供了一个灵活的起点。
-
重力修改器:这是粒子系统组件中的一个设置,模拟重力对粒子的影响。你可以调整此设置以使粒子下落得更快或更慢,从而创建如漂浮灰尘或快速降雨的效果。
-
生命周期内速度模块:此模块规定粒子在其生命周期内速度和方向的变化。结合重力修改器,这可以创建出粒子被风吹或湍流捕获的逼真效果。
-
阻力:位于生命周期内力模块下,在 Unity 的粒子系统中允许用户在其生命周期内对粒子应用不同的力,这个属性让你可以模拟空气或流体阻力的效果。通过修改阻力属性,你可以使粒子移动得像在更重的介质中一样,为粒子提供重量和深度的感觉。
-
生命周期内颜色模块:此模块指定粒子在其生命周期内颜色的演变。此模块与大小生命周期模块结合使用,允许你创建自然的淡入淡出效果,增强粒子的真实感。
-
生命周期内大小模块:此模块确定粒子在其生命周期内的缩放变化。通过使粒子随时间缩小或增大,环境看起来会演变并变得对观察者来说是动态的。
-
碰撞模块:此模块控制粒子在碰撞时如何与场景中的其他 GameObject 交互。你可以控制诸如反弹(恢复力)、阻尼(速度损失)和碰撞时寿命损失等属性。这可以为粒子对其环境的反应提供高度的真实感,例如火花从表面弹跳或水滴溅起。
为了说明这些原理的应用,考虑一个简单的篝火示例。在这种情况下,从火中升起的火星可以创建为一个粒子效果,其中粒子向上移动,受到略微随机的速度影响,以模拟热量和空气阻力的效果。由于热量,重力的影响在这里将是负的(向上拉粒子),粒子在出生时可能呈现红色,随着冷却而变暗,模拟真实火星的生命周期。然而,烟雾可以通过粒子向上移动并具有更高的随机速度来创建,模拟火焰的翻滚效果。这些粒子受重力影响较小,寿命较长。它们还可以使用颜色渐变,从靠近火焰的深灰色变为上升和冷却时的浅色。最后,火焰本身可以通过高频率的小而明亮的粒子来模拟,这些粒子寿命短,随机速度高。效果将是一个生动、动态的闪烁火焰。
-
-
粒子系统渲染器组件负责在屏幕上渲染粒子。此组件可以根据您应用程序的具体视觉需求进行自定义。其一些属性包括以下内容:
-
材质:这定义了粒子的外观,可以包括纹理、颜色和着色器
-
渲染模式:这决定了粒子的渲染方式,可以是广告牌(始终面向相机)、网格或其他类似实体
-
排序模式:这决定了粒子渲染的顺序,当粒子重叠时尤为重要
-
记住,粒子不仅仅是视觉装饰。它们可以在你的叙事、玩家指导和世界构建工作中发挥关键作用。例如,一串神秘的火花可能引导玩家找到隐藏的宝藏,或者一缕烟雾可能暗示附近最近熄灭的篝火。
现在我们已经探讨了 Unity 粒子系统的关键组件,接下来让我们深入了解以下部分,该部分解释了如何将粒子系统集成到我们的鼓场景中。目标是每次我们敲击鼓时,都会释放出与敲击力度成比例的雾气。
向 VR 场景添加具有不同属性的粒子
你还记得上一次你参加现场音乐会的时候吗?在传奇歌曲的高潮部分,舞台被一层白色的雾气笼罩,而你和朋友沉浸在音乐中?从现实世界音乐会中常用的舞台烟雾中汲取灵感,我们将应用我们最近学到的 Unity 粒子系统知识来创建类似的效果。我们的目标是把粒子系统整合到我们的鼓场景中,每次敲击鼓时释放雾气,雾气的强度与敲击速度相对应。鼓敲击得越频繁,雾气应该越饱和我们的场景,反之亦然,从而完全复制在真正音乐会上的愉悦感觉。
为了实现这个目标,我们首先需要在场景中初始化一个粒子系统。
在您的 VR 鼓场景中初始化粒子系统
按照以下步骤在您的 VR 鼓场景中建立粒子系统:
-
在您的 Unity 场景中,在 Hierarchy 窗口中 右键单击,导航到 Effects,然后选择 Particle System。这将在一个新的粒子系统实例化到您的场景中。
-
现有的粒子系统使用的是 Unity 的标准粒子材质,这并不理想于创建雾效。然而,我们可以轻松地为粒子系统自定义材质。转到
Fog。 -
下载一张云或雾的透明图片。我们可以使用一张云的图片,该图片可在以下链接下载:
pixlok.com/images/clouds-png-image-free-download/。您也可以通过本章的 GitHub 文件夹访问它。将此图片拖放到您刚刚创建的Fog文件夹中。 -
在
Fog文件夹中,通过 右键单击 并选择Fog来创建一个新的材质。现在,将之前下载的图片从您的本地文件系统中拖放到材质的基础图中。接下来,在 Inspector 窗口中将材质的 Shader 字段修改为 Mobile/Particles/Alpha Blended。此设置允许粒子相互重叠并无缝融合,从而创建更逼真的雾效。 -
选择粒子系统,并将
Fog材质拖动到其 Inspector 窗口中。这将自动更新材质。因此,您的场景现在应该类似于 图 7.6 中所示的场景。

图 7.6 – 当前 Unity 场景和粒子系统检查器的 Inspector 窗口应如何看起来,以及新添加的雾效果
在成功将粒子系统添加到我们的 VR 鼓场景后,让我们稍微修改其属性,以实现更动态的雾行为,这取决于下一节中鼓和鼓棒的碰撞速度。
修改 VR 鼓场景中粒子系统的属性
让我们通过展开检查器窗口中的粒子系统来探索其属性。有一些关键属性你需要修改,以使你的 VR 鼓场景中的雾效表现得更加自然。修改后的属性可以在图 7.7中观察到。

图 7.7 – 在检查器窗口中修改后的扩展粒子系统
这些属性将在以下列表中详细解释:
-
5秒来使场景更加动态。 -
PlaySoundOnCollision脚本。 -
0。 -
5秒的生命周期应该足够了。 -
0和2。这将在这些限制内随机化每个粒子的速度,从而创建一个更加自然主义的雾效。曲线和在两个曲线之间随机是两种你也可以选择的替代选项。它们提供了对速度变化的更细致的控制,允许你定义值随时间以及特定范围内如何变化。 -
使用
(2,2,2)来在所有维度上加倍大小。 -
起始颜色:这决定了每个粒子的初始颜色。为了增强视觉效果并使我们的雾效更加动态,我们将引入一些颜色变化。点击起始颜色旁边的箭头符号,并选择在两个渐变之间随机选项。此选项允许我们定义两个颜色渐变,每个单独的粒子的颜色将随机分配到这两个渐变之间的某个值。在将选项切换到在两个渐变之间随机后,会出现两个颜色渐变预览字段。要自定义颜色渐变,你可以点击这些字段以打开渐变编辑器窗口。在渐变编辑器窗口中,你可以添加、删除或重新排列颜色标记,以达到你想要的颜色渐变。图 7.8提供了一个如何修改颜色渐变的视觉指南。

图 7.8 – 如何修改起始颜色的渐变编辑器
初始时,你可以将模式设置为混合或固定。固定模式呈现一种纯色,而混合模式则允许颜色之间的平滑过渡。然后,你可以通过简单地左键单击颜色空间上方或下方来添加多个关键帧。上方的关键帧建立 alpha 值,决定透明度,而下方的关键帧则确定颜色本身。
在窗口底部,你会看到两个现有的渐变预设,还有一个标记为新的第三个预设,它对应于我们当前正在编辑的渐变。根据你的偏好创建两个渐变预设,并将它们分配给起始颜色。在我们的例子中,我们将选择使用我们已有的两个预设(白色和彩虹渐变)。在运行时,这种配置将在我们的雾效中产生引人入胜的鲜艳和动态的色彩光谱,如图7.9所示。

图 7.9 – 选择两个预置起始颜色时的雾的视觉外观
-
0。 -
0.4。如果模拟速度调整到低于0.4的值,雾的运动将变得更慢,创造出更悠闲的外观,而高于0.4的值将使雾移动更快,赋予它更活泼的运动。 -
展开
13。13被选为达到所需粒子密度和外观的理想速率。通过保持0,我们确保粒子是根据时间单独发射的,而不是根据运动,这样我们可以精确控制发射的粒子数量。 -
在下面,将
(3,3,1)展开以创建更大的雾效果。由于粒子系统在 X 轴上的-90 度旋转,Z 轴现在指向 Y 方向,因此不需要缩放。 -
启用
30。这将逐渐使粒子褪色,增加逼真的雾效果。图 7.10提供了启用或未启用颜色随时间变化模块以及低Alpha设置时雾的外观比较。

图 7.10 – 比较启用或未启用“随时间变化颜色”模块时雾的视觉外观
尽管粒子系统提供了大量的参数可以调整,但我们讨论的这些参数对于创建逼真的雾效果最为关键。如果您想深入了解粒子系统,Unity 提供了一门短小、免费的课程,我们强烈推荐:learn.unity.com/tutorial/introduction-to-particle-systems#。
在 VR 鼓场景中通过脚本在碰撞时设置雾的外观
在设置好粒子系统后,我们需要回到PlaySoundOnCollision脚本并做一些调整。
首先,我们需要创建一个public变量,以便引用我们想要粒子从其发射的粒子系统。这个代码相对简单:
public ParticleSystem fogParticleSystem;
然后,每当鼓被击打时,我们应该调用一个方法来启用粒子系统发射粒子。我们根据鼓棒的冲击速度来确定发射粒子的数量。由于我们已经有根据鼓棒速度调整音量的OnTriggerEnter()方法,我们可以简单地将相同的逻辑应用于粒子系统。为此,我们在OnTriggerEnter()方法中的if语句中添加了三行代码:
if (velEstimator && enableVelocity)
{
float velocityMagnitude = velEstimator.GetVelocityEstimate().magnitude;
float soundVolume = Mathf.InverseLerp(minimumVelocity, maximumVelocity, velocityMagnitude);
_soundSource.PlayOneShot(soundClip, soundVolume);
// Convert the velocity to an integer representing the number of particles
int numParticles = Mathf.RoundToInt(velocityMagnitude * 10f);
// Create an EmitParams instance
ParticleSystem.EmitParams emitParams = new ParticleSystem.EmitParams();
// Emit the particles
fogParticleSystem.Emit(emitParams, numParticles);
}
else
{
_soundSource.PlayOneShot(soundClip);
}
fogParticleSystem是对我们之前设置的粒子系统 GameObject 的引用,它将通过int numParticles = Mathf.RoundToInt(velocityMagnitude * 10f);这一行将速度的大小转换为相应的粒子数量,乘以10——这是一个可以调整以适应你特定需求的任意因子。这个数字被四舍五入到最接近的整数,因为粒子发射方法需要一个整数输入。
ParticleSystem.EmitParams emitParams = new ParticleSystem.EmitParams();这一行初始化了一个EmitParams实例。这个结构可以用来在通过脚本发射粒子时改变粒子系统的特定参数。在我们的案例中,我们将使用创建的粒子系统的默认设置。
最后,fogParticleSystem.Emit(emitParams, numParticles);调用Emit()方法来立即发射定义数量的粒子。它使用之前创建的EmitParams实例和从对象的速率中计算出的粒子数量。
通过这些调整,所需的函数功能被添加。回到 Unity 编辑器中,只需通过检查器窗口将粒子系统拖放到你的鼓的PlaySoundOnCollision脚本组件中的fogParticleSystem字段即可。完成后,运行你的场景,并戴上 VR 头盔测试实现效果。注意,鼓被敲击的频率越高,雾气越能饱和场景,反之亦然。
恭喜!你现在知道如何完全复制出现在一场真实鼓手演奏的音乐会现场时的兴奋感觉!
摘要
在本章中,我们开始了一段穿越声音和粒子世界的迷人之旅,理解它们的物理属性,并深入探讨了在 Unity 场景中实现这些现实世界现象的方法,以增强 XR 体验的沉浸感。
到达本章的结尾,你现在应该不仅能够构建具有复杂交互或动画的端到端 XR 应用,而且能够舒适地通过有效地使用 Unity 的音频和粒子系统来增强这些创作,为你的 XR 场景引入额外的真实感。
本书迄今为止所涵盖的 XR 开发概念主要针对初学者到中级水平的人。然而,随着我们继续前进,我们为你准备了一些真正独特且丰富的内容。接下来的章节将进一步通过介绍这个领域的一些最显著和高级技术来提升你的 XR 开发技能,例如手势追踪、眼动和头部追踪以及多玩家功能。这些关键知识将完善你的技能集,使你成为一个更全能的 XR 开发者,并能够创建更广泛的复杂 XR 应用。
第三部分 - 高级 XR 技术:手势追踪、注视追踪和多玩家功能
恭喜您完成了从 XR 开发和 Unity 初学者到熟练掌握创建各种高级 XR 技术并具有复杂逻辑的进阶者的旅程!在我们这本书的最后一部分,我们旨在进一步提升您的技能,使您成为一名中级 XR 开发者。我们将向您介绍那些不仅在 XR 应用领域处于前沿,而且还能提升您的 XR 场景到新的直观性和娱乐水平的先进 XR 技术。
本节还将向您介绍 XR 开发生命周期的不同阶段和方面。它将为您提供基于研究的、精确的当前 XR 开发技术状态和未来趋势的概述。通过深入研究本书早期未涵盖的额外 XR 工具包和插件,我们将为您提供在完成本书后深入您所偏好的 XR 开发领域的所需知识。
本部分包含以下章节:
-
第八章, 构建高级 XR 技术
-
第九章, XR 开发中的最佳实践和未来趋势
第八章:构建高级 XR 技术
迄今为止,您已经探索了 XR 开发的各个方面,制作了适合广泛用例的沉浸式和交互式 XR 应用程序。随着您进一步掌握 XR 开发,不仅要熟练创建从基础到中级的应用程序,还要掌握提升您 XR 产品商业可行性和影响力的高级技术至关重要。
本章旨在通过实践方法使您熟悉关键的高级 XR 方法。您将深入了解手部追踪集成,使用眼动和头动进行复杂交互,并了解如何建立多人服务器以创建引人入胜的多人 XR 体验。
本章的内容可能听起来令人畏惧,但请放心——我们将全程指导您将这些复杂的 XR 策略融入各种场景。利用您在前几章中建立的稳固 XR 基础,您会发现这些高级技术比预期的更直观。
无论您拥有哪种 XR 设备,本章都承诺提供丰富的知识,所有技术都适用于不同的设置。我们将在技术要求部分深入探讨这一点。
本章包括以下部分:
-
将手部追踪添加到 XR 体验中
-
通过眼动或头动在 XR 体验中与对象交互
-
构建 VR 多人应用程序
技术要求
要导航本章中的手部追踪、眼动和多人方面,需要了解共享和独特的技术先决条件。为了获得无缝的开发体验,我们建议您熟悉所有列出的要求。尽管本章深入探讨了高级主题,并且与早期章节相比可能最初显得有些令人生畏,但您可以确信本章中的所有教程都是为简单执行而设计的——即使您手头没有 VR 头显。
首先,让我们解决整体的技术要求。为了跟随本章中的教程,您需要 Unity 2021.3 LTS 或更高版本。通过将您的硬件与 Unity 网站上描述的系统要求进行比较来验证其适用性:docs.unity3d.com/Manual/system-requirements.html。根据您的 VR 头显规格,确保您的设置支持 Windows/Linux/Mac 或 Android 构建支持。
大多数现代 VR 头显,尤其是具有内向外置摄像头追踪的头显,都集成了手部追踪功能。例如,包括 Meta Quest 系列、HTC Vive Cosmos Elite、PlayStation VR2、Pico Neo 2 Eye、Lynx-R1、Valve Index、HP Reverb G2、Varjo VR-3 以及即将发布的 Apple Vision Pro。请始终参考您 VR 头显的技术规格,以了解它是否支持手部追踪。
如果你无法访问支持手部追踪的头显,你仍然可以遵循本章,因为 XR 设备模拟器可以完美地复制 VR 头显的手部追踪功能。
虚拟现实中的眼动追踪是一个不断发展的领域,有趣的是,无论你的 VR 头显规格如何,你都可以深入了解本章眼和头部注视追踪部分的眼动追踪教程。即使你仅使用 XR 设备模拟器而没有物理 VR 头显,你也会发现我们的教程易于访问。虽然我们现在不会透露所有细节,但值得注意的是,XR 交互工具包为那些 VR 头显缺乏标准眼动追踪功能的情况提供了创新解决方案。截至本书出版时,提供眼动追踪功能的 VR 头显包括 PlayStation VR2、HP Reverb G2 Omnicept Edition、Pico Neo 3 Pro Eye、HTC Vive Pro Eye、Pico Neo 2 Eye 和 Meta Quest Pro。此外,即将推出的 Apple Vision Pro 预计也将具备眼动追踪功能。这个列表可能在你阅读本书时不会涵盖所有可用选项,所以请始终检查你的 VR 头显规格以确认是否支持眼动追踪。
现在硬件都设置好了,让我们开始使用 XR 交互工具包探索手部追踪。
为 XR 体验添加手部追踪
在本节中,你将学习如何将手部追踪功能添加到你的 XR 体验中。然而,在创建新的 Unity 项目之前,你必须了解手部追踪的技术概念以及它如何比常规控制器更丰富 XR 体验。
理解手部追踪和潜在用例
在虚拟现实中,手部追踪的核心是指直接检测、捕捉和解释用户在虚拟环境中裸手和手指的细微动作和定位的技术能力。
与基于控制器的追踪不同,后者依赖于外部设备来调解和将用户输入转换为 VR 动作,如 Xbox 控制器,手部追踪无需中介硬件,直接将现实世界的手势和动作映射到虚拟领域。这种方法利用了复杂的传感器、摄像头和算法来构建用户手的实时动态模型。从抓取物体到用手指手势施法,手部追踪提供了一系列潜在交互。它促进了复杂和细微的交互,这些交互难以用传统控制器复制,允许在 VR 中实现更自然和直观的交互。
要使 VR 头显能够利用手部追踪的潜力,它应该配备高分辨率传感器和摄像头,能够捕捉到详细的动作,包括单个手指的细微动作。这些摄像头通常需要以提供宽阔视野的方式定位,以便持续追踪手部的移动。
手部追踪需要实时解释复杂的手部和手指动作,这需要强大的处理能力。VR 头显应该有一个内置处理器或连接到一台可以无延迟处理这些计算的机器。
除了硬件之外,头显的软件必须设计或可适应以有效地识别和解释手部动作。这包括拥有能够区分有意手势和无意手部动作的算法。
在这些基础要求的基础上,下一节将指导你设置 Unity 项目,以便有效地利用和启用手部追踪,为你的 XR 体验用户提供更丰富、更沉浸式的体验。
使用 XR 交互工具包实现手部追踪
为了启动我们将手部追踪功能添加到 XR 项目的流程,我们必须执行以下步骤:
-
前往 Unity Hub,通过导航到
AdvancedXRTechniques并点击创建项目按钮来创建一个新项目。 -
在场景层次结构窗口中,你会看到你的场景只包含主相机和方向光。你可以删除主相机,因为它不是必需的。
-
导入
com.unity.xr.interaction.toolkit,然后按Enter键。工具包现在应该会自动添加到你的项目中。在包管理器窗口中,导航到新添加的XR 交互工具包包的示例选项卡,并通过点击每个旁边的导入按钮来导入入门资产、XR 设备模拟器和手部交互演示。 -
为了在我们的场景中启用手部追踪,我们不仅需要
com.unity.xr.hands,还需要按Enter键。一旦该包被添加到你的项目中,导航到包管理器窗口中XR 手部包的示例选项卡,并点击HandVisualizer示例旁边的导入按钮。 -
现在,我们通常会拖放
XR Interaction Hands Setup到0,0,0的搜索栏中。 -
是时候正确设置XR 插件管理以启用手部追踪了。导航到编辑 | 项目设置 | XR 插件管理,并根据你的 VR 头显需求,在Windows/Mac/Linux选项卡或Android上选择OpenXR复选框。
-
一旦安装了OpenXR插件,导航到左侧XR Plug-in Management标签下的子标签页。在这里,转到Windows/Mac/Linux或Android标签。点击+按钮将Interaction Profile项目添加到你的项目中。除了在新建菜单中选择你的 VR 头盔的控制器外,你还应该添加另一个名为Hands Interaction Profile的Interaction Profile。在OpenXR的核心中,Hand Interaction Profile提供了一种标准化的方式来解释不同 VR 头盔之间的手势和动作。不同的 VR 头盔可能有自己追踪手部的技术和方法。如果没有标准化的系统,开发者需要为每个头盔的手部追踪系统编写独特的代码,这可能会非常耗时且不切实际。
-
保持处于OpenXR子标签页,勾选Hand Interaction Poses和Hand Tracking Subsystem复选框,无论你使用哪种 VR 头盔。
当你勾选Hand Interaction Poses时,你是在告诉 Unity 使用由OpenXR标准定义的标准姿势或手势集。这些包括抓取(握持)、指向(瞄准)、捏合和戳击。因此,你不需要手动编写这些手势的检测代码,Unity 会根据这个标准为你完成。通过勾选Hand Tracking Subsystem复选框,Unity 使用OpenXR标准来跟踪手的位置和移动方式。这个子系统就像引擎盖下的引擎,时刻关注手部的移动。
如果你有一个 Meta Quest 设备,你还必须勾选Meta Hand Tracking Aim复选框。这个功能通过理解手的方向或瞄准,增强了现有的手部追踪,给你的 VR 应用提供了更好的用户指向感或用户可能试图交互的对象感。虽然我们的Hand Interaction Profile提供了对手部动作的基础理解,但这些复选框深入到具体的手势、实际追踪和特定设备的功能。
-
现在,让我们在场景中添加一个简单的平面作为地面,并添加一个立方体来进行交互测试手部追踪。你可以通过在层次结构中右键单击,选择
Ground Floor并将其定位在原点(0``0``0)来实现。
重复上一步,但不要选择Hand Tracking Cube。将其定位在(0, 1.25, 1),并缩放到(0.1, 0.1, 0.1)。在Hand Tracking Cube中,在搜索栏中点击XR Grab Interactable。通过双击选择XR Grab Interactable脚本。你应该能看到一个Rigidbody组件已经自动添加到InteractableCube中,与XR Grab Interactable脚本并列。在Rigidbody组件内部,确保选中了Use Gravity和Is Kinematic复选框,这样我们的与立方体的交互就可以在遵守重力定律的情况下进行。
重要提示
如果你没有访问具有手势追踪功能的 VR 头盔,你可以简单地通过使用 XR 设备模拟器来测试此功能,如第三章中的安装 XR 设备模拟器和使用 XR 设备模拟器部分所述。要切换到手势追踪模式,只需按下H键。
是时候使用你的 VR 头盔测试场景了。像平时一样启动场景。你甚至不需要手头有 VR 头盔的控制器。一旦场景开始运行,调整你的头部,使 VR 头盔上的外部摄像头指向你的手。
你应该注意到控制器视觉已经被手部视觉所取代,精确地反映了你真实手的准确位置和动作,如图图 8.1所示。

图 8.1 – 当你放下控制器并将目光转向你的手时,你将看到的视觉
尝试分别移动每个手指,转动你的手,甚至将一只手藏在背后。如果一切设置正确,并且你的 VR 头盔完全支持手势追踪,虚拟手应该能够准确模仿你的真实手部动作。如果你将一只手藏在背后,对应的虚拟手也应该消失。
最后,让我们使用仅手势追踪的方式测试场景中的立方体交互。将右手激光笔对准立方体。将右手拇指和食指指尖相触,形成一个近似的三角形形状,如图图 8.2所示。

图 8.2 – 在现实生活中,当你将右手拇指和右手食指指尖相触时的叠加手部视觉
现在,你正在抓取立方体。在保持这个位置的同时,指向各个方向,观察立方体相应地移动。
恭喜!你现在已经在你的 VR 场景中实现了与使用标准 VR 控制器相似的手势交互体验。
要探索 XR 交互工具包的手势追踪功能如何与其他类型的对象(如 UI 元素或按钮)协同工作,请深入了解手部交互演示,它位于我们最初导入的工具包的样本区域中。要访问它,请按照以下步骤操作:
-
前往项目窗口中的资产。从那里,导航到样本 | XR 交互工具包 | 版本号 | 手部交互演示 | 运行时。
-
然后,双击HandsDemoScene Unity 场景。如果你喜欢,可以使用项目窗口中的搜索栏快速定位HandsDemoScene。
-
一旦你在 Unity 编辑器中打开场景,点击播放按钮。这将让你亲身体验如何与 UI 元素互动、按按钮,甚至仅用双手操纵 3D 对象。
到现在为止,你应该感觉自己已经是一名手部追踪专家了。下一节将向你介绍 XR 开发中的另一个高级概念:眼动追踪。
通过眼动或头动在 XR 体验中与物体交互
在本节中,你不仅将了解眼动追踪本身及其如何丰富你的 XR 体验,你还将实现眼动追踪功能到你的 XR 体验中,无论你的 VR 头盔是否支持眼动追踪。
理解眼动追踪及其潜在应用场景
从读取人的意图到增强数字交互,眼动技术正在改变各种技术感知和解释人类行为的方式。
由于眼睛能够表达和传达情绪、意图和注意力,它们通常被称为“灵魂之窗”。从生物学的角度来看,眼睛的几个关键方面对此有所贡献:
-
瞳孔扩张:通常是一种无意识的反应,瞳孔可以根据情绪状态、注意力水平或对刺激的反应而扩张或收缩。例如,当看到吸引他们的人时,某人的瞳孔可能会扩张,而在暴露在明亮光线中时可能会收缩。
-
眼跳:这些是在眼球从一个点转向另一个点时发生的快速、突然的运动。我们往往没有注意到眼跳,但它在我们从周围环境中收集视觉信息方面起着关键作用。
-
眨眼和微表情:眨眼的频率可以表明各种状态,从放松到压力。此外,眼睛周围的微妙动作可以透露瞬间的情绪——这些被称为微表情。
眼动技术围绕监测和记录眼球运动和注视点展开。以下是它通常的工作原理:
-
光源:红外光指向眼睛。这种光从角膜和视网膜反射。
-
传感器和摄像头:这些检测眼睛反射的光。先进的系统可能会使用来自不同角度的多个摄像头来捕捉眼睛运动的立体视图。
-
数据处理:传感器捕获的原始数据通过算法处理,以推断注视方向和焦点点。
-
表示:注视数据通常以热图或注视图的形式表示在观察介质上,无论是计算机屏幕还是物理环境。
眼动技术通过使虚拟交互更接近人类行为,弥合了数字世界和现实世界之间的差距。当 XR 中的社交虚拟形象通过眨眼、注视和展示情绪来模仿真实的眼球运动时,它加深了用户的临场感和沉浸感。
同样,眼动追踪可以极大地提高 XR 空间中对用户意图的理解。这意味着 XR 环境可以实时适应用户的焦点。例如,一个恐怖游戏只有在用户看向正确的方向时才会触发惊吓,从而最大化情感冲击。通过分析用户注视的位置、频率和持续时间,开发者可以获取有价值的见解。这可以指导设计选择,确保重要元素吸引注意力,并优化用户界面。
眼动追踪为更直观的用户界面铺平了道路。例如,用户无需使用笨拙的手控制器在菜单中导航,只需凝视菜单选项即可选择它。
幸运的是,无论您的 VR 头盔是否支持眼动追踪,您都可以通过眼动追踪来丰富您的 XR 场景。如果这激发了您的兴趣,请跟随下一节的教程。
设置 XR 场景以支持眼动和头动追踪
XR 交互工具包支持眼动和头动追踪,增强 XR 应用的用户参与度。虽然眼动追踪专门捕捉用户的目光焦点,但头动追踪确定用户头部指向或注视的方向。让我们通过回顾我们在上一会话中创建的基本 VR 场景来亲自尝试这些追踪技术。
XR 交互工具包的眼动和头动追踪功能的关键组件已经包含在我们的场景中。要观察它们,请在项目的场景层次结构窗口中点击XR Interaction Hands Setup预制件旁边的箭头按钮,以查看其子项。导航到XR Origin (XR Rig) | Camera Offset并启用XR Gaze Interactor和Gaze Stabilized预制件。这些预制件不仅是XR Interaction Hands Setup预制件的一部分,也是XR Interaction Setup预制件的一部分,如果您不包含手部追踪,您将在场景中使用它。
这些预制件与所有类型的 VR 头盔一起工作,无论它们是否支持眼动追踪。如果您的头戴式设备不支持眼动追踪,它将使用 VR 头戴式设备的内置头动追踪功能来估计头部注视。
虽然将眼动和头动追踪纳入我们的场景是一个重要的进步,但这只是 XR 中构建直观的基于注视交互方程的一部分。如果事情这么简单,那么就没有必要写这一章了,尤其是考虑到我们在本书中的每个 VR 场景都使用了这个预制件。要真正利用眼动追踪的能力,我们还必须在场景中添加可以与XR Gaze Interactor预制件交互的对象。让我们创建这些对象:
-
为了保持我们的场景井然有序,在“眼动追踪和手部追踪交互”中的
Hand Tracking Cube上右键单击。这个 GameObject 将存储两个额外的立方体,使我们能够创建与已创建的立方体不同的眼动追踪交互。 -
让我们把所有的立方体都放在一个非常简单的桌子上。通过点击
Table创建桌子,将其定位在(0,0.5,0),并将其缩放到(3,1,1)。 -
将
Hand Tracking Cube缩放到(0.5,0.5,0.5),并通过将值更改为(-1,0,0)将其放置在Table上。同时,确保你取消选中Hand Tracking Cube并选择Hand Tracking Cube。将两个立方体重命名为Eye Tracking Cube 1和Eye Tracking Cube 2。将Eye Tracking Cube 1的位置更改为(0,0,0),将Eye Tracking Cube 2的位置更改为(1,0,0)。 -
接下来,让我们添加一个功能,当用户的注视点指向
Eye Tracking Cube 1时,在其上方会出现一个球体。我们可以通过在0、1、0)中选择Eye Tracking Cube 1并将它缩放到(0.5,0.5,0.5)来向场景中添加一个球体。 -
与
Eye Tracking Cube 1类似,当我们的 VR 场景的用户看向Eye Tracking Cube 2时,应该出现一些文本。为了使交互更加复杂,文本应根据用户是否看向立方体以及是否通过控制器按钮按下选择或取消选择立方体而改变。为了创建所需的 UI 元素,在Eye Tracking Cube 2的0、-1、-1.01)上右键单击并选择其1。现在,在Interactable Text中的No state detected!上右键单击,将其所有方向上的缩放设置为0.005,并将其定位在(0.1,0.1,0)。 -
让我们在场景中添加一些彩色材料,使其更具视觉吸引力。具体来说,我们想要为我们的立方体添加两种材料——一种用于它们的默认外观,另一种用于它们被悬停时。因此,我们将为
Table创建一个材料,并为Materials创建一个材料,然后双击它以打开它。通过右键单击,选择HighlightedCube在Materials文件夹内创建一个新的材料。在HighlightedCube中,点击旁边带有240、G:240、B:140的彩色单元格,并设置70。 -
在
Materials文件夹内右键单击并选择CubeMaterial、TableMaterial和SphereMaterial材料。对于CubeMaterial,我们选择了一种复杂的红色(R:186、G:6、B:6);TableMaterial已被分配了一种深棕色(R:58、G:40、B:3);而对于SphereMaterial,我们选择了一种蓝色(R:29、G:120、B:241)并通过设置1使其看起来像金属。所有这些材料都有255。通过简单地从TableMaterial和SphereMaterial拖放材料,将CubeMaterial应用到场景中的所有三个立方体上。
图 8**.3显示了你的 VR 场景当前应该看起来是什么样子。

图 8.3 – 眼睛追踪的 VR 场景当前状态
在下一节中,你将学习如何通过眼神或头部注视与这些立方体进行交互。
使用 XR 交互工具包通过眼神和头部注视与对象交互
当用户注视我们为注视跟踪创建的两个立方体之一时,他们应该能够像上一节所述那样与之交互。为了实现这一点,我们需要调整场景中的某些组件。
XR Gaze Interactor 预制件只会与场景中具有 XR Simple Interactable 或 XR Grab Interactable 脚本的对象交互,并且相应的脚本启用了 Allow Gaze Interaction 复选框。这意味着我们必须将这两个脚本之一添加到我们的两个新立方体上。
在我们的情况下,我们将为每个眼动立方体添加 XR Simple Interactable 脚本。为了实现这一点,我们需要执行以下三个步骤:
-
按 Ctrl/Cmd 并在 Scene Hierarchy 窗口中选择两个立方体。
-
将
XR Simple Interactable点击到搜索栏中,然后双击脚本将其添加到两个立方体上。 -
点击
XR Simple Interactable脚本组件旁边的 Gaze Configuration 属性旁边的箭头以打开与注视相关的属性。选择 Allow Gaze Interaction 复选框。
现在,我们需要指定如何通过注视与我们的两个立方体交互。让我们从第一个立方体开始。记住,我们的目标是只有当我们的眼睛、头部或控制器指向它时,蓝色球体才出现在第一个立方体的顶部。我们可以通过以下步骤将此逻辑添加到立方体中:
-
在
Eye Tracking Cube 1中,导航到 XR Simple Interactable 脚本组件的末尾。点击 Interactable Events 旁边的箭头以打开它。通过点击 + 按钮两次,向 First/Last Hover 的 First Hover Entered 函数添加两个新事件。 -
让我们填写我们新创建的交互事件的缺失信息。根据 Scene Hierarchy 窗口中的
Eye Tracking Cube 1将其指示到第一个 None (Object) 单元格。通过将第二个事件分配给 Sphere 重复此操作。 -
要在通过控制器、眼睛或头部悬停在
Eye Tracking Cube 1上时更改其材质,我们必须为每个交互事件分配必要的函数并提供所需的参数。通过搜索栏选择HighlightedCube材质并选择它。对于使用控制器、眼睛或头部悬停在Eye Tracking Cube 1上的情况,你将看到蓝色球体出现在其顶部。 -
一旦你的控制器、眼睛或头部不再指向
Eye Tracking Cube 1,立方体的材质应恢复到默认颜色,球体应消失。为了实现这一点,转到Eye Tracking Cube 1和CubeMaterial,并选择它。通过将 GameObject | SetActive (bool) 函数分配给 Sphere 重复此过程,并确保这次新出现的复选框未勾选。 -
为了评估我们迄今为止放置的逻辑,有必要在我们的场景中禁用或隐藏蓝色的球体对象。这确保了当用户首次进入场景时,看不到它。你可以通过在场景层次结构窗口中选择球体,然后在检查器窗口顶部取消选中其名称旁边的复选框来实现这一点。
哇哦——我们已经完成了所有必要的步骤,为我们的第一个立方体添加了强大的眼动追踪功能。图 8.4显示了当你将眼睛或头部指向立方体时,立方体应该看起来是什么样子。

图 8.4 – 由于你的眼睛或头部在立方体上方悬停,因此出现了高亮的立方体和蓝色球体
如果你正在使用头部注视功能,当你戴着 VR 头盔或使用 XR 设备模拟器时,只有当立方体位于你当前视野的中心时,你才会看到蓝色的球体。当你控制器指向立方体时,你也可以观察到相同的效果。
我们将为第二个立方体添加更强大的交互功能。与第一个立方体一样,当眼睛、头部或控制器指向第二个立方体时,会在其下方出现一个文本元素。然而,这次显示的文本本身将根据是否使用眼睛、头部和控制器交互悬停、选择或取消选择立方体而改变。按照以下步骤完成此目标:
-
使用以下修改重复为
Eye Tracking Cube 1执行的步骤:将Eye Tracking Cube 2和画布拖放到First Hover Entered函数和Last Hover Exited函数的两个事件中。 -
到目前为止,当立方体被悬停时,立方体的颜色会改变,文本元素也会变得可见。然而,文本本身也应该从
Hovered变为新出现的空白文本单元格中的Interactable Text。 -
当你悬停在立方体上方并通过按下控制器按钮(通常用于移动物体)选择立方体时,立方体下方的文本应该改变。要实现这个逻辑,请滚动到
Selected中的Interactable Text元素,并将其拖放到空白的文本字段中。 -
当立方体不再通过控制器选择时,文本应该再次改变。这可以通过向
Interactable Text添加一个新事件到Deselected并拖放到新创建的文本单元格中来实现。 -
在测试第二个立方体的逻辑之前,通过在检查器窗口中取消选中它,就像对第一个立方体所做的那样,在场景中隐藏它。
是时候尝试与这个立方体进行交互了。图 8.5显示了立方体的三种交互状态——悬停、悬停并选择,以及悬停但取消选择。

图 8.5 – 立方体的三种可交互状态
欢呼——你已经成功地为场景添加了不同的眼动交互!在下一节中,你将学习如何在 Unity 中设置多人 XR 游戏。
构建 VR 多人游戏应用
在本节中,你将构建你的第一个 VR 多人游戏应用。尽管这涉及到相当数量的 C#编程,但你已经获得了足够的知识来顺利地导航这个教程。但在我们深入之前,让我们暂停一下,深入探讨构建多人游戏应用的细微差别、必要组件以及 XR 环境中多人体验的吸引力。
理解多人应用和多人网络系统
在本质上,多人体验允许多个用户同时在一个共享的数字环境中交互。这个环境可以从简单的基于文本的界面到复杂的虚拟现实。多人体验的关键组件通常包括托管游戏环境的服务器、处理数据同步和通信的网络系统、玩家化身以及管理交互规则的游戏逻辑。
将多人模式添加到游戏中可以使游戏更具不可预测性,因为人类的行为和决策。相比之下,单人模式通常更加可控,并且可以围绕预定义的叙事来设计。
通过将多人功能添加到 XR 中,用户被鼓励共同参与任务、挑战或体验,使环境感觉更加生动和动态。例如,包括合作解谜、虚拟团队建设练习和联合探索。
重要提示
如果你认真考虑成为一名 XR 开发者,你应该感到舒适地创建多人 XR 体验。在 VR Chat 等论坛上的虚拟聚会是目前最受欢迎的 XR 应用之一。这些聚会凸显了人们希望在虚拟世界中与其他真实人类聚会的愿望,而不是仅仅被虚拟资产所包围。
任何多人游戏中最关键的部分是多人网络系统。本质上,多人网络系统是数字骨架,使得各种玩家能够在共享环境中无缝交互。该系统确保一个玩家执行的动作能够被其他所有玩家准确且一致地反映出来,从而创造出一个和谐的虚拟体验。
每个多人网络系统的关键组件是服务器。这些是强大的计算机,它们托管游戏的数字环境。它们是玩家连接的中心点,并维护游戏的主权状态。在某些配置中,一个玩家可能充当服务器,称为对等网络,但在大型游戏中,由于稳定性和可扩展性,专用服务器更为常见。
玩家使用的单个设备或计算机被称为客户端系统。它们将玩家动作或行为等数据发送到服务器,并接收有关游戏世界和其他玩家的更新。
在实时游戏中,即使是微小的延迟也可能影响游戏体验。多人网络系统使用诸如延迟补偿等技术,以确保玩家拥有流畅的体验。这涉及到预测动作或行为,然后在实际数据到达后进行协调。
为了避免多人游戏成为作弊或黑客的目标,网络系统采用诸如数据加密、权威服务器和作弊检测工具等措施。
除了游戏本身之外,玩家经常希望进行沟通,无论是通过文本、语音还是其他媒介。网络系统为这些交互提供了基础设施,确保实时且清晰的沟通。
下面是三个对 Unity 开发者来说有趣的主要多人网络提供商的概述:
-
Photon Unity Networking (PUN): PUN 是为 Unity 多人游戏量身定制的解决方案。其基于云的方法意味着开发者无需担心服务器的创建或维护。PUN 提供免费层。尽管它附带某些限制,但免费版本被许多刚开始多人游戏开发旅程的独立游戏开发者和小型项目爱好者广泛使用。
-
镜面反射: 镜面反射提供了一款由社区驱动的开源网络工具,专为 Unity 量身定制。它是已废弃的 Unity 网络系统的进化版本。作为开源软件,它不收取许可费用,这使得它成为一个经济实惠的选择。镜面反射因其灵活性而闻名,为开发者提供了对其多人游戏逻辑的更高控制度。然而,其可定制性意味着对于初学者来说,学习曲线稍微有些挑战。
-
网络代码: 网络代码是 Unity 的专有游戏网络解决方案,之前被称为MLAPI。这一演变和品牌重塑标志着 Unity 对持续改进的承诺,以及其致力于为开发者提供顶级多人游戏开发工具的奉献。作为 Unity 的内在解决方案,网络代码承诺与 Unity 生态系统无缝集成。
在接下来的章节中,我们将创建自己的多人游戏。为此,我们将利用 Photon PUN 2 的免费层。其零成本障碍,加上对初学者直观的设置过程,使其成为快速原型设计和较小规模项目的理想选择。
下一节将教授您如何为即将创建的 VR 多人游戏设置 PUN。
为我们的 VR 多人游戏设置 PUN
我们这个 VR 多人游戏的目的是既简单又稳健,涵盖了多人体验所需的所有基本元素。我们的目标是设计一个 VR 场景,其中多个用户可以同时加入。用户应该通过由头部和两个控制器组件组成的化身看到自己和他人。他们应该实时观察在这个共享空间中他人的动作,观察他们如何操纵或旋转控制器。此外,通过手部动画,他们应该能够辨别出他人何时按下他们的手。
在我们将 Photon PUN 2 导入项目之前,让我们为这一章节的这一部分创建一个新的场景。按照以下步骤开始:
-
打开我们在本章前几节中创建的
AdvancedXRTechniques项目。通过导航到 文件 | 另存为 并输入您选择的场景名称,例如HandAndEyeTrackingScene来保存当前场景。 -
前往
MultiplayerScene。 -
在您新场景的 Unity 编辑器中,通过搜索栏删除
XR Interaction Setup(位置为0,0,0)。
现在我们已经设置了场景,按照以下步骤安装和设置我们的网络系统,PUN:
-
我们可以通过 Unity Asset Store 安装 PUN,就像安装其他包一样。访问
assetstore.unity.com/packages/tools/network/pun-2-free-119922或在 Unity Asset Store 中搜索PUN 2 – FREE(窗口 | 资产商店)。点击添加到我的资产按钮将包添加到您的资产中。一旦包被添加,Asset Store 网站上会出现一个名为在 Unity 中打开的新按钮。点击它以在项目的包管理器窗口中打开包。按下下载和导入按钮将资产导入到您的项目中。 -
在 图 8.6 中显示的PUN 向导窗口将在 Unity 编辑器中弹出。

图 8.6 – PUN 向导弹出窗口
如果您已经有了 Photon 账户,您可以直接在这里输入您的AppId。否则,完成输入您的电子邮件并点击设置项目按钮。这将创建一个账户并将您转发到一个网页,您可以在那里设置您的密码。
重要提示
如果您意外关闭了这个弹出窗口,只需前往 www.photonengine.com/ 并在那里注册。
- 一旦您登录到您的账户,前往
dashboard.photonengine.com/并点击创建新应用按钮。您将被转发到 图 8.7 中显示的页面。

图 8.7 – 在 Photon 网站上创建新应用后将被转发的网页
- 选择
我的第一个多人游戏。点击创建按钮 – 注意您在仪表板中新建的应用程序。如图图 8**.8所示,您可以在仪表板的布局元素之一中找到您的 Photon App ID。将其复制以稍后连接到服务器。

图 8.8 – 包含您的 App ID 的仪表板元素
- 返回到您的 Unity 项目。如果您仍然看到PUN 向导窗口,您可以直接将其中的App Id粘贴进去,然后点击设置项目按钮。或者,您可以直接在Photon 服务器设置中输入您的App Id,方法是导航到窗口 | Photon Unity Networking | 高亮服务器设置,如图图 8**.9所示。

图 8.9 – 如何在 Unity 中将 App Id 添加到 Photon 服务器设置中
现在,是时候将我们的 Unity 项目连接到服务器了。下一节将向您展示如何做到这一点。
通过网络管理器连接到服务器
要将我们的 Unity 项目连接到 PUN 服务器,我们必须在我们的场景中添加一个新的 GameObject,并关联一个 C#脚本。让我们一步一步地完成这个过程:
-
通过在
网络管理器中右键单击来创建一个新的空 GameObject。 -
现在,我们想要添加一个脚本到这个 GameObject,我们可以使用它来连接到 PUN 服务器并检查是否有人加入了服务器。要创建这个脚本,导航到
网络管理器并点击添加 组件按钮。 -
搜索
NetworkManager,选择新建脚本选项,然后按创建并添加按钮来创建一个名为NetworkManager.cs的 C#脚本,该脚本将自动添加到NetworkManager作为组件。双击脚本以在您首选的 IDE 中打开它。 -
NetworkManager脚本作为在 VR 多人应用程序中使用 PUN 框架启动和管理网络交互的基础元素。删除NetworkManager脚本中当前的所有内容,以便您可以从一个干净的基础开始。
让我们通过导入以下库来开始添加我们的代码逻辑:
using UnityEngine;
using Photon.Pun;
using Photon.Realtime;
Photon.Pun和Photon.Realtime库对于任何 PUN 应用程序都是至关重要的,因为它们提供了访问核心多人网络功能的能力。
接下来,让我们定义NetworkManager类和一些重要的常量:
public class NetworkManager : MonoBehaviourPunCallbacks
{
private const string ROOM_NAME = "Multiplayer Room";
private const byte MAX_PLAYERS = 5;
}
NetworkManager类继承自MonoBehaviourPunCallbacks。这种继承意味着它不仅仅是一个标准的 Unity 脚本(MonoBehaviour),而且它还拥有 PUN 提供的特殊回调函数,这些函数会通知我们的脚本各种网络事件。
虽然ROOM_NAME代表玩家将加入或创建的房间名称,但MAX_PLAYERS定义了房间中允许的最大玩家数,在这个例子中是5名玩家。我们稍后需要在脚本中使用这两个常量。
让我们继续,将我们的应用程序连接到 Photon 服务器:
private void Awake()
{
InitiateServerConnection();
}
private void InitiateServerConnection()
{
if (!PhotonNetwork.IsConnected)
{
PhotonNetwork.ConnectUsingSettings();
Debug.Log("Attempting server connection...");
}
}
一旦调用Awake()方法,它将通过调用InitiateServerConnection()方法来启动与 PUN 服务器的连接。如果客户端尚未连接到 Photon,InitiateServerConnection()方法将尝试使用我们之前插入的App Id值连接到服务器空间。请参阅*图 8**.9,以防您错过了这一步。此方法的第二行通过调试消息记录了我们的尝试。
如果连接尝试成功,以下方法将被执行:
public override void OnConnectedToMaster()
{
base.OnConnectedToMaster();
Debug.Log("Connected to Master Server.");
JoinOrCreateGameRoom();
}
此方法是对 Photon 的OnConnectedToMaster回调的重写。一旦应用程序成功连接到 Photon 主服务器,它就会被触发。此方法是 PUN 框架的一个组成部分,允许我们在成功连接后执行特定的逻辑。在此方法内部,我们记录了成功连接到主服务器。我们还调用了JoinOrCreateGameRoom()方法,它使用了我们在脚本开头定义的常量:
private void JoinOrCreateGameRoom()
{
RoomOptions options = new RoomOptions
{
MaxPlayers = MAX_PLAYERS,
IsVisible = true,
IsOpen = true
};
PhotonNetwork.JoinOrCreateRoom(ROOM_NAME, options, TypedLobby.Default);
}
在此方法的最后一行,客户端尝试加入或创建一个名为多人房间的房间,房间内最多允许五名玩家。如果房间不存在,它将使用提供的选项创建一个。
我们代码中的下一个方法是重写:
public override void OnJoinedRoom()
{
base.OnJoinedRoom();
Debug.Log("Successfully joined a room.");
}
此方法是对 Photon 的OnJoinedRoom回调的重写。当客户端成功加入房间时,它会被触发。在最后一行,打印了一条调试消息以确认成功进入房间。
为了管理新玩家,我们可以使用以下方法:
public override void OnPlayerEnteredRoom(Player newParticipant)
{
base.OnPlayerEnteredRoom(newParticipant);
Debug.Log("Another player has joined the room.");
}
此OnPlayerEnteredRoom()方法也是对 Photon 的OnPlayerEnteredRoom回调的重写。每当有新玩家进入房间时,它就会被调用。同样,在最后一行打印了一条调试消息,通知另一个玩家已加入。
欢呼,您已经将所有必要的组件实现到了NetworkManager脚本中!正如您所看到的,它提供了一个连接到 Photon 服务器、管理多人房间以及在 VR 环境中处理玩家交互的基础结构。让我们看看我们的代码逻辑是否工作。在下一节中,您将了解到如何在单个设备上测试多人应用程序。
从一个设备测试多人场景
要从单个设备测试多人场景,我们需要运行场景两次。这可以通过首先在计算机上构建和运行场景,然后从编辑器内部启动它来实现。以下是逐步分解:
-
在 Unity 编辑器中,转到文件 | 构建设置并选择Windows/ Mac/ Linux选项卡。添加您想要测试的打开场景,点击构建按钮,并为即将构建的可执行文件选择一个文件夹。
-
文件构建完成后,点击 Unity 编辑器中的播放按钮以启动场景。
-
现在,打开您刚刚构建的可执行文件。
-
前往 Unity 编辑器的 控制台 窗口并检查 调试 语句。如果你一切都做得正确,你将看到我们在脚本中之前定义的调试线条,如图 8.10 所示。

图 8.10 – 如果一切按预期工作,你应该看到的调试线条
为了确保我们的场景功能最优,我们必须彻底测试其 VR 功能。根据我们的评估,场景导航流畅,头戴式设备和控制器都被准确追踪和定位。目前,我们的场景在初始玩家激活时立即建立服务器连接,并且我们已经设置了检测新玩家进入的方法。
然而,我们的 XR 交互设置 并非完全适合多人操作。它在管理移动和交互方面表现出色,但并没有为不同身体部位提供动画模型。简单来说,如果有人此时进入我们的多人场景,他们可能只能看到控制器。更糟糕的是,他们可能检测不到我们化身的一部分,因为控制器模型没有网络意识。这意味着当前场景中的对象没有在会话中的所有玩家之间同步。但别担心,我们将在下一节中解决这个问题。
使用脚本显示我们的化身的手和脸
我们下一个目标是当化身连接到服务器时显示其手和脸。为了实现这一点,让我们在点击 NetworkPlayerPlacer 后选择 Network Manager 并在 NetworkPlayerPlacer 中添加一个新的脚本。通过双击打开脚本。
管理玩家存在
我们即将深入探讨的 NetworkPlayerPlacer 脚本专门用于监控玩家存在,这是多人虚拟现实应用的核心元素。具体来说,这意味着创建和删除玩家化身或其在游戏中的表示。NetworkPlayerPlacer 脚本专门为此角色定制。它从以下声明开始:
using UnityEngine;
using Photon.Pun;
public class NetworkPlayerPlacer : MonoBehaviourPunCallbacks
{
private GameObject playerInstance;
private const string PLAYER_PREFAB_NAME = "Network Player";
}
导入语句和类声明与 NetworkManager 脚本中的非常相似。这两个类都继承自 MonoBehaviourPunCallbacks。playerInstance 作为场景中实例化玩家对象的引用。同时,PLAYER_PREFAB_NAME 是一个常量字符串,它保存了为实例化设置的玩家预制件的名称。预计这个预制件已在 Photon 资源目录中注册并可访问。
让我们创建 NetworkPlayerPlacer 脚本的第一个方法:
public override void OnJoinedRoom()
{
base.OnJoinedRoom();
SpawnPlayer();
}
OnJoinedRoom() 方法覆盖了 Photon 的 OnJoinedRoom 回调,当本地玩家成功加入房间时会被触发。
使用 base.OnJoinedRoom() 调用 OnJoinedRoom 的基类实现。在最后一行,调用了 SpawnPlayer() 方法,其外观如下:
private void SpawnPlayer()
{
playerInstance = PhotonNetwork.Instantiate(PLAYER_PREFAB_NAME, transform.position, transform.rotation);
}
此方法使用 Photon 的网络实例化方法创建一个新的玩家对象。新玩家将在NetworkPlayerPlacer对象的位置和旋转处生成。这确保了玩家对象在网络上是网络化的,并且在房间中的所有客户端上都是同步的。
我们脚本中的下一个方法覆盖了 Photon 的OnLeftRoom回调,当本地玩家离开房间时调用:
public override void OnLeftRoom()
{
base.OnLeftRoom();
DespawnPlayer();
}
OnLeftRoom()方法包含两个调用:一个是对OnLeftRoom基类实现的调用,另一个是对DespawnPlayer()的调用,这是一个销毁玩家的方法。让我们看看DespawnPlayer()方法:
private void DespawnPlayer()
{
if (playerInstance)
{
PhotonNetwork.Destroy(playerInstance);
}
}
此方法处理玩家对象的销毁。
if语句检查playerInstance引用是否不为空。如果是这样,则存在玩家对象。PhotonNetwork.Destroy(playerInstance);这一行销毁了网络玩家对象。这将确保对象不仅在本地上被移除,而且在所有客户端上都被移除。
从本质上讲,NetworkPlayerSpawner脚本,通过其两个关键回调函数OnJoinedRoom()和OnLeftRoom(),无缝地处理了玩家在 VR 多人空间中的出现和消失,补充了NetworkManager脚本提供的功能。
创建面部和双手
之前,我们提到脚本预期一个名为Resources的预制件。Unity 在通过名称引用对象时使用此默认命名约定。要创建所需的文件夹,请点击Resources。
接下来,我们需要创建代表我们角色的网络玩家预制件。按照以下步骤完成此操作:
-
在
网络玩家上右键点击。 -
通过按下添加组件按钮并在检查器窗口中搜索它,将光子视图组件添加到其中。光子需要此组件在服务器上实例化玩家。如果没有它,系统将无法识别所有权或准确同步玩家的身体部位。
-
通过在
Head、左手和右手中选择Network Player,将其他三个空 GameObject 作为子对象添加到Network Player中。 -
现在,我们需要创建 3D 对象来表示我们角色的三个组成部分。对于
Head,我们可以在Head中使用一个简单的Head并将其缩放到(0.1,0.1,0.1) -
我们也可以为我们的角色双手使用原始形状。然而,由于互联网上有许多可用的动画手模型,我们可以简单地使用其中之一。对于这个项目,我们使用了 Unity 资产商店上的Oculus 双手示例,该示例来自Oculus 集成包(
assetstore.unity.com/packages/tools/integration/oculus-integration-82022)。然而,我们建议直接从这本书的 GitHub 仓库克隆双手。这避免了由于Oculus 集成包频繁更新而导致的额外内容和不必要的资产丢失。 -
现在,在
Scene Hierarchy窗口中,不再需要选择Resources文件夹中的Network Player,可以将其删除。
我们必须在Network Manager中添加另一个脚本,以确保Head、Left Hand和Right Hand组件跟随用户头戴式设备和控制器的位置。为此,在NetworkPlayer中选择Network Manager并输入到搜索栏中,然后创建一个具有此名称的新脚本。
现在我们已经创建了脚本,让我们学习如何使用它来跟踪玩家的位置和移动。
跟踪玩家位置和移动
NetworkPlayer脚本控制玩家在多玩家 VR 环境中的移动跟踪和表示。该脚本封装了确保角色头部、左手和右手的准确跟踪和更新的功能。
让我们看看这个脚本的开始部分:
using UnityEngine;
using UnityEngine.XR;
using Photon.Pun;
using UnityEngine.InputSystem;
public class NetworkPlayer : MonoBehaviour
{
public Transform head;
public Transform leftHand;
public Transform rightHand;
private PhotonView photonView;
public InputActionAsset xriInputActions;
private InputActionMap headActionMap;
private InputActionMap leftHandActionMap;
private InputActionMap rightHandActionMap;
private InputAction headPositionAction;
private InputAction headRotationAction;
private InputAction leftHandPositionAction;
private InputAction leftHandRotationAction;
private InputAction rightHandPositionAction;
private InputAction rightHandRotationAction;
}
除了导入常规的 Unity 和 PUN 命名空间外,还声明了一个名为NetworkPlayer的类,该类继承自MonoBehaviour。Transform变量,如head、leftHand和rightHand,代表玩家在游戏中的 VR 角色组件的 3D 位置、旋转和缩放。PhotonView组件对于 PUN 至关重要,它决定了多玩家游戏中对象的拥有权和同步。InputActionAsset,称为xriInputActions,是 Unity 配置的一组针对 VR 头戴式设备的输入定义。InputActionMap变量,例如headActionMap,将相关的输入动作分组,以便有组织地处理如头部或手部动作等输入。最后,InputAction变量,如headPositionAction和headRotationAction,检测来自 VR 头戴式设备的单个输入动作。为了同步玩家的现实世界 VR 动作与其游戏中的角色,我们需要在脚本中实现方法。让我们从第一个方法开始:
void Start()
{
photonView = GetComponent<PhotonView>();
// Get the Action Maps
headActionMap = xriInputActions.FindActionMap("XRI Head");
leftHandActionMap = xriInputActions.FindActionMap("XRI LeftHand");
rightHandActionMap = xriInputActions.FindActionMap("XRI RightHand");
// Get the Position and Rotation actions for each action map
headPositionAction = headActionMap.FindAction("Position");
headRotationAction = headActionMap.FindAction("Rotation");
leftHandPositionAction = leftHandActionMap.FindAction("Position");
leftHandRotationAction = leftHandActionMap.FindAction("Rotation");
rightHandPositionAction = rightHandActionMap.FindAction("Position");
rightHandRotationAction = rightHandActionMap.FindAction("Rotation");
// Enable actions
headPositionAction.Enable();
headRotationAction.Enable();
leftHandPositionAction.Enable();
leftHandRotationAction.Enable();
rightHandPositionAction.Enable();
rightHandRotationAction.Enable();
}
在Start()方法中,初始化photonView。然后,使用它们的名称检索头部、左手和右手的动作图。这些名称(XRI Head、XRI LeftHand和XRI RightHand)在头部的Position和Rotation动作以及每个手的动作中是预定义的。最后,启用所有这些动作,以便它们开始读取输入值。
我们脚本中的下一个方法是Update()方法:
void Update()
{
if (photonView.IsMine)
{
rightHand.gameObject.SetActive(false);
leftHand.gameObject.SetActive(false);
head.gameObject.SetActive(false);
MapPosition(head, XRNode.Head);
MapPosition(leftHand, XRNode.LeftHand);
MapPosition(rightHand, XRNode.RightHand);
}
}
在一个由光子驱动的多人游戏环境中,将出现许多 NetworkPlayer 实例,代表游戏中的每个玩家。然而,在每个玩家的设备上,只有一个实例真正代表该特定玩家,其余的则表示远程玩家。在 Update() 方法的 if 语句中检查 photonView.IsMine 属性,可以确定给定机器上的 NetworkPlayer 实例是否对应于使用该机器的玩家。这种区分在多人场景中至关重要,用于识别谁控制某些活动或决策。如果返回值为 true,则表示该 NetworkPlayer 实例属于该设备的本地玩家。因此,该玩家头部和手部的视觉表示被禁用,确保用户体验的流畅性。
在我们的多人场景中,存在两个主要玩家:我们的本地玩家(通过 Network Player)。这个远程玩家对所有其他多人环境中的参与者都是可见的。由于本地玩家已经有了手部模型,引入远程玩家的额外手部模型可能会导致令人困惑的体验,尤其是在网络更新延迟的情况下,如 图 8.11 所示。11*。

图 8.11 – 当未实现 SetActive(false) 语句时会发生什么
因此,我们确保 Network Player 的元素对用户不可见。相反,如果属性返回 false,则表示该实例代表从该设备看到的另一个参与者。最后,if 语句还使用 MapPosition() 方法根据 VR 头盔或 VR 控制器的移动更新手部和头部位置和旋转。
现在,让我们看看 MapPosition() 方法:
void MapPosition(Transform target, XRNode node)
{
Vector3 position = Vector3.zero;
Quaternion rotation = Quaternion.identity;
if (node == XRNode.Head)
{
position = headPositionAction.ReadValue<Vector3>();
rotation = headRotationAction.ReadValue<Quaternion>();
}
else if (node == XRNode.LeftHand)
{
position = leftHandPositionAction.ReadValue<Vector3>();
rotation = leftHandRotationAction.ReadValue<Quaternion>();
}
else if (node == XRNode.RightHand)
{
position = rightHandPositionAction.ReadValue<Vector3>();
rotation = rightHandRotationAction.ReadValue<Quaternion>();
}
target.position = position;
target.rotation = rotation;
}
MapPosition() 方法的目的是为传入的 if 语句分配正确的位置和旋转,并读取相应的输入值。例如,如果节点是 XRNode.Head,它分别从 headPositionAction 和 headRotationAction 读取位置和旋转值。这些 InputAction 变量在每一帧从 VR 头盔获取最新的位置和旋转值。最后,MapPosition() 方法将获取到的位置和旋转分配给传入的目标变换。
从本质上讲,此方法确保玩家在游戏中的表示与他们在现实世界中的 VR 移动同步。
此脚本中的最后一个方法是 OnDestroy() 方法:
void OnDestroy()
{
headPositionAction.Disable();
headRotationAction.Disable();
leftHandPositionAction.Disable();
leftHandRotationAction.Disable();
rightHandPositionAction.Disable();
rightHandRotationAction.Disable();
}
OnDestroy() 方法在脚本被销毁时简单地禁用所有输入动作,确保在后台没有发生不想要的输入读取。
总体而言,NetworkPlayer脚本充当一座桥梁,将玩家的现实世界 VR 动作转换为虚拟多玩家空间。通过将此脚本添加到我们的场景中,玩家可以体验同步和沉浸式的 VR 多玩家环境。
当我们现在测试应用程序时,我们可以在场景中某个位置看到头部和两只手与我们的控制器位置对齐。接下来,我们将当按下扳机和握持按钮时动画化我们的手。
手部模型动画
您的多玩家应用程序已经取得了长足的进步。现在,让我们通过手部动画进一步增加沉浸感。通过将这些控制器输入映射到这些动画,用户将在虚拟世界中体验到更高的真实感。如果您对动画感到陌生,我们建议您快速浏览第五章中的理解动画和动画系统部分。
在Prefabs文件夹中,然后按照以下步骤操作:
-
添加一个
Animator。在第五章中,我们提到了 Unity 中的Animator,这对于控制角色动画至关重要。Animator需要Animator Controller来管理动画的过渡和交互。它还需要Avatar,这是一个映射角色骨骼结构的图,确保动画适合并在角色上真实地移动。
-
对于我们的头像,我们可以从Multiplayer Scene | Oculus Hands | Models中选择L_hand_skeletal_lowres和R_hand_skeletal_lowres选项。
-
然而,我们还没有获得
Left Hand Animator和Right Hand Animator。
双击Left Hand Animator以显示一个Animator窗口,展示Layers和Parameters选项卡。从Parameters选项卡开始,引入Grip和Trigger参数,它们都是float类型。它们表示扳机和握持动作的压力强度:
-
Trigger确定手部捏合的程度
-
Grip控制拳头的弯曲程度
然而,仅仅拥有这些参数并不能神奇地让手指活动起来。为了让它们栩栩如生,我们需要将这些参数绑定到特定的动画状态或集成到混合树中。这些概念在连接动画状态方面有不同的方法,所以让我们比较一下,看看哪种方法最适合我们的需求:
-
0.5,手可能会过渡到HandClosed状态;否则,它将保持在HandOpen状态。 -
混合树可以根据一个或多个参数在多个动画之间实现无缝过渡。这就像使用音乐混音器混合歌曲一样。
对于手部动画,拥有三个状态很有用:HandOpen、HandHalfClosed和HandFullyClosed。而不是基本过渡,这可能会感觉生硬,可以使用混合树在状态之间流畅地移动,所有这些都基于Grip值。这就是为什么它是我们需求的最佳选择。
要设置混合树,在基础层窗口的中心处右键单击,并选择创建状态|从新混合树。你的基础层窗口应该类似于图 8.12中所示。

图 8.12 – 动画器窗口中的基础层
通过双击混合树并随后选择它,你会被提示选择一个混合类型属性,它包括以下内容:
-
1D:这围绕一个单一参数旋转,例如步伐,以在行走和跑步等动画之间切换
-
2D 自由形式笛卡尔坐标系:这使用两个独立的参数,例如,根据角色的情绪和能量水平确定动画强度
-
2D 自由形式方向性:在这里,两个参数作为方向向量,例如,在水平和垂直方向上瞄准武器
-
2D 简单方向性:通常,这使用两个参数,通常是X和Y输入,类似于摇杆的运动,以确定角色方向
对于使用握把和扳机的细微手部动画,2D 自由形式笛卡尔坐标系是理想的。每个参数独立操作:握把决定了拳头强度,而扳机则负责捏合手势。将混合类型调整为2D 自由形式笛卡尔坐标系,然后在检查器窗口中将握把指定为X轴,将扳机指定为Y轴。在同一个窗口中,我们需要定义一些关键动作。
对于一个固定位置,你应该考虑以下四个关键动作,描述手部动作的极限:
-
0。幸运的是,我们不需要自己创建这样的动画剪辑,因为Multiplayer Scene|Oculus Hands|Animations文件夹中已经有了。 -
0和1。这将是在同一文件夹中Take 001的l_hand_pinch_anim动画剪辑。 -
1和0。这将是之前的Animations文件夹。 -
在这两种情况下都是
1。这也会是1。
如果你一切操作正确,你的混合树应该看起来像图 8.13中所示的那样。

图 8.13 – Unity 中的混合树设置
为右手动画控制器重复此过程。一旦我们完成这个,我们可以将刚刚创建的左手和右手动画控制器拖入左手模型和右手模型预制件的相应字段。
接下来,我们只需要创建一个脚本,将握把和扳机变量的浮点值链接到控制器的按钮输入。
在运行时启用手部动画
在本节中,我们将深入探讨在多人 VR 应用程序中实时启用手部动画的过程。这意味着在实际游戏过程中,当用户与虚拟环境和其他玩家互动时,他们可以见证并体验捏合或攥拳等手势。这种实时交互增强了我们的多人 VR 游戏的沉浸感和交互性。通过在运行时集成这些动画,用户可以无缝地响应游戏机制或与其他玩家进行非语言交流。
我们将通过创建一个脚本将我们的 HandControllerPresence 放入搜索栏,创建一个具有相同名称的新脚本,然后打开它。我们将首先定义必要的变量:
public GameObject handVisualizationPrefab;
[SerializeField] private InputActionProperty triggerAction;
[SerializeField] private InputActionProperty gripAction;
private GameObject instantiatedHandVisual;
private Animator handMotionController;
handVisualizationPrefab 是一个公共的 GameObject 变量,它引用了基于用户 VR 控制器输入将要被动画化的手部模型预制体。在我们的案例中,这将包括 triggerAction 和 gripAction 序列化字段,这意味着它们可以在 Unity 编辑器中分配,但在脚本中保持私有。它们被设计用来获取触发和握持输入的当前值。
instantiatedHandVisual 和 handMotionController 是内部使用的私有变量。前者存储场景中的实例化手部模型,而后者是 Awake() 和 InitializeHandController() 方法的引用:
void Awake()
{
InitializeHandController();
}
void InitializeHandController()
{
instantiatedHandVisual = Instantiate(handVisualizationPrefab, transform);
handMotionController = instantiatedHandVisual.GetComponent<Animator>();
}
当脚本实例被加载时,会调用 Awake() 方法。在这里,它调用 InitializeHandController() 方法来设置手部视觉和动画。此方法在场景中实例化手部模型预制体并将其附加到脚本所附加的对象上。然后,它获取并存储 handMotionController 变量。此 AdjustHandMotion() 方法:
void AdjustHandMotion()
{
float triggerIntensity = triggerAction.action.ReadValue<float>();
float gripIntensity = gripAction.action.ReadValue<float>();
handMotionController.SetFloat("Trigger", triggerIntensity);
handMotionController.SetFloat("Grip", gripIntensity);
}
此方法使用 triggerAction 和 gripAction 变量分别获取触发和握持输入的当前值。这些值在 0(未按下)到 1(完全按下)的范围内。
获取的值(triggerIntensity 和 gripIntensity)随后传递给手的 SetFloat() 方法。这实际上根据 VR 控制器的实时输入调整手的动画。最后,我们只需每帧调用此方法一次,以确保手的动画能够实时更新以匹配用户的 VR 控制器输入。这是在 Update() 方法中完成的:
void Update()
{
AdjustHandMotion();
}
现在,我们只需要将相应的 handVisualiationPrefab 和控制器动作分配给两个控制器的 触发动作 和 握持动作 字段,如图 图 8**.14 所示的左侧控制器。

图 8.14 – 手部控制器存在脚本及其引用
您可能想知道为什么我们使用图 8.14中显示的XRI 左手引用。在我们的场景中,我们使用XR 交互设置,这是 XR 交互工具包的起始资源的一部分。这个XR 交互设置使用XRI 默认输入动作作为控制器输入处理。
通过转到样本 | XR 交互工具包 | 您的 版本 | 起始资源并双击XRI 默认输入动作来查看它们。这将打开图 8.15所示的窗口。

图 8.15 – XR 交互工具包的 XRI 默认输入动作
Unity 中的 XR 交互工具包基于动作的输入系统允许设备无关的控制设置。它使用动作映射来分组相关的动作,例如XRI 左手交互,以处理特定的动作,如选择值或激活值。然后,这些动作与特定的输入相关联,称为绑定,例如 XR 控制器的握把按钮或扳机按钮,从而允许在各种 XR 设备上实现灵活直观的控制配置。您可以添加额外的动作映射、动作和绑定,或更改现有的绑定。您甚至可以在资产 | 创建 | 输入动作下构建自己的完整的输入动作设置。然而,您需要在输入动作管理器的动作资产下的检查器窗口中链接此新的输入动作设置。有了这个,我们就实现了手模型动画。要开始与朋友测试应用程序,请按照以下简单步骤操作:
-
打开您的 Unity 项目,然后转到文件,然后构建设置。
-
将当前打开的场景添加到构建设置中。
-
点击构建选项。当提示时,选择一个您可以轻松访问并记住的目录。
-
此操作将在所选目录中生成可执行文件以及其他与场景相关的关键文件。为了让您的朋友加入,请与他们分享整个文件夹。
-
通过按下播放按钮来启动到服务器的连接。在您等待连接时,指示您的朋友启动可执行文件。
哇!您已经成功设置了您的第一个多人游戏环境。现在,您和您的朋友可以像图 8.16所示的那样互动。

图 8.16 – 我和我的朋友在我们的多人游戏环境中
注意
你可能已经注意到了一个令人惊叹的深空背景和一幅如画的星球。这种美学效果是由我们从 Unity Asset Store 导入的 Skybox Volume 2 包提供的(assetstore.unity.com/packages/2d/textures-materials/sky/skybox-volume-2-nebula-3392)。它显著增强了我们环境的氛围。
随着本章接近尾声,你现在应该能够自信地使用高级技术来增强你的 XR 体验。然而,这并不意味着你应该不加思考地将每个功能,例如眼动追踪或手势追踪,应用到所有项目中。同样,这也不意味着你后续的所有 XR 努力都必须是多玩家应用。
它真正意味着的是,你的视野已经拓宽。你现在拥有更丰富的交互技巧来创建你的 XR 应用程序。例如,你不再可以不加区分地将眼动追踪应用到每个场景元素上,而是可以选择性地将其用于真正从中受益的组件。想象一下消防车虚拟展览:你不必让用户负担过多的信息,当用户的目光停留在特定的车辆上时,可以无缝地显示技术规格。基于用户的视觉焦点,可以激活交互式组件,如动画消防员或可探索的车辆内部,从而提供引人入胜且动态的用户体验。同样,在寻宝游戏中,当玩家的目光遇到神秘的镜子时,可能会出现提示。可能性是无限的!
摘要
在本章中,你学习了如何将手势追踪、注视追踪和多玩家功能集成到你的 XR 场景中。将这些高级 XR 方法融入你未来的 XR 项目中,将使你能够为用户创造更加直观、沉浸和有趣的体验。结合你在前几章中学到的如何创建和部署交互式 XR 体验的知识,你应该能够自信地开发各种 XR 项目,无论它们涉及编码、动画、粒子、音频还是多玩家支持。
现在你已经掌握了 XR 的技术和编程方面,下一章将聚焦于 XR 的商业领域。在那里,你将探索 XR Interaction Toolkit、ARKit、ARCore 和 AR Foundation 之外的强大 XR 插件和工具包,这些可以作为你未来 XR 开发技能的有价值补充。下一章不仅会让你了解 XR 的最新趋势,还会为你提供行业最佳实践,以确保你项目的成功。
第九章:XR 开发的最佳实践和未来趋势
在这本书中,你已经掌握了在 Unity 中进行 XR 开发的一系列技能。虽然你现在应该能够使用 XR Interaction Toolkit、AR Foundation、ARKit 和 ARCore,通过本书中学到的所有技术,在 Unity 中创建各种 VR、MR 和 AR 应用感到自在,但我们还希望帮助你并指导你从现在开始 XR 开发之旅。本章专门为此目的而设计。它不仅会为你提供 XR 开发的最佳实践,这些最佳实践是你应该熟悉以成为一名更灵活、更有力的 XR 开发者,而且还会提供一个关于 XR 工具包和插件的全面概述,这些工具包和插件可能是你想要专注于掌握的,以深化你在特定领域的 XR 开发知识。
你还将了解 XR 技术和应用的当前趋势,我们甚至会提供一些该领域领先专业人士和研究人员对 XR 未来趋势的预测。到本章结束时,你不仅将成为一名优秀的 XR 开发者,还将对 XR 技术的未来路径感到自信。你将能够更好地评估如何使你的 XR 项目与这些发展保持一致,并处于前沿,以及哪些技能可能对你来说是有趣的,值得你接下来去掌握。
本章分为以下几部分:
-
探索 XR 技术和应用当前及未来的趋势
-
学习 XR 开发的最佳实践
-
XR 开发的其它有用工具包和插件
探索 XR 技术和应用当前及未来的趋势
你知道吗?到 2023 年,消费级 XR 头显的出货量达到了 1780 万,这是商业级 XR 出货量的三倍多,后者为 560 万。B2C XR 市场激增至 311 亿美元,比 2022 年增长了 23%。移动 AR 在 XR 领域占据主导地位,市场价值为 211 亿美元,超过了价值 158 亿美元的 VR 市场(www.statista.com/topics/6072/extended-reality-xr)。
拥有创建沉浸式 XR 体验的能力和工具,并见证 XR 市场的快速扩张,你可能会思考应该优先考虑哪个 XR 细分市场。本节将探讨主要采用 XR 的领域。你将深入了解当前的 XR 研究,发现每个细分领域的领先公司,并了解新兴趋势和应用。让我们首先考察一个显示出显著 XR 采用的领域:教育。
在新现实中的学习——XR 在教育中的应用
想象一个世界,教室不再受四壁的限制,学生可以穿越宇宙,深入人体,或从地球的另一端探索石灰岩洞穴——不是通过教科书,而是通过沉浸式体验。这不是科幻小说的领域,而是由 XR 推动的教育快速发展的前沿,而你作为 XR 开发者的技能对于将其变为现实至关重要。
如果没有人热衷于使用它,一项创新技术本身就没有价值。在墨西哥的一所大学中,参与一项研究的学生中有超过 90%的人认为 VR 有助于他们理解三维向量、可视化与向量相关的数学问题以及理解向量与三维轴之间的角度(repositorio.unab.cl/xmlui/handle/ria/24387)。此外,超过 80%的人表示有兴趣在未来寻找包含 VR 集成的课程,并认为熟悉 VR 工具是快速且直接的。
对于教师来说,情况也相同。一项大规模调查调查了超过 20,000 名教师对在教育中使用 VR 的态度(link.springer.com/article/10.1007/s10639-022-11061-0)。这项调查发现,教育工作者对 VR 在教育中作用的看法是相当积极的。研究结果还显示,随着 VR 集成程度的提高,其使用频率也相应增加。
VR 被发现通过提高参与度和动机、促进远程团队合作、提供跨学科协作空间、培养社交技能以及与协作学习策略相一致,从而增强协作学习(www.frontiersin.org/articles/10.3389/frvir.2023.1159905/full)。
在过去 20 年中,围绕教育中沉浸式 VR 的出版物逐年增加。这一点在 2017 年至 2022 年这段时间尤为明显,年出版量比前一个时期高出 2.6 倍(www.mdpi.com/2071-1050/15/9/7531)。这些发现证明了使用 XR 进行教育目的的研究兴趣日益增长。当将 VR 应用中的量化学习成果与桌面计算机和演示等不太沉浸式教学技术的成果进行比较时,VR 在大多数情况下被发现提供了显著的好处(link.springer.com/article/10.1007/s40692-020-00169-2)。
几家公司正在利用最近的研究成果,通过 VR 和 AR 增强教育体验。ClassVR提供了一个沉浸式的教育平台,将 VR 头盔与配套的课程内容库相结合。这些内容,被称为Avanti’s World,也可以在没有头盔的情况下访问。它是一个以主题公园格式设置的全面虚拟学习环境,包含六个 VR 区域,每个区域都致力于不同的教育领域(www.classvr.com/)。
同样,zSpace提供了一种集成的 XR 解决方案,包括软件和独特的硬件,增强了动手学习的体验。学生可以使用轻便的眼镜,通过触控笔与 3D 虚拟模型互动。该平台提供跨多个学科的丰富内容,从 K-8 和高中阶段的数学、科学、生物学等课程,到职业主题如健康科学和制造等(zspace.com/)。
Kai XR是一个专为教师设计的教育 XR 平台。该平台提供 360 度虚拟旅行,使学生能够从教室中虚拟穿越全球各地。Kai XR致力于提供儿童友好的沉浸式体验,提供从历史遗址到现代奇迹的多样化 VR 内容。公司强调其适应性,邀请教育工作者使用预先设计的课程,或者使用Kai XR的资源自行设计课程。目标是促进中学生的丰富学习体验,同时磨练他们在现代世界的技能。该平台与多种设备兼容,从智能电视到Oculus Quest等 VR 头盔。
在苹果的 App Store 和谷歌的 Play Store 等平台上出现了许多教育 XR 应用。值得注意的例子包括利用 AR 的Human Anatomy Atlas和Catchy Words,以及 VR 体验Ancient Egypt。此外,VR 头盔制造商如 Meta 在其原生平台上提供了一系列教育 VR 应用。这包括如语言学习的Mondly、太空探索的Star Chart和艺术爱好者的Painting VR等应用。
如果你是一名 XR 开发者或爱好者,现在正是专注于教育 VR 的绝佳时机。需求正在上升,研究令人鼓舞,教育意义深远。教育领域正准备迎来一次 XR 革命,你的专业知识可能塑造其未来。
另一个推动 XR 创新的动力是工业和制造用例,关于这些内容你将在接下来的章节中了解更多。
工业环境和智能制造中的 XR
目前,美国大约有 13%的企业正在将 XR 解决方案集成到他们的公司中。这一比例凸显了对该技术的日益增长的兴趣和接受度。此外,预测表明,近 23%的公司计划在未来三年内采用这些技术。这为 XR 开发者提供了一个巨大的市场机会,以便利用一个即将扩大的市场。
将 XR 技术集成到工业领域的显著好处是,有可能大幅减少工作场所事故——高达 70%。通过使用 XR 识别潜在危险和危险操作,行业可以创造一个更安全的工作环境。这种对安全和效率的关注可能会推动对能够提供此类结果 XR 解决方案的需求。
从美国市场收集的数据表明,大约有 2.5%的公司正在充分利用 XR 技术。这些现代实体通常被称为未来的智能工厂,拥有有利于 XR 解决方案的全面技术生态系统。利用这个细分市场,开发者可以推动 XR 可能性的边界,为行业设定基准(doi.org/10.1016/j.procs.2022.09.357)。
在智能制造领域,尤其是 AR 技术正在取得显著进展。通过使用智能手机或头戴式设备等 AR 设备,工人在执行任务时可以接收实时信息和指导。例如,一个 AR 头戴式设备可以显示逐步的组装说明,并在发生错误或工具接近使用寿命结束时提供反馈。AR 在制造业的另一个有用应用是,当客户需要维修帮助时,专家可以通过 AR 眼镜(如微软的HoloLens)远程引导。
随着增强现实(AR)技术的应用增加,工人的准确性和效率得到提升,在智能制造环境中采用这项技术会导致制造设施的整体生产率提高。对于新员工的入职和培训,AR 可以直观地展示复杂的任务和流程,确保更好的理解和记忆。管理者可以通过他们的移动设备快速确定生产状态,当他们导航工厂地面时(www.mdpi.com/2079-9292/12/7/1719)。
在最近的文献中,发现组装是制造业中 AR 采用的一个领导者。这种突出地位源于组装活动以视觉为中心,需要大量的操作员参与。比较研究表明,AR 提高了维护和组装的效率,缩短了维护时间,并提高了任务质量,优于传统工具。
质量保证也从 AR 中受益。最初使用 AR 投影二维信息,现在则使用空间 AR 进行质量检查,例如焊接点检查。空间 AR 与实时 3D 计量数据相结合,有助于评估零件的表面质量,确保精确的焊接,并支持包装领域如冲压机设置,减少错误和成本。
近期的研究也利用 AR 对汽车零部件进行质量控制,消除了操作员不断查阅静态文档的需求,简化了流程,并提高了效率。测试表明,AR 系统将复杂质量控制程序的执行时间缩短了 36%。基于以用户为中心的设计的其他应用展示了 AR 在协助工人进行设计差异检测方面的潜力。AR 工具的效率体现在它对用户认知负荷的降低,因为他们不再需要在设计数据和物理原型之间分散注意力。
另一项在汽车领域的研宄开发了一个 AR 系统,用于在车身装配过程中纠正对齐错误,显著加快了过程。该 AR 系统提供了实时指导,使程序几乎快了四倍,且无论操作员经验如何,结果都更加一致。未来的改进目标包括进一步减少设置时间并实施人工神经网络进行错误检测(www.mdpi.com/2076-3417/12/4/1961)。
在工业 AR 环境中,跟踪技术在准确确定物体和设备的位置和方向方面发挥着关键作用,确保了沉浸式和交互式的 AR 体验。根据提供的信息,这些工业场景中最常用的跟踪技术如下:
-
基于标记的跟踪: 在制造环境中,基于标记的跟踪是应用最广泛的跟踪方法之一,占据了主导地位。我们已在第四章的“什么是基于标记和无标记的 AR?”部分对此技术进行了详细讨论。对于工业应用案例,基于标记的跟踪的主要优势在于其速度、简单性和鲁棒性。它已在诸如辅助装配过程 AR 教学系统、协助维护过程、指导车间操作员以及支持汽车行业焊接过程等场景中得到广泛应用。该方法广泛应用的证据是,在 200 篇与工业环境中 AR 应用相关的选定研究文章中,有 63 篇文章(31.5%)专注于基于标记的跟踪,这表明它在基于 AR 的制造应用中的重要性。
-
无标记跟踪:无标记跟踪是我们在第四章的“什么是基于标记和无标记 AR?”部分中广泛讨论的另一种方法,在工业环境中,它经常使用的 AR 跟踪技术的主导地位中排名第二。其应用实例包括在汽车行业中使用工作站的三维点云进行质量控制程序,或集成云数据库进行故障诊断。
-
混合跟踪:这是一种新兴趋势,混合跟踪结合了基于计算机视觉的技术(如基于标记或无标记方法)和基于传感器的方法的优点。通过这样做,它实现了更快的跟踪速度,减少了延迟,并减轻了无标记跟踪算法固有的计算负担。引入额外的传感器数据还可以提高其他跟踪方法的表现。
-
基于模型的跟踪:当有跟踪对象或部件的 3D CAD 模型可用时,这种方法基于这些模型分析和识别对象的姿态和位置。尽管由于其集成到 Unity 和Vuforia等 AR 软件开发平台而受到越来越多的欢迎,但它的主导地位仍然不如其他方法,有 13 篇(6.5%)200 篇研究文章采用了这种技术。
-
基于传感器的跟踪:这种方法在制造业的 AR 解决方案中相对不太受欢迎,主要是因为部署传感器相关的复杂性和成本,尤其是在室内环境中。挑战包括传感器信号可能被设备、机器或其他物体阻挡,使其效果降低(
www.mdpi.com/2076-3417/12/4/1961)。
尽管各种跟踪技术在制造业中满足不同的增强现实(AR)应用需求,但基于标记的跟踪由于其简单性和鲁棒性而仍然是最受欢迎的。然而,随着工业环境的发展和技术的持续进步,我们正在见证一种逐渐向更复杂但更通用的跟踪技术转变的趋势,如无标记和混合方法。如果你对探索工业增强现实(XR)的世界感兴趣,首先了解这些跟踪技术的优缺点应该是你未来主要优先事项之一。
在工业 XR 领域崭露头角的明星企业RealWear专注于免手持 AR 可穿戴解决方案。其 AR 可穿戴设备允许能源和制造等领域的工人在不影响手部操作的情况下获取关键信息(www.realwear.com/)。
TeamViewer 也看好 AR 在工业用例中的应用。其 AR 平台 TeamViewer Frontline 设计用于引领无桌工业劳动力进入数字时代。利用最先进的可穿戴技术,Frontline 简化了各行业的手动流程,弥合了熟练的数字化办公人员和实际操作的工业团队之间的差距。其 XR 解决方案套件提供无缝集成、广泛的硬件兼容性和用户友好的界面(www.teamviewer.com/en/products/frontline/)。
类似地,PTC 的 Vuforia 提供了一套针对工业用例定制的 AR 解决方案。从让服务技术人员使用 AR 可视化和获取关于机械的见解,到协助设计审查和工厂布局,Vuforia 的 AR 平台满足了广泛的工业需求。
正如你所见,工业部门为 XR 开发者提供了一个充满创新、颠覆和增长机会的肥沃土壤。XR 的实际效益,加上采用趋势和行业面临的挑战,使其成为 XR 开发者集中精力关注的有利可图的领域。
另一个从 XR 集成中受益巨大的行业是医疗保健。
从真实身体到虚拟世界的桥梁——医疗保健中的 XR
虚拟现实因其医学教育中的潜力而备受关注。一项涵盖 1990 年至 2019 年研究的综合荟萃分析旨在评估 VR 在解剖学教学中的有效性。该研究的发现表明,与传统方法相比,在解剖学教学中采用 VR 可以提高学生的考试成绩。作者的分析强调了 VR 作为提升学生对解剖学理解的有价值工具的潜力(bmcmededuc.biomedcentral.com/articles/10.1186/s12909-020-1994-z)。
UbiSim 是这个领域中的一家有趣的公司。它为护理学生提供了一个完全虚拟的模拟实验室,让他们沉浸在能够与真实患者互动的环境中。这个工具旨在提高他们的患者互动、临床推理和决策能力,提供从紧急响应到儿童护理等多样化的场景(www.ubisimvr.com/)。其他提供类似手术 VR 培训平台的公司包括 PeriopSim VR、Osso VR 和 Oxford Medical Simulation。后者为医疗和护理行业提供全面的 VR 培训。该平台的内容可在常规计算机或 VR 头盔上使用。强调以学习者为中心的方法,它提供逼真的患者护理场景和团队合作模拟。牛津大学、曼彻斯特大学和爱丁堡大学等几所著名机构已将此平台纳入其课程体系(careers.oxfordmedicalsimulation.com/)。
XR 技术在医疗保健领域的另一个重大飞跃是 VR 在康复目的上的应用。需要康复的人数激增,尤其是在老年人和有残疾、慢性疾病、功能和认知障碍的人中。这些人面临运动、感觉、平衡和认知方面的挑战,这些挑战极大地影响了他们的生活质量、职业和社会参与。
传统康复治疗面临诸如固定康复中心、资源稀缺、训练过程单调、治疗费用高昂以及缺乏自我驱动鼓励和自动引导等问题。这往往导致康复过程中信心下降和效果减弱。
通过 VR,康复过程正在被彻底改变。VR 提供沉浸式体验,激励患者并增强他们的积极参与。这不仅克服了传统中心的固定性质,也填补了资源不足的空白。此外,基于 VR 的系统与适当的传感器配合,可以密切监控和记录患者的运动和生物数据,为优化和个性化康复计划提供途径。
对这个研究领域的贡献来自 63 个国家和 1,921 个机构,突显了全球对 VR 康复的关注和合作。VR 康复的研究趋势包括运动学、神经康复、脑损伤、运动游戏、老龄化、运动康复和脑瘫等领域。这种多样性强调了 VR 在各个康复领域的广泛应用和范围(www.ncbi.nlm.nih.gov/pmc/articles/PMC10028519/)。
在这个领域,一家有趣的公司专门提供从慢性背痛到帕金森病等一系列不同康复项目的 VR 方案,那就是Penumbra(www.realsystem.com/)。
VR 在手术培训、康复或其他医疗领域的开发不仅是一个令人兴奋的医疗技术和技术的交汇点,而且是一个充满创新、合作和巨大增长潜力的领域。鉴于明显的差距和不断增长的需求,XR 爱好者和发展者如你一样,专注于这个领域,推动下一波有意义的 XR 应用,这是一个令人信服的理由。
用 XR 应用丰富游戏行业的想法可能最初并不像为外科手术程序开发 VR 培训那样深刻。然而,正如你将在以下部分中发现的那样,XR 具有实现全新游戏体验的潜力,从而以我们目前无法完全预测的方式影响这个数十亿美元的行业。
跨越现实的游戏 – 游戏中的 XR 趋势
游戏与 XR 有着历史性的共生关系;XR 在丰富多样和充满活力的游戏领域中找到了其早期应用和广泛的测试场。该行业不断推动边界,寻求提供越来越沉浸、互动和逼真的体验,这自然使其成为 XR 采用和创新的前沿。
一流公司和游戏工作室在培养这个领域方面发挥了关键作用。以其图形处理单元而闻名,NVIDIA 在 XR 领域扮演着重要角色。其RTX系列 GPU,具备光线追踪功能,在 VR 环境中提供了增强的现实感。它还致力于 AI 驱动的进步,如深度学习和超采样,以改善 XR 体验。
索尼推出了PlayStation VR,这是一款与 PlayStation 游戏机集成的 VR 头戴设备。像Astro Bot Rescue Mission和Blood & Truth这样的游戏为该平台提供了专属的沉浸式 VR 体验。
如Ubisoft、EA Sports和Epic Games等知名游戏工作室也积极地将 XR 融入他们的游戏生态系统中,从而改变了我们今天玩游戏的方式。他们与其他技术领导者合作,创造了支持 XR 的游戏,这些游戏提供了前所未有的沉浸感和互动性。
除了这些技术和游戏巨头之外,一些初创公司和较小的实体也加入了竞争,渴望为自己开辟市场。例如,Magic Leap和Niantic(Pokémon GO背后的公司)一直在不懈地努力构建 AR,将物理世界和数字世界在游戏场景中融合。其他值得关注的公司包括专注于 VR 游戏的Resolution Games,该工作室是知名 VR 游戏如Demeo的发行商,以及以其 VR 社交平台和游戏元素集成为特色的Rec Room Inc.。
对于希望投身充满机遇的领域的 XR 开发者来说,游戏行业呈现了一片充满潜力的景观。该行业提供了丰富的类型和叙事,可供探索和创新,从幻想世界到基于现实的模拟。
此外,由于游戏行业是一个价值数十亿美元的行业,它不仅承诺带来创造性满足感,还承诺带来可观的财务回报。开发者有机会从事尖端技术工作,推动可能性的边界,塑造娱乐的未来。
此外,游戏受众,传统上对新技术和创新持开放态度,提供了一个渴望接受 XR 技术为游戏空间带来新奇的成熟市场。这个开放受众可以为精心设计的 XR 游戏产品提供一条特别直接的通往商业成功的途径。
一项研究通过涉及 473 名 VR 游戏玩家的在线调查,探讨了影响人们接受和使用 VR 游戏的因素。研究人员调查了享乐和功利方面对 VR 游戏的影响。享乐方面指的是从玩 VR 游戏中获得的快乐和享受,包括乐趣、娱乐以及这些游戏提供的沉浸式体验。功利方面与玩 VR 游戏可以带来的实际效益相关,例如某些游戏可以促进的健康和福祉改善。这项研究的结果表明,与功利方面相比,享乐方面是人们玩 VR 游戏更强的驱动力。尽管存在诸如身体不适和 VR 不适等潜在不便,但研究人员发现,这些因素并没有显著减少使用 VR 游戏的意愿或玩家体验到的沉浸程度。研究发现,VR 系统的易用性对于鼓励以享乐(享乐)和实用(功利)为目的的 VR 游戏使用至关重要(link.springer.com/article/10.1007/s10055-023-00749-4))。
这些结果为 XR 开发者提供了重要的见解;理解玩家将享受和沉浸式体验置于实用效益之上,可以指导设计过程。此外,确保系统用户友好可以促进娱乐和实用价值。因此,旨在专注于游戏的 XR 开发者应专注于创造沉浸式、有趣且易于使用的体验,同时不必过分关注可能与 VR 游戏相关的潜在身体不适和 VR 不适。
另一项研究旨在通过进行 750 款基于 PC 的 VR 游戏和 17,635 个游戏平台Steam上的用户评论的实证研究,来了解玩家对 PC 基于 VR 游戏的投诉。研究发现,大多数新发布的 VR 游戏支持多个头戴式设备类别和游戏区域。随着时间的推移,对小型游戏区域的支持有所增加。尽管 VR 游戏的平均价格翻倍,但关于游戏内容定价过高的投诉急剧减少。同样,关于晕动症的投诉很少,并且随着时间的推移稳步下降。从 2018 年开始,大多数投诉已从 VR 舒适度问题转移到游戏特定问题上(ieeexplore.ieee.org/document/9347709/)。
研究结果表明,基于 PC 的 VR 游戏市场正变得更加复杂。传统上集中在 VR 舒适度上的担忧,如晕动症,其普遍性有所降低。这意味着专注于游戏开发的 XR 开发者现在应优先考虑提升游戏设计和游戏玩法方面,同时确保 VR 舒适度保持在当前标准或更好。
一项使用 515 名《精灵宝可梦 GO》玩家数据的调查显示,对《精灵宝可梦》系列的怀旧情感激发了玩家对现实世界中 AR 游戏内容的想象。这反过来又培养了玩家对 AR 内容的喜爱,增强了从游戏中获得的满足感。同样,社交参与,包括社区认同和社会自我效能感,提升了游戏体验的意义(www.sciencedirect.com/science/article/pii/S0747563221001394#sec7)。
另一项研究的研究人员开发了一款名为ARQuiz的游戏,用于芬兰科学中心的公众展览参观者。ARQuiz 游戏使游客能够参与与展览相关的虚拟问答。在展览参观期间,玩家使用智能手机定位与附近展览相关的问答问题的 AR 提示。除了主要的问答游戏玩法外,用户还可以通过为其他玩家留言进行社交互动。他们的研究发现,AR 应用对公众展览的整体参观体验产生了积极影响。喜欢 ARQuiz 的游客也更喜欢展览,在问答中表现更好,在展览后感觉更社交。ARQuiz 被认为是有趣的,并且与传统展览相比提供了不同的用户体验(ieeexplore.ieee.org/document/8861040)。
游戏行业成为 XR 开发者另一个有吸引力的途径。无论您打算用 XR 应用程序针对哪个特定行业,都存在某些基本最佳实践和设计原则,您的 XR 应用程序应始终遵循。这些将在下一节中介绍。
学习 XR 开发的最佳实践
本节将为您提供所有 XR 项目的最佳实践和设计模式,无论您为哪个行业创建它们。有了这些知识,您将能够为每个 XR 项目做出正确的硬件、软件和设计决策。让我们从探索您在 XR 项目开始时应考虑的硬件因素开始。
XR 开发中的硬件考虑因素
在 XR 领域,硬件不仅仅是体验的载体;它是体验质量的决定因素。最强大的 VR 设备并不适合每个 XR 应用,就像购买超级计算机只是为了创建一个 PowerPoint 演示文稿一样过度。考虑一个公平的场景:您更愿意使用配备外部传感器、要求高性能 PC 和全身追踪的漫长 VR 设置来展示太阳能电池板的 VR 表示,还是更愿意使用 Meta 或 PICO 等用户友好的独立 VR 设备来完成这项任务?
正确的硬件在性能、适应性和易用性之间达到和谐。一些关键因素包括设备类型、性能和测试。让我们在下一节中更详细地了解不同设备类型及其优势。
XR 设备类型及其优势
理解 XR 设备的限制对于旨在创造沉浸式和流畅体验的 XR 开发者至关重要。每种 XR 设备,无论是智能手机、AR 眼镜还是专用 VR 头盔,都是根据其计算能力针对不同场景定制的。
例如,智能手机因其多功能性和广泛使用,非常适合 AR 应用,如《精灵宝可梦 GO》或 AR 驱动的购物体验,用户可以在真实环境中可视化产品。AR 眼镜,如微软的 HoloLens,更适合专门的任务,如免提工作指导或建筑可视化。相比之下,专门的 VR 头盔,如 Oculus Quest 或 HTC Vive,旨在提供深入、沉浸式的体验,用户可以完全进入一个虚拟世界。以下是一些最常见的使用案例,适合不同类型的 XR 硬件:
-
VR 头盔:
-
提供 360 度视野的完全沉浸式游戏体验
-
模拟训练,用户可以在安全的虚拟空间中练习手术或驾驶飞机等任务
-
在家中体验地点和历史遗迹
-
在房屋建造之前通过建筑可视化漫步您的未来家园
-
虚拟办公室,全球团队可以实时通过化身进行协作
-
-
AR 眼镜:
-
复杂任务的逐步叠加指导
-
在真实世界上的实时方向叠加,结合在工业环境中,用户应无需手持移动
-
外科医生在手术过程中无需不断在患者和屏幕之间移动头部,即可接收到重要信息的叠加
-
技术人员在对他们正在修复的设备上叠加原理图或指导
-
-
智能手机(AR):
-
游戏体验,如《精灵宝可梦 GO》,玩家可以与真实世界地点互动
-
在购买前在你的空间中预览家具或服装物品
-
由 AR 驱动的步行或驾驶方向,如 Google Maps 提供的那种
-
为游客提供地标的历史信息或交互式学习模块
-
通过数字增强来提升视频通话或视频内容
-
在家庭维修等任务上的实时指导
-
一旦你为你的 XR 项目选择了合适的硬件,你需要了解这个领域常见的性能挑战。让我们在接下来的部分中逐一探讨。
XR 设备的性能挑战
创建展示详细 3D 环境的 XR 应用,例如 VR 中的建筑可视化,需要解决性能挑战。老旧设备或计算能力有限的入门级 VR 头盔可能无法平滑渲染这些细节,导致延迟或视觉干扰。同样,一个加载了高分辨率纹理和复杂 3D 模型的 AR 应用可能在先进的设备(如最新的 iPhone)上运行流畅,但在老旧设备上可能因为内存限制而运行不畅。
创建 XR 应用的第一步是评估你将要整合的 3D 模型。例如,Unity 提供了关于导入的 3D 模型的顶点或三角形数量的信息。通常,一个 3D 模型的顶点数往往等同于由三个顶点组成的三角形。因此,模型复杂度直接与其顶点数相关,这对于处理能力有限的设备(如独立的 VR 头盔或智能手机)来说变得至关重要。
参考文档提供了对设备特定顶点数限制的理解。例如,Oculus Quest 1 的文档建议三角形数量上限为 350,000-500,000,而 Quest 2 可以处理 750,000 到 1 百万个顶点(developer.oculus.com/documentation/unity/unity-perf/)。请注意,这适用于场景中渲染的累积顶点数,而不仅仅是单个模型。因此,为了获得最佳性能,场景中所有实体的总顶点数不应超过这个数字,尽管根据其他优化因素(如着色器或物理)存在例外。
假设客户想在 Quest 2 头戴式设备的独立模式下展示五个高分辨率的汽车原型。然而,每个汽车模型有 100 万个多边形,所以五个模型的总多边形数量将是 500 万个,这超过了 Quest 2 推荐的 200 万个多边形的限制。开发者可以采取一些措施来解决这个问题:
-
使用 PC VR 模式:选择在 PC VR 模式下运行 Quest 2,搭配一台强大的计算机,从而避免优化的需求。这样做的原因是 PC 具有更强的计算能力,消除了独立式 VR 头戴式设备的典型硬件限制。
-
利用网格简化:网格简化是一种强大的技术,可以在不显著降低其视觉吸引力的情况下显著减少模型的多边形数量。实施这种方法需要精通 3D 建模软件并理解简化模型的基础几何形状。没有硬性限制,但关键是找到平衡点:有效地减少多边形数量,同时确保模型保留其基本特征和美学价值。
要了解更多关于网格简化的信息,请参阅这篇有见地的博客文章:
odgy.medium.com/mesh-decimation-done-right-95245c4b5f52 -
优化技术:尽管独立式 VR 头戴式设备可以容纳超过其推荐多边形数量的场景,但要实现这一点需要许多优化。采用简单的着色器、实现烘焙光照和选择降低纹理分辨率是一些实现方法。然而,根据我们的经验,对于此类优化,建议保持在规定的限制以上的百万多边形以内。
最后,你应该在整个开发过程中持续测试和评估你的 XR 应用程序,以确保它与硬件的能力相匹配。Unity 的性能分析器等工具是宝贵的辅助工具。在下一节中,你将了解如何使用它。
测试和性能分析应用程序
Unity 的性能分析器是诊断性能问题和优化你的 VR 体验的无价之宝。性能分析器提供了关于你的应用程序的实时数据,捕获了 CPU、GPU、内存使用、渲染、物理等方面的详细信息。在 VR 体验中实施和使用性能分析器与用于任何其他 Unity 项目类似,但有一些 VR 特定的考虑。以下是如何为你的 VR 体验实施 Unity 性能分析器的分步指南:
-
在 Unity 中打开你的项目。转到窗口 | 分析 | 性能分析器,或者简单地按Ctrl/Cmd + 7打开性能分析器窗口。如果你使用的是独立式头戴式设备,确保你的 PC 和头戴式设备处于同一网络。
-
如果你有一个基于 PC 的 VR 头盔,只需在 Unity 中点击播放按钮即可开始你的 VR 体验。当你的 VR 体验正在运行时,Profiler窗口将实时更新,显示从你的应用程序捕获的数据。对于独立 VR 头盔,你必须首先构建并部署你的应用程序到你的 VR 设备上。
-
在 Unity 的Profiler窗口中,点击活动 Profiler下拉菜单。你应该在那里看到你的 VR 设备(假设它与你的网络在同一网络中)。如果没有,请确保 Unity 和你的设备可以通过你的网络进行通信。从列表中选择你的 VR 设备。Unity 将直接从设备开始分析,并且Profiler窗口将实时更新。
在 Profiler 中的许多指标都适用于所有 Unity 应用程序,但在 VR 应用中,你应该特别注意以下几点:
-
帧时间:确保你能够持续达到你的 VR 头盔所需的帧率(例如,Oculus Rift 为 90 Hz,Oculus Quest 为 72 Hz)。错过帧率可能导致 VR 中的运动病。你可以在 VR 硬件的文档中找到推荐的帧率。
-
渲染线程:VR 需要渲染两个视图(每个眼睛一个),这可能会更加耗时。在这里寻找任何尖峰或瓶颈。
-
GPU:由于需要为每个眼睛渲染两次,高质量着色器和后期处理效果在 VR 中可能会特别耗时。始终在 VR 中测试它们的影响。
一旦你确定了你的 VR 体验可能遇到性能瓶颈的区域,你可以深入到 Profiler 的具体部分(例如CPU、GPU和内存)以获取详细的性能分析。寻找任何意外的尖峰或长时间的高使用。这些可能是潜在问题的指标,例如效率低下的脚本、过多的活动物理对象或过于详细的三维模型。根据你的发现对你的项目进行调整。例如,简化复杂的三维网格、优化着色器,并减少活动物理对象的数量。在做出更改后,再次测试你的 VR 体验,以查看问题是否已解决,并确保没有出现新的问题。
小贴士
在 Unity 中分析 XR 应用程序时,常常会忘记以下三个重要方面:
-
Unity 有一个提供更详细信息的深度分析模式,但会牺牲性能。当你需要深入分析时再使用它。
-
记得在最终构建中关闭任何调试日志,因为它们可能会影响性能。
-
对于 VR,始终追求一致且流畅的性能。即使是微小的卡顿也可能让用户感到迷失和不适。
通过在整个 VR 开发过程中定期使用 Profiler,你可以确保你的应用运行顺畅,并为用户提供最佳体验。然而,运行顺畅的体验并不能保证用户会喜欢你的应用。让我们更深入地看看在设计应用之前需要关注的最重要的方面:你的受众。
理解你的受众
在制作成功的 XR 应用的基础步骤之一是了解谁将使用它。正如木匠在开始建造之前不会没有蓝图一样,开发者在没有清晰了解他们的受众的情况下不应该开始创作。本节将指导你通过识别和理解你的目标用户的过程。
在你深入开发你的 VR 应用之前,你需要问自己:“这是为谁准备的?”答案将影响你做出的几乎每一个其他决定。例如,为儿童设计的 VR 应用可能会优先考虑色彩丰富的图形和简洁性,而针对特定行业专业人士的应用可能更注重功能性和数据可视化。考虑年龄、性别、教育和职业。针对青少年的 VR 游戏在设计元素和挑战上将与针对成人的游戏不同。
在这个背景下,另一个需要回答的重要问题是你的受众是否熟悉 VR。如果不熟悉,你的应用可能需要包含入门教程或更直观的控制。技术熟练的用户可能渴望高级功能和定制,而其他人可能希望有一个更简洁、即插即用的体验。通过识别这些用户需求,你可以确保你的应用将相关、用户友好,并且对你的受众有吸引力。
在树立旗帜之前评估环境总是明智的。看看目前可用的、服务于类似目的或目标受众的 VR 应用。确定当前产品中缺少什么。是否有用户在评论中要求的功能或体验,但目前还没有提供?继续关注用户评论,仅通过阅读类似应用的评论就能获得的见解是无价的。用户通常会详细说明他们喜欢什么,他们讨厌什么,以及他们希望包含什么。
创建用户角色是产品设计中的另一种常见方法,在 VR 的世界里,其重要性被放大了,因为体验是如此个人化和沉浸式的。用户角色是一个虚构的角色,代表你的目标受众的一部分。他们有自己的名字、背景、偏好和挑战。角色有助于使抽象的用户需求更加具体。在做出决定时,你可以问:“这个功能会对喜欢游戏的、技术娴熟的大学本科生安娜有什么好处?”或者“这个界面对刚接触 VR 的中年建筑师拉吉来说是否直观?”将用户角色纳入你的规划阶段可能是 VR 应用感觉通用和感觉为用户量身定制之间的区别。
理解你的受众不仅仅是 VR 应用开发的第一步;它是一把指南针,应该引导每一个后续的决定。真正努力去理解你的用户,确保最终产品不仅能满足,还能超越他们的期望。在你理解了你的受众之后,你还必须确保你能满足其需求。无论你是单独工作还是在一个团队中,高效的项目管理对于在合理的时间内以合理的方式完成你的 XR 应用至关重要。让我们在下一节更深入地探讨这个话题。
XR 的高效项目管理
每一个伟大的创造都始于一个意图,一个清晰的目标,即一个人希望实现什么。设定可衡量的目标确保开发过程保持专注,最终产品与预期的目的相一致。本节将阐述如何设定有效的目标、优先考虑功能以及确定成功的标准。
就像水手不会在没有目的地的情况下出发一样,开发者应该为他们的 VR 应用有一个明确的目标。首先问自己:“我们为什么要构建这个?”你是想娱乐、教育、培训还是提供独特的服务?明确目的将塑造应用程序的设计、内容和用户体验。一旦你能回答这个问题,确定你应用程序的边界。如果是一个教育 VR 应用,它将涵盖一个主题还是提供广泛的课程?设定范围确保你的努力保持有针对性和可管理性。在这种情况下,你还应该具体说明目标用户希望通过你的应用程序实现什么。无论是掌握一项新技能、获得娱乐还是解决特定问题,理解这一点可以帮助你细化你的目标。
在所有这些问题都解决,并且有一系列可能的功能要整合之后,你需要一个策略来优先排序。以下是一些你应该考虑的重要事项:
-
列出你为你的应用程序设想的所有功能。然后,将它们分类为基本功能和那些额外的增强功能。这有助于你首先关注什么是最关键的。
-
使用你的用户画像或早期反馈来确定哪些功能是受众最需要的。
-
对时间、预算和技术限制要有现实的认识。一些功能可能在纸上看起来很棒,但实施起来可能需要大量资源。记住你团队的人数和技能。
定义成功与设定初始目标一样重要。你将如何知道你的 VR 应用是否达到了,或者希望超过预期?为此,我们建议你在 XR 项目开始时就建立成功指标,以便在发布后以及用户测试期间进行评估。跟踪平均会话时长、使用频率以及用户在应用中的进度,以衡量参与度水平。同样,监控崩溃率、故障和其他与性能相关的问题。一个技术过硬的应用对于保留用户至关重要。不要仅仅将你的指标视为成绩单,而应将其视为未来更新、改进甚至潜在扩展的路线图。
为了使你的 XR 项目成功,你还应该熟悉一些管理 XR 项目的基本技术和工具。让我们一步步来了解它们:
-
思维导图和头脑风暴会议:这些会议能帮助你利用集体智慧,推动概念清晰度和创造力的提升。对于这些会议,你应该召集一个多元化的团队,包括技术开发者、设计师甚至潜在最终用户。即使你是独立开发者,你也应该这样做。他们的综合见解可以产生丰富的新想法。对于这些会议,我们建议你使用米罗或清晰图表等工具。
-
游戏设计文档(GDD):GDD 作为项目的蓝图,将叙事、机制、交互和关卡设计交织在一起。与传统的分镜头脚本不同,GDD 更深入地探讨了用户在 XR 环境中的交互细节,列出了机制,设定了规则,绘制了每个关卡中的挑战,并通过详细说明菜单来确保无缝的用户体验。这种整体方法简化了开发过程,为成功项目奠定了基础。
-
创建 3D 线框图:虽然传统的线框图工具有助于绘制数字界面,但 XR 需要更 3D 的方法。例如Sketchbox和Gravity Sketch这样的工具让开发者和设计师能够制作 3D 线框图,从而对 XR 环境有一个空间上的理解。
-
管理你的代码库:一旦项目规划完成,就需要对其进行管理。特别是在复杂的 XR 项目中管理代码库的变更可能是一项艰巨的任务。在这种情况下,Git,一个分布式版本控制系统,将成为你的日常伴侣。Git 允许开发者同时在不同功能或错误上工作,而不会影响主代码库。一旦某个功能或修复完成,它就可以合并回主分支。每一次变更、每一次合并和每一个版本都会被跟踪。这意味着如果出现问题,你可以轻松地回滚到应用程序的先前状态。Git 提供了一个平台,让多个开发者可以协作而不会相互干扰。每个贡献者都可以在自己的本地副本上工作,然后将更改推送到共享仓库。
GitLab和GitHub都提供了扩展 Git 功能的平台,使协作过程更加顺畅。除了版本控制之外,这些平台还提供了一系列工具,如代码审查、持续集成和持续部署,这些工具简化了开发过程。你还可以使用它们报告、跟踪和分配错误或功能。这有助于团队在优先事项上保持一致,并确保问题得到有序解决。这两个工具还配备了看板。看板是一个用于管理任务和工作流程的视觉工具。随着任务从一个阶段移动到另一个阶段,例如从待办到进行中或完成,它们可以在看板的列之间拖动。这提供了项目进度和瓶颈的快速概述,非常适合敏捷项目。
规划 XR 应用是一个多方面的过程,将传统技术与 XR 特定工具相结合。这种集成确保了 XR 应用的基础稳固、清晰,并准备好成功开发。无论你是绘制用户的旅程图还是构建 3D 原型,每个规划阶段都是实现引人入胜且具有影响力的 XR 体验的一步。
在下一节中,我们将重点关注确保良好用户体验的最佳实践。
确保良好的用户体验
在 XR 应用中确保良好的用户体验不仅仅局限于图形和性能;它深入到直观设计和用户交互。从掌握 XR UI/UX 设计的基础到创建包容性界面,以及理解反馈的重要性,每一个方面都在定义用户无缝和沉浸式体验中扮演着关键角色。
传统的 UI/UX,无论是针对网页还是移动应用,都关注于平面屏幕上的空间关系。设计师会问:“一个元素放在另一个元素旁边看起来如何?”在 XR 中,问题会演变。空间关系不仅仅是左右,还包括深度。这是关于一个元素如何在 3D 空间中相对于另一个元素存在的问题。
XR 环境也引入了传统设计中没有的挑战。例如,如何确保用户在 VR 中能够舒适地阅读文本?或者在 AR 中,如何设计一个界面,使其与现实世界相辅相成,而不是相互冲突?
随着 XR 的成熟,一些模式和指南已经出现,有助于创建直观和沉浸式的体验。正如汉堡图标在传统应用中表示菜单一样,某些手势或符号在 XR 中正在标准化。例如,在 VR 中,手的捏合可能表示选择,而在 AR 中,滑动可能旋转一个物体。物理反馈,如控制器对动作的振动响应,可以显著加强用户在 XR 环境中的动作。无论您正在开发哪种类型的 XR 应用,以下是一个很好的经验法则:利用现实世界中的熟悉动作(如抓取或投掷)来使您的 XR 应用中的虚拟交互立即易懂。
同样,XR 界面需要以用户舒适度为首要考虑。元素应位于舒适的可触及和可视范围内,确保用户不需要做出尴尬的动作或过度用眼。这也涉及到考虑人体工程学,确保长时间交互不会导致身体疲劳。在 XR 应用中包含大量交互和细节的诱惑很大,但这往往会导致混乱。清晰和简洁应该是首要原则。如果一个界面元素或交互没有明确的目的,那么重新考虑其包含是值得的。
随着数字革命的到来,人们可能会认为可访问性障碍已经显著减少。然而,如果没有仔细的设计,增强现实(XR)可能会无意中引入新的障碍。确保 XR 应用不仅服务于众多用户,而且服务于所有人至关重要。对于您未来的任何 XR 应用,以下有三件重要的事情需要牢记:
-
并非所有用户都以相同的方式与 XR 互动。有些人可能有视觉障碍,其他人可能有听觉挑战,还有其他人可能面临行动限制。例如,字幕音频可以帮助听力障碍者,而语音命令可以帮助行动受限者。
-
在设计中,一刀切很少有效,尤其是在 XR 中。提供用户调整设置以适应其舒适度的能力可以产生巨大差异。这包括为可能发现默认尺寸难以阅读的用户调整 UI 大小,或为对强烈光线敏感的用户调整亮度。在 VR 中,音频级别可以调整,以确保用户可以舒适地沉浸于环境中。
-
XR 中的包容性不仅仅是添加功能,而是采用一种心态。当设计过程从考虑所有潜在用户开始,无论他们面临什么挑战,都会导致一个不仅更健壮,而且更普遍受欢迎的产品。
XR 的潜力是无限的。然而,这种潜力只有在设计师将用户置于设计过程的核心时才能实现。通过关注直观交互和倡导包容性,XR 应用程序可以为每个人提供变革性的体验。
确保良好的用户体验的另一个重要方面是收集用户反馈。任何 XR 应用程序的开发质量仅取决于它所收到的反馈。在 XR 中,用户正在导航复杂的 3D 环境和进行新颖的交互,了解他们的体验至关重要。有几种可能的方式来收集用户反馈:
-
游戏测试:这是收集洞察力最直接的方式之一。通过观察用户在 XR 体验中的导航过程,您可以识别痛点、困惑时刻或表现特别出色的元素。它提供了用户如何与您的应用程序互动的第一手资料,对于 XR 开发来说是无价的。
-
调查和问卷:这些可以在体验后用来收集结构化反馈。它们可以关注 XR 应用程序的特定方面,如交互的直观性、视觉美学或整体用户满意度。定制问题可以深入了解特定元素,而开放式问题可以提供意外但宝贵的观点。
-
自发反馈:除了结构化的游戏测试之外,有时只是允许用户与 XR 应用程序互动并自发地分享他们的想法,可以产生最坦率的反馈。这些会议可以更加自由,让用户以自己的节奏探索,开发者记录反应、评论和行为。
并非所有反馈都是可操作的,有些甚至可能是相互矛盾的。关键在于寻找用户之间的一致痛点或赞扬的模式。结合热图和眼动追踪等工具,可以直观地表示用户最常看或互动的地方,这可以非常有价值。同样,关于身体不适、困惑或愉悦时刻的反馈也应给予优先考虑。
基于这样的分析,您的 XR 体验应该进行相应的调整。这可能意味着重新设计某些 UI 元素,优化性能,甚至引入新功能。目标是增强有效部分,修复或消除无效部分。
为了避免对交互感觉不自然或直观的批评,您应该从一开始就专注于选择常见的输入配置。让我们在下一节中讨论它们。
输入设备
在 XR 领域,交互模式是影响用户沉浸感和参与度的一个关键方面。现代 XR 体验提供了一系列交互模式,从控制器到直接的手势追踪和手势识别。作为开发者,确保无缝、直观且稳健的交互至关重要。让我们从 VR 控制器输入配置开始,探讨这些 XR 交互方法的最佳实践。
VR 控制器输入配置
在 VR 的动态世界中,用户与环境交互的方式可以显著影响他们的整体体验。VR 控制器是这种交互的核心,许多开发者遵循一些通用约定以确保一致且直观的用户体验。以下是对常见 VR 控制器输入及其经常关联的动作的概述:
| VR 控制器输入 | 主要动作 | 次要动作 |
|---|---|---|
| 触发按钮 | 抓取或拿起物体 | 射击或激活高亮的项目 |
| 握柄按钮 | 握持或持有物体,模仿闭合手部的动作 | 对象操作,如缩放或旋转 |
| 滑动条/触摸板 | 导航,通常通过传送或平滑移动 | 旋转用户的视角,滚动菜单或调整设置 |
| 面部按钮(A、B、X、Y 或等效按钮) | 游戏中的动作,如跳跃、交互或访问菜单 | VR 体验中的次要模式或工具 |
| 菜单或系统按钮 | 访问游戏菜单、暂停或拉起系统设置 | 常常是校准或重置 VR 视图的快捷方式 |
| 触觉反馈 | 虽然不是按钮,但触觉反馈为用户提供触觉响应,指示成功的交互、碰撞或其他游戏事件 |
表 9.1 – 与不同 VR 控制器输入相关的动作
在下一节中,我们将深入了解 VR 中的常见手势。
VR 中的手势识别
随着 VR 技术的发展,手势追踪和手势识别已成为实现更自然和直观用户交互的强大工具。与传统的控制器输入不同,手势利用了人类手部动作的细微差别,在虚拟环境中创造了一种更沉浸式和直接的交互体验。以下是对常见手势及其典型 VR 动作的分解:
| 手势 | 主要动作 | 次要动作 |
|---|---|---|
| 张开的手 | 通常表示一种放松状态或中性位置 | 在物体或菜单项上悬停 |
| 闭合拳头 | 握持、抓取或拿起物体;与握拳的动作相似 | 有时可能触发一拳或击打,尤其是在以战斗为导向的经历中 |
| 捏合(拇指和食指) | 选择或与特定项目或 UI 元素交互 | 调整对象,如调整大小或旋转 |
| 指点(伸出的食指) | 指向或突出显示特定项目或区域 | 在社交 VR 设置中启动传送或吸引注意力 |
| 大拇指向上 | 通常在社交 VR 环境中代表肯定、同意或积极反应 | 有时可以触发特定的游戏内动作或表情 |
| 手掌朝外 | 停止或阻挡,尤其是在以叙事为主导的体验中推走对象或激活障碍物 | |
| 滑动(水平或垂直) | 浏览菜单、滚动或更改视图 | 也可以在某些游戏中用于如挥剑等动作 |
| 旋转(手从一侧扭转到另一侧) | 旋转对象或调整设置,如音量或亮度 | 可能用于在某些应用程序中更改视角或视图 |
表 9.2 – 与不同手势关联的操作
为了结束这个话题,让我们来看看移动 AR 应用程序的常见输入方法。
移动 AR 输入方法
通过将数字领域与我们的物理环境相结合,移动 AR 通过移动设备的镜头开启了一个充满可能性的世界。移动 AR 的交互性与传统 VR 不同,因为它通常不涉及专用控制器或手势追踪硬件。相反,它利用了智能手机和平板电脑的现有功能。以下是对常用移动 AR 输入及其标准操作的分解:
| 移动 AR 输入 | 主要操作 | 次要操作 |
|---|---|---|
| 触摸(单击) | 选择或与 AR 对象或 UI 元素交互 | 触发动画、获取信息或播放视频 |
| 触摸(双击) | 重置或重新居中 AR 体验 | 在 AR 模式或视图之间切换 |
| 触摸(长按) | 启动拖动或移动 AR 对象的函数 | 也可以激活上下文特定的菜单或选项 |
| 捏合和缩放 | 缩放 AR 对象,使其变大或变小 | 缩放查看详细信息或图像 |
| 滑动 | 旋转 AR 对象或浏览 AR 菜单或幻灯片 | 删除 AR 元素或访问额外内容 |
| 设备移动(倾斜或平移) | 探索 AR 环境,更改视图或影响 AR 对象的行为 | 也可以在游戏或体验中用于控制角色或车辆 |
| 摄像头输入 | 扫描或识别标记、图案或对象以启动 AR 叠加 | 捕获带有叠加 AR 元素的图像或视频 |
| 语音命令 | 通过语音控制 AR 体验或与 AR 对象交互 | 搜索信息、发起通话或访问设备功能 |
| 陀螺仪和加速度计 | 检测设备方向和运动,这可以影响 AR 内容的定位和行为 | 用于游戏或模拟中根据设备倾斜来引导、导航或控制 AR 元素 |
表 9.3 – 与不同移动 AR 输入关联的操作
在探讨了 XR 空间中的最佳实践之后,本章的下一节将探讨一些您可能希望考虑用于即将到来的 XR 项目的有用工具包和插件。
其他有用的 XR 开发工具包和插件
在本章中了解了 XR 开发的趋势和最佳实践后,您可能已经对您对 XR 开发的哪个领域充满热情。随着您进一步探索您选择的专长,本节将通过提供对有价值的 XR 工具包和 Unity 插件的详细分析来引导您。虽然我们已经讨论了 XR Interaction Toolkit、AR Foundation、ARKit 和 ARCore,但还有许多其他工具。其中一些工具包是为特定项目定制的,而其他工具包可能成为您各种 XR 项目的基础工具,具体取决于您选择的方向。
探索 Unity Asset Store 中的强大 AR 工具包
在广阔的Unity Asset Store中,存在着众多 AR 工具包,每个工具包都为桌面带来了其独特的功能。本章将向您介绍四个强大的 AR 工具包,并帮助您辨别最适合您项目需求的选择。其中之一是Vuforia Engine。
Vuforia Engine,AR 的先驱
Vuforia Engine 是全球最广泛使用的 AR 平台之一,以其在开发跨平台 AR 应用方面的强大功能而闻名。它针对手持设备和数字眼镜,并提供高级计算机视觉功能,包括图像、物体和空间的识别。
支持超过 80,000 个应用,Vuforia Engine 拥有包括EA、Square Enix、LEGO和Activision等知名客户的客户群。如果行业巨头都信任 Vuforia,那么考虑它进行您的 AR 项目就有充分的理由。如果您想在该领域找工作,一旦开始在这本书之外的 AR 项目中工作,获得 Vuforia Engine 的经验应该是最重要的。从将 Vuforia Engine 添加到您的 Unity 项目,设置图像目标到测试您的 AR 应用,每个步骤都在其文档中有详细说明(library.vuforia.com/getting-started/getting-started-vuforia-engine-unity)。
您可以通过在 Unity Asset Store 中搜索或在以下链接上点击来找到这个工具包:assetstore.unity.com/packages/templates/packs/vuforia-engine-163598
对于任何认真从事 AR 开发的人来说,另一个不可或缺的工具包是AR Foundation Remote 2.0,它极大地促进了在智能手机上测试 AR 应用。您将在下一节中了解更多关于它的信息。
AR Foundation Remote 2.0 工具包,AR 开发的生命周期伴侣
与 Vuforia Engine 一起,AR Foundation Remote 2.0 工具包是那些如果你想要进一步探索 AR 开发世界时应该熟悉的工具之一。这个工具将极大地改变你的 AR 开发之旅,因为它允许快速迭代和高效的流程。
传统 AR 开发涉及修改、构建项目、部署到设备以及测试,这个周期虽然必要,但耗时较长。使用 AR Foundation Remote 2.0,开发者可以直接在 Unity 编辑器中运行和调试 AR 应用。这大大缩短了开发时间,使得开发者能够更多地专注于优化和提升 AR 体验。
该工具包不仅超越了基本的Debug.Log()方法,还提供了实时调试功能。AR 开发的一个挑战是可视化应用在真实设备上的外观和感觉。AR Foundation Remote 2.0 将视频从 Unity 编辑器流式传输到真实的 AR 设备,如智能手机,让你能够在不进行完整构建的情况下预览你的工作。这种实时反馈对于微调用户体验非常有价值。在 Unity 编辑器中直接访问场景层次结构和所有对象属性,调试过程变得更加直观和全面。
该工具的另一个显著特点是它的输入远程功能,它允许你从 AR 设备(如智能手机)流式传输多指输入,甚至可以在 Unity 编辑器中使用鼠标模拟触摸。这种灵活性使得测试和调整用户交互更加彻底和高效。
该工具包完全使用纯 C#编写,不依赖第三方库,并提供完整源代码,这使得开发者可以根据自己的具体需求进行修改、定制。它还提供了与 ARKit 和 ARCore 的无缝集成。
考虑到这个工具包提供的所有这些以及许多其他功能,我们强烈建议你投资这个资产,继续深入 AR 开发的世界。通过减少开发和调试时间,该工具包将为你提供可衡量的投资回报。你的初始成本很快就会通过节省的时间和 AR 应用的提升质量得到补偿,并使你成为一个更专业的 AR 开发者。
你可以通过在 Unity Asset Store 中搜索AR Foundation Remote 2.0或点击此链接来找到该工具包:assetstore.unity.com/packages/tools/utilities/ar-foundation-remote-2-0-201106
现在你已经了解了哪些工具包可以提升你的 AR 开发能力,让我们来看看一些更专业的工具包,这些工具包将帮助你更快、更高效地开发特定的 AR 应用。
GO Map – AR 游戏中的 3D 地图,基于位置 AR 应用的隐藏宝藏
无论你是在开发基于位置的 AR 游戏还是需要丰富的地图可视化样式选择,如地形、卫星图像和混合地图,Unity 资产商店中的GO Map – 3D 地图用于 AR 游戏资产都将对你非常有价值。它还包含了展示多种风格的演示场景——从经典平面地图到混合地图,从真实建筑渲染到地形。
GO Map 包允许无缝地将兴趣点和现实世界的景观集成到游戏玩法中。由于每个设置和图形控制都可以直接从检查器窗口中操作,你可以节省宝贵的发展时间,从而让你能够专注于内容和游戏玩法。
你可以通过访问 Unity 资产商店并搜索GO Map - 3D 地图用于 AR 游戏或直接导航到其 URL(assetstore.unity.com/packages/tools/integration/go-map-3d-map-for-ar-gaming-68889)来找到这个工具包。
如果你更感兴趣的是现实世界的 AR 导航或游览,而不是 3D 地图,那么下一个工具包就是为你准备的。
AR+GPS 位置,开启导航、游览和未来基于位置的游戏的可能
如果你喜欢像《精灵宝可梦 GO》这样的游戏或 Google Maps 的 AR 导航功能,Unity 的AR+GPS 位置包将是一个非常有趣的资产,因为它允许你在相对较短的时间内创建自己的类似应用。
该资产提供的前沿功能是其 AR 导航系统。该系统从Mapbox Directions API中汲取力量,不仅允许开发者创建,还可以在现实世界景观中可视化路线。无论是 Mapbox 绘制的路径还是为不太为人知的地区定制的个性化路线,用户的旅程都通过详细的标志、箭头和视觉提示得到了增强。一个互补的功能提供了使用集成 Mapbox SDK 的 2D 地图视图,同时提供 AR 显示,从而提供丰富的导航体验。
拥有了这项资产,世界真正成为了你的画布。开发者可以在特定的地理位置内锚定 3D 对象。无论是繁华城市中的纪念碑还是偏远村庄中的文物,这些对象都可以通过纬度、经度和海拔坐标进行虚拟定位,为周围环境注入活力。
进一步增强用户参与度的还有 AR 热点。这些是特殊区域,当进入或接近时,会激活特定的 AR 表现。想象一下,当你走过历史小巷时,一个虚拟向导会讲述它的丰富历史,这一切都只是因为你出现在那个地方。
通过资产建立 3D 文本标记的能力,文本表示得到了改进,可以在现实世界的地标上建立。一个在城市中导航的游客可以立即获得关于一个地点的信息,悬停的文本提示引导他们的探索。
当用户移动时,AR 叠加层会自然且精确地响应,确保用户的移动与增强显示之间的和谐融合。此外,物体可以编排沿复杂路径移动或保持静止。
采用 AR+GPS Location 资产需要工具和硬件的某些对齐。与 AR Foundation 版本 4.x 或 5.x 或 Vuforia 版本 10 或更新的版本兼容是必要的。在部署时,设备必须支持 ARKit(iOS)或 ARCore(Android)。对于使用 Vuforia 的开发者,必须使用具有地面平面能力的设备。
你可以通过在 Unity 资产商店中搜索AR + GPS Location或点击此链接来找到这个资产:assetstore.unity.com/packages/tools/integration/ar-gps-location-134882
通过探索本节中提到的 AR 工具包,你正在朝着掌握 AR 开发的技能迈进。下一节将介绍一些同样强大的 VR 工具包,如果你想要进一步探索 VR 开发的领域,你应该关注这些工具包。
探索 Unity 资产商店中的强大 VR 工具包
XR 交互工具包无疑是 Unity 中 VR 开发的基石,应该是你投入最多时间和精力的工具。然而,还有一些其他工具包可以在某些情况下补充或替代它。这些替代方案通常提供了 XR 交互工具包中目前尚未发现的专用功能。深入研究这些工具包不仅可以提高你的 VR 开发技能,使你成为一个更全能的 VR 开发者,还可以根据每个项目的需求优化你的工作流程。尽管 XR 交互工具包在持续发展,但熟悉其他硬件或软件特定的工具包和插件仍然是任何有志于 VR 开发的开发者的重要步骤,正如你将在下一节中了解到的那样。
Oculus 集成、SteamVR、VIVE 输入实用工具和类似的 VR 工具包
深入研究 XR 交互工具包是一个很好的起点,但要真正提升你的 VR 开发能力,直接探索 VR 硬件制造商提供的工具包和插件将大有裨益。这包括为 Meta Quest 系列设备定制的 Oculus 集成包、适用于 PICO 头显的 PICO Unity 集成 SDK、兼容广泛 VR 设备的 SteamVR 插件,以及适用于 VIVE 和其他品牌各种头显的 VIVE 输入实用工具资产。让我们深入了解这些工具,以了解它们在你进一步精炼 VR 专业知识旅程中的重要性:
-
Oculus 集成包:此包为 Oculus VR 设备和一些兼容 OpenVR 的设备提供全面支持。它能够无缝处理所有应用内的音频和音效,提供将 Oculus 头像集成到应用中的工具,促进头像唇部动作与语音的同步以增强真实感,允许在应用中包含 Oculus 平台解决方案以扩展其功能,并引入沉浸式语音交互,让玩家可以使用语音与虚拟世界互动,以及其他许多强大功能。正如您所看到的,对于以 Oculus 设备为目标的 XR 开发者来说,深入研究这个工具包至关重要,因为它提供了一套全面的工具,确保应用针对此平台进行了优化(
assetstore.unity.com/packages/tools/integration/oculus-integration-82022)。 -
PICO Unity 集成 SDK:这是由 PICO 专门为 Unity 开发的 SDK。它提供了一系列功能,从渲染和追踪到 MR 功能。该 SDK 包含了针对空间音频、眼动聚焦渲染(基于眼睛注视优化渲染)、固定聚焦渲染(一种静态的以注视为中心的渲染方法,从中心到边缘降低分辨率)、眼、脸、手和身体追踪、捕捉混合现实视频、透视以及其他许多功能。与 Oculus 集成包类似,这个 SDK 是面向希望为 PICO 生态系统创建定制 XR 体验的开发者的全面包(
developer-global.pico-interactive.com/resources/#sdk)。 -
SteamVR 插件:由 Valve 维护,这个插件是一个与多种 PC VR 头戴设备兼容的通用接口。它简化了 VR 控制器在虚拟空间中的表示,提供骨骼手部数据,并允许复杂的双手与物体交互。虽然这个插件与 XR 交互工具包有许多交集,但 VR 开发者也应该对此感到舒适,因为工具包或其脚本的部分仍然被多家公司使用(
assetstore.unity.com/packages/tools/integration/steamvr-plugin-32647)。 -
VIVE 输入工具:这是一个多功能的工具包,特别针对 VIVE 设备,但也支持众多平台。它使开发者能够创建沉浸式移动和对象交互。它还促进了特定设备与角色的关联,推动了标准化 VR 开发,并提供了跨平台的手部追踪。对于那些关注 VIVE 生态系统的 XR 开发者来说,VIVE 输入工具是一个必不可少的工具包(
assetstore.unity.com/packages/tools/integration/vive-input-utility-64219)。
每个这些制造商和公司都提供了许多其他有趣的 VR 插件。我们建议您探索每个公司的 Unity Asset Store 页面,以发现可能激发您兴趣的额外 VR 插件:
-
Meta Quest:
assetstore.unity.com/publishers/25353 -
HTC Vive:
assetstore.unity.com/publishers/21581
如果您热衷于进一步探索 VR 游戏开发,下一节中介绍的工具包肯定会引起您的兴趣。
Hurricane VR,VR 游戏开发的 XR 交互工具包替代品
虽然 XR 交互工具包是处理 XR 交互的领先工具包,但其通用方法有时可能无法满足特定 VR 游戏应用的需求。如果您想涉足 VR 游戏开发领域,Hurricane VR可能是一个有趣的选择,因为它在游戏领域有着深厚的投入。
此工具包提供了一组丰富的功能,专为 VR 游戏定制,例如武器系统、专门物理交互(如手中翻转刀子)或复杂的玩家控制器。虽然 XR 交互工具包提供了广泛的动作,但 Hurricane VR 为 VR 游戏提供了更细致的玩家控制器功能,例如无缝切换坐立模式、冲刺、蹲下等。
工具包不仅仅是一个工具箱;它是一个完整的工坊。它提供了从物理交互对象(如门和旋钮)到肩上背包库存和武器的各种样本,开发者可以亲身体验工具包的潜力。此外,它无缝集成其他资产,如VR - Physics Interactions Bundle和Final IK,增强了其实用性。您可以通过 Unity Asset Store 搜索或直接导航到assetstore.unity.com/packages/tools/physics/hurricane-vr-physics-interaction-toolkit-177300找到这个工具包。
在深入研究增强你的 XR 能力的工具箱之后,现在是时候细化你的 XR 开发流程了。在接下来的章节中,你将了解到如何利用人工智能的优势来提高你的 XR 开发效率。
探索 Unity Asset Store 中的强大 AI 工具箱
无论你在 XR 领域的特定兴趣是什么,在整个 XR 项目开发周期中利用尖端工具都是至关重要的。利用人工智能可以使你专注于 XR 应用程序的核心游戏机制和逻辑,无需花费无数小时在基本脚本编写上。为了成为一个紧跟当代趋势和进步的熟练 XR 开发者,我们建议你探索下文所述的 AI 工具箱。
ChatGPT 和 DALL·E 的 AI 工具箱,你的 XR 开发伴侣
游戏开发与人工智能的相互作用从未如此流畅或强大。ChatGPT 和 DALL·E 的 AI 工具箱正是这一演变的体现,它展示了开发者对项目中的代码感知、交互和利用方式的范式转变。
想象一下,你不再需要手动编写每一行 C#脚本或着色器,而是用人类语言简单地写下你的需求。ChatGPT将你的需求翻译成功能性和上下文相关的代码,直接在 Unity 中进行。通过使用这个工具箱,经验丰富的开发者可以简化他们的工作流程,将更多时间投入到游戏设计的核心和灵魂上。
这个工具箱的力量不仅限于脚本编写。DALL·E,一种前沿的扩散模型,可以轻松地将你的文本描述在 Unity 引擎内转换为生动的图像。无论是为你的地形创建独特的纹理,还是为你的游戏品牌设计一个标志性的 logo,都可以通过简单的描述实现。
使用这个资产,Unity 环境保持不变。在安装工具箱后,只需在 Unity 编辑器中将传统的添加脚本按钮替换为新的生成脚本选项,然后观察 ChatGPT 的实际操作。
虽然这个工具箱革命性地改变了 XR 开发流程,但理解其局限性至关重要。尽管 AI 非常出色,但它可能无法始终如一地满足复杂需求的高精度。它是你开发旅程的补充,而不是完全的替代品。
从本质上讲,ChatGPT 和 DALL·E 的 AI 工具箱与其说是一个工具,不如说是一个伙伴,准备好分担负担,并将你的游戏开发追求提升到前所未有的高度。你可以在 Unity Asset Store 中通过搜索AI Toolbox for ChatGPT and DALL·E或直接导航到其 URL(assetstore.unity.com/packages/tools/ai-ml-integration/ai-toolbox-for-chatgpt-and-dall-e-250892)找到它。
重要提示
在撰写本书时,这个资产为 Google Bard 提供了实验性支持。当你阅读这段内容时,这个资产可能已经完全支持 Google Bard,因此可能略有重命名。如果你在 Unity Asset Store 中找不到这个资产,请搜索资产的发布者 Dustyroom(assetstore.unity.com/publishers/16150),并查看其资产以找到可能已重命名的资产。
在下一部分,你将发现另一个用于在 XR 场景中创建角色的强大 AI 工具。
Blaze AI Engine,通用 AI 角色创建的强大工具
无论你是绘制一个会变成警觉巡逻代理的简单立方体,还是雕刻一个适应游戏环境的战术先进敌人,Blaze AI Engine工具包都允许你轻松将这些角色添加到你的项目中。它为任何 GameObject 注入智能和真实的行为,而不需要你编写任何代码。
这个资产的美妙之处在于,你不必遵循严格的框架。你可以自由地塑造你想象中的 AI 行为。这个资产与几乎任何系统或资产兼容,包括视觉脚本。
这个工具包不仅关于智能敌人的创建。它还允许你制作忠诚的伙伴来陪伴玩家完成他们的任务,能够动态响应各种命令。
为了丰富你未来 XR 项目的无限 AI 角色选择,请在 Unity Asset Store 中搜索Blaze AI Engine来查看这个资产(assetstore.unity.com/packages/tools/behavior-ai/blaze-ai-engine-194525)。
下一个部分将向您介绍一个简化 XR 应用原型设计的实用工具。
原型化 XR 应用
ShapesXR (www.shapesxr.com) 提供了一系列 UI/UX 和空间模型原型设计功能。它简化了 3D 创建,允许用户从基本元素开始,或从广泛的原始库中选择。通过自定义颜色、材料和文本,该平台通过其捕捉系统提供精确控制。
合作也是 ShapesXR 的核心关注点。它通过使团队成员能够轻松进入 VR 环境,促进了实时共创。这种沉浸式的设计审查方法可以增强理解和生产力。
ShapesXR 支持各种 2D 和 3D 格式,简化了资产的集成。一个Figma插件保持资产同步,你可以从浏览器无缝导入和导出资产。
ShapesXR 还提供了 MR 功能,使设计能够进入现实世界。如穿透材料等特性为 XR 开发提供了宝贵见解。
摘要


浙公网安备 33010602011771号