IOS-和安卓-AR-游戏开发指南-全-

news/2025/9/29 10:39:02/文章来源:https://www.cnblogs.com/apachecn/p/19118286

IOS 和安卓 AR 游戏开发指南(全)

原文:zh.annas-archive.org/md5/eaf1b154611090aa6422cd5e3d6dc2fc

译者:飞龙

协议:CC BY-NC-SA 4.0

前言

在本书中,我们将介绍增强现实及其如何使用强大而简单的工具实现。利用 Vuforia 和 Unity 3D 的免费许可证,我们将看到这两种技术如何无缝结合并产生惊人的效果。我们将学习如何设计一个令人沉浸的增强现实体验,当在现实世界中增强时不会感觉陌生。随着该领域最近的发展,增强现实变得越来越可靠;我们将学习如何以最有效的方式利用这种潜力。

本书涵盖内容

第一章, 什么是增强现实?,将解释什么是增强现实,以及它的过去、现在和未来。

第二章, 设置环境,将涵盖如何使用 Unity 3D 和 Vuforia 设置 AR 所需的必要环境,以及如何在 iOS 和 Android 设备上部署 AR。

第三章, 理解 Vuforia,将介绍 Vuforia 的组件以及它们如何协同工作以实现增强现实。

第四章, 可追踪对象和追踪,将解释如何为 Vuforia 创建可追踪对象以及如何优化它们以实现最高的追踪分数。

第五章, 高级增强现实,将介绍如何使用 Unity 和 Vuforia 制作功能齐全的 AR 游戏。

您需要为本书准备的内容

需要 Unity 3D 的免费版本以及 Vuforia SDK。

本书面向对象

本书面向具有基本至高级编程经验,并对增强现实和游戏开发感兴趣的人。在蓬勃发展的智能手机行业,本书面向那些希望通过互动游戏和增强现实进入沉浸式移动体验的人。

术语约定

在本书中,您将找到多种文本样式,用于区分不同类型的信息。以下是一些这些样式的示例及其含义的解释。

文本中的代码词如下所示:“我们可以通过使用include指令来包含其他上下文。”

新术语重要词汇将以粗体显示。您在屏幕上看到的词汇,例如在菜单或对话框中,将以如下形式出现在文本中:“点击下一步按钮将您带到下一屏幕”。

注意

警告或重要注意事项将以如下框中的形式出现。

小贴士

小贴士和技巧将以如下形式出现。

读者反馈

我们欢迎读者的反馈。请告诉我们您对本书的看法——您喜欢什么或可能不喜欢什么。读者反馈对我们开发您真正能从中获得最大收益的标题非常重要。

如要向我们发送一般反馈,请简单地将电子邮件发送至 <feedback@packtpub.com>,并在邮件主题中提及书名。

如果您在某个领域有专业知识,并且您有兴趣撰写或为书籍做出贡献,请参阅我们关于www.packtpub.com/authors的作者指南。

客户支持

现在,您是 Packt 书籍的骄傲拥有者,我们有多种方式可以帮助您从您的购买中获得最大收益。

下载示例代码

您可以从www.packtpub.com的账户下载您购买的所有 Packt 书籍的示例代码文件。如果您在其他地方购买了这本书,您可以访问www.packtpub.com/support并注册,以便将文件直接通过电子邮件发送给您。

错误清单

尽管我们已经尽一切努力确保我们内容的准确性,但错误仍然可能发生。如果您在我们的某本书中找到一个错误——可能是文本或代码中的错误——如果您能向我们报告这一点,我们将不胜感激。通过这样做,您可以节省其他读者的挫败感,并帮助我们改进本书的后续版本。如果您发现任何错误清单,请通过访问www.packtpub.com/submit-errata,选择您的书籍,点击错误清单提交表单链接,并输入您的错误清单详情来报告。一旦您的错误清单得到验证,您的提交将被接受,错误清单将被上传到我们的网站,或添加到该标题的现有错误清单中,在“错误清单”部分下。您可以通过从www.packtpub.com/support选择您的标题来查看任何现有错误清单。

侵权

在互联网上,版权材料的侵权问题是一个持续存在的问题,涉及所有媒体。在 Packt,我们非常重视我们版权和许可证的保护。如果您在互联网上发现我们作品的任何非法副本,无论形式如何,请立即提供位置地址或网站名称,以便我们可以追究补救措施。

请通过链接到疑似侵权材料的方式与我们联系<copyright@packtpub.com>

我们感谢您在保护我们的作者以及为我们提供有价值内容的能力方面的帮助。

问题

如果您在本书的任何方面遇到问题,可以通过<questions@packtpub.com>联系我们,我们将尽力解决。

第一章:什么是增强现实?

在增强现实中,我们周围的现实世界被叠加了虚拟内容。无论是沉浸式的 3D 体验还是简单的文本和指示,虚拟现实都是一个古老的概念,也是一个新兴的新技术。在本章中,我们将探讨增强现实的概念及其多种形式,以拓宽我们对概念范围及其应用的认识。我们还将介绍帮助我们在这爆炸性增长的移动平台上,特别是 iOS 设备上实现这一概念的工具。以下图像展示了一个增强现实游戏:

什么是增强现实?

增强现实(Augmented Reality)的定义

增强现实(AR)在其最广泛和最简单的定义中,是一种使虚拟内容能够添加到现实世界中的技术。这通常与将 3D 内容添加到摄像头实时画面中相关联,尽管这个术语本身具有更广泛的意义和用法。

可能是人们几十年来一直在使用的最简单的增强现实形态,就是十多年前在照相机中可用的那种。许多人都在使用它,但很少有人意识到所应用概念的本质。这是相机中称为“取景器”的部分,是你通过它观察通过相机看世界的那个小窗口。这个小小的窗口实际上是一种非常简单的增强现实。它本质上是通过镜头观察周围的世界,然后添加一层印在玻璃上的图层,以突出镜头的中心和要捕捉的图像的边缘。在这里所做的是所有形态的增强现实都力求做到的事情,即在现实世界之上叠加相对信息。

在移动平台上,增强现实遵循相同的原理,尽管方法略有不同。摄像头捕捉周围世界的实时画面,然后计算机视觉系统试图在可见的 3D 空间中获得方位,并以与周围世界无缝的方式显示增强现实。计算用户相对于周围现实世界的相对位置的过程,以便能够为用户正确增强内容,被称为跟踪(tracking)。

增强现实的形态

增强现实可以采取多种形式。它总是以某种形式依赖于一种计算相对于我们周围现实世界的相对 3D 空间的技术。它可以使用许多技术来实现这一点。例如,iPhone 上的陀螺仪可以用来跟踪手机在 3D 空间中的放置,如果应用了运动,可以用来跟踪相对于设备的世界。这通常在许多增强现实游戏中看到。这当然是一种 AR 形式,但在这本书中,我们将主要关注一种使用计算机视觉的跟踪形式。

计算机视觉跟踪可以分为两个部分:标记跟踪和无标记跟踪。在标记跟踪中,有一个物理实体,计算机视觉被训练去跟踪;它将摄像机的视角相对于它定位。所使用的物理对象通常被称为可跟踪对象。可跟踪对象通常被内部处理,作为原点和世界的中心,计算机视觉可以据此定位自己。有时,摄像头实时流被认为是世界的中心,可跟踪对象或可跟踪对象是围绕它旋转的物体,从某种意义上说。

无标记跟踪技术本质上与标记跟踪相似,因为它们都试图找到一个基准点来相对于现实进行增强。它们在寻找基准点的方式上有所不同,与标记跟踪不同,它们不需要使用预先定义的物理对象,计算机视觉只训练跟随该对象。在无标记跟踪中,计算机视觉主要被编程为跟随某些颜色和形状,具有一定的自由度。例如,计算机可以被训练去跟随某种色调的绿色物体,并用蓝色物体将其完全覆盖。在这种情况下,它只是跟踪颜色;如果它在摄像头输入中找到一个绿色区域,它就会用蓝色虚拟物体进行增强。计算机视觉甚至可以被训练去识别面部,例如所有那些在用户头部或面部周围添加动画效果的名人相机应用程序。无标记跟踪无疑更加灵活,但它提供的可靠性比标记跟踪要低。此外,无标记跟踪自然地更复杂,这促进了标记跟踪增强现实技术的流行。

在这本书中,我们将使用 Vuforia SDK,这是一个使用标记跟踪技术的 SDK。我们将使用它与 Unity 3D 引擎结合,在 iOS 设备上提供增强现实体验。在利用这两种技术的同时,我们将熟悉创建增强现实的工作流程。

智能手机与增强现实

正如我们已经确立的,增强现实的概念是一个古老的观念。它甚至被编织进我们所能记得的科幻电影中的流行文化中。作为一项技术,增强现实直到最近才达到主流。在过去,由于需要昂贵的设置才能运行,增强现实被认为是一个小众领域。在硬件方面,增强现实的要求很高。它需要一个摄像头来观察世界,计算能力来计算和渲染增强内容,以及用户与虚拟内容交互的方式。所有这些对于主流用户来说都难以实现。

现在,几乎每个人都随身携带非常强大的电脑,能够在很大程度上渲染逼真的图形内容。这些智能手机以史无前例的速度发展,每月都变得更加强大。而且最好的一点是,它们配备了精确的摄像头,满足了增强现实所需的三个条件。

并不非常不准确的是假设每个人都可以随意携带一个增强现实设备。仅此一点就消除了长久以来存在的可访问性障碍。现在,增强现实内容可以以前所未有的沉浸式体验触及数百万用户。

许多公司已经理解了行业趋势及其潜力的重要性。也许走在最前面的是全球最大的移动芯片制造商高通。高通意识到了手机中存在的 AR 的巨大潜力,并开发了免费的 SDK Vuforia。Vuforia 过去被称为 QCAR,是为了让开发者能够挖掘移动空间中的这一潜力而创建的。Vuforia 最初在 Android 平台上启动,后来扩展到包括 iOS 设备。高通始终在其芯片上包含微妙的优化,以进一步提高 AR 体验。这表明他们对技术未来的信心有多大。高通甚至投资于制作一个更适用于移动设备的 OpenCV SDK,称为 Easy CV。Easy CV 是用于图像处理和计算机视觉的工具,可以进一步增强 AR 的体验以及其他涉及计算机视觉的应用。

谷歌也通过其 Google Glass 项目大力投资于增强现实的概念。Google Glass 可能是目前开发中的最雄心勃勃的增强现实项目。它承诺以头戴式显示器和相机的方式为大众提供可穿戴电脑。设计旨在不引人注目,但同时又高效地显示基于现实世界输入的增强现实数据。交互将以语音命令的形式进行,并且能够访问互联网。该项目仍处于起步阶段,但谷歌投入了如此多的资源,显然表明了新兴 AR 技术的重要性。

随着增强现实硬件的可访问性、主要企业的支持以及巨大的市场,增强现实拥有其茁壮成长并长期存在的所有必要条件。这就是为什么了解这一概念及其潜力是重要的。

内容传递的沉浸因素

沉浸是用户对你呈现给他们的世界的全神贯注程度。世界越可信,用户就越沉浸其中,体验试图传达的信息就越成功。成功的开发者会努力实现尽可能高的沉浸水平。

人类的大脑总是会试图理解他们所看到的;这一点对所有人类互动都是适用的。对于虚拟交互来说,这一点尤其有趣,因为人类大脑试图理解的东西在物理上并不存在。谎言越复杂,大脑就越容易相信它。因此,沉浸的艺术就是向大脑讲述完美的谎言的艺术。正如所有优秀的骗子都会说,如果他们在那一刻诚实,讲述完美谎言的方法就是将其与真相混合。根据这个定义,增强现实是讲述谎言的完美方式。

通过将虚拟内容与真实世界混合,用户会感到与展示的内容紧密相连,这是其他大多数虚拟媒体所做不到的。第一次观看用户与增强现实内容互动总是很美妙。通常,我们可以看到用户会暂时忘记他们是通过设备的屏幕观看虚拟内容的,并试图用手去抓取它,好像要检查它是否真的不存在。这种情况几乎总是发生,并且肯定是潜意识中的。这表明用户在行动中沉浸得有多深。

除了沉浸感之外,用户与增强现实内容交互的方式也增加了沉浸感。用户可以从几乎所有的角度查看内容。他们可以围绕它走动,靠近它,也可以远离它。它与世界周围环境的一致性,保持了用户与内容之间的联系。如果这种体验与合适的音频和/或视频内容相结合,它可能会给用户带来笑容。

交互甚至可以以游戏结构的形式出现,允许用户直接影响显示的内容。这种类型的交互对用户来说可以非常有趣,也是一种全新的游戏玩法。

Vuforia SDK 及其如何帮助提供 AR 体验

Vuforia 是高通公司提供的一项优秀产品,为增强现实行业提供了巨大的推动力。它拥有市场上最快的跟踪算法之一,这种算法不太容易受到可追踪遮挡的影响,甚至在低光条件下也是如此。这使得使用 SDK 创建的应用程序用户友好且易于使用。最好的是,Vuforia SDK 提供免费,使其被广泛使用,并在论坛上有一个活跃的社区,解决可能出现的多数问题。

SDK 对新接触这一概念的开发者也非常友好。它有一个流畅的工作流程,易于学习,而且合乎逻辑。使用这个 SDK 将允许开发者以极短的时间部署简单的 AR 应用程序,同时仍然允许他们开发强大且复杂的 AR 体验。

Vuforia 提供易于使用的组件,当它们相互作用时执行增强现实角色。例如,SDK 提供了 ARCamera 组件。ARCamera 组件将自动从设备获取视频摄像头流并将其显示出来供使用。它还将检测开发者为摄像头指定的可追踪对象。ARCamera 将主要对用户相对于可追踪对象的朝向做出响应,而无需开发者进行太多干预。这极大地简化了创建增强现实体验的过程。

Vuforia 还提供了一系列跟踪解决方案,覆盖了多种情况。SDK 中提供的组件列表如下:

  • ARCamera: 这实际上是用户通过应用程序进入现实世界的大门。它提供了设备的实时摄像头流,并提供了要检测的可追踪对象数量。

  • 图像目标: 这是 Vuforia 提供的最常见的可追踪对象形式。使用此组件,应用程序可以检测它被训练来检测的任何合适的图像,并在其上方显示叠加的 AR 内容。只需将内容添加到此组件并设置需要跟踪的图像,AR 内容就会相对于现实世界中的可追踪图像出现。以下图像显示了带有 3D 对象的图像目标:Vuforia SDK 及其如何帮助提供 AR 体验

  • 帧标记: 这是一个带有代码嵌入其内部边缘的方形标记。Vuforia 提供了 100 个编码的帧标记供您使用,应用程序可以通过它们的编码数字检测它们,并在其上方显示 AR 内容。帧标记可以比图像目标小,我们可以在它们的边界内添加任何类型的图像,而无需担心它们能否被很好地跟踪。它适用于游戏配件或扑克牌。在性能影响最小的情况下,许多帧标记可以同时被跟踪。以下图像显示了帧标记图像:Vuforia SDK 及其如何帮助提供 AR 体验

  • 多目标: 多目标允许开发者从任何角度跟踪一个简单的物理盒子。盒子必须在其上具有适合的详细图像,并且必须是简单的形状。使用多目标甚至可以允许从物理对象遮挡 AR 内容。这意味着如果对象要围绕被跟踪的盒子旋转,它可以被开发成在通过被跟踪对象时 3D 内容被遮挡。

  • 虚拟按钮:虚拟按钮是一种有趣的技术,可以为整个 AR 体验增添价值。这个组件的作用是允许用户触摸可跟踪图像的物理部分,应用会对其做出响应。图像目标上可以有多个虚拟按钮,并且可以分配不同的事件。以下截图显示了虚拟按钮如何影响渲染对象的颜色:Vuforia SDK 和它如何帮助提供 AR 体验

随着 Vuforia 提供的一系列选项,现在大多数智能手机上都可以实现完整且丰富的 AR 体验。

在这本书中,我们将重点关注最灵活且最受欢迎的跟踪技术——图像目标。使用图像目标,可以提供一种自然的用户体验,因为可跟踪的图像非常相关。例如,可跟踪的图像可以是一则带有信息的广告,但如果通过 AR 应用查看,它会在图像上显示叠加的视频播放,就像图像栩栩如生一样。

图像目标的跟踪数据存储在称为数据集的实体中。在数据集中,存储了图像的数据,如边缘和对比度区域,ARCamera 会持续处理实时视频流,寻找与数据集中任何图像匹配的区域。当这种情况发生时,可跟踪物被认为在现实世界中已被找到,AR 内容会叠加。应用可以同时激活多个数据集。每个数据集最多可以包含 100 张图像。这对于应用实时处理的数据量来说是非常大的,这也展示了 Vuforia 的强大之处。

使用 Vuforia 目标管理器 创建图像目标的过程也非常简单,它可以从图像中创建数据集,甚至可以分配一个分数来衡量该图像跟踪效果的好坏。图像的可跟踪性取决于许多因素,主要是高对比度和清晰的边缘。以下图像展示了 Vuforia 目标管理器 网站:

Vuforia SDK 和它如何帮助提供 AR 体验

Vuforia 还提供了一系列图像目标行为的解决方案。它提供的一项服务是基于云的识别。高通提供的云识别服务使得应用能够同时拥有超过一百万个图像目标。它还允许更轻松地管理大量目标。这项服务非常适合需要经常更改的大型目标部署,例如为零售店创建 AR 购物体验。这项服务免费,但非商业用途限制在总共 1000 张图像,而商业用途则需要付费且无限制。

此外,Vuforia 允许用户在运行时从相机拍摄中创建一个用户定义的图像目标。这是一个非常通用的工具,它不会将用户绑定到可能不是每次都需要的目标图像。以下图片展示了 Vuforia 的用户定义目标示例应用:

Vuforia SDK 和它如何帮助提供 AR 体验

我们可以使用 SDK 中提供的许多优秀工具。我们将尝试涵盖基础知识,以便创建一个用户能够产生共鸣的明确 AR 体验。

Unity 3D 和它与 Vuforia 的兼容性

Unity 是由 Unity Technologies 开发的一个跨平台游戏引擎。该游戏引擎内置了 IDE 并具有部署到众多平台的能力。超过一百万的开发者正在使用 Unity,使其成为迄今为止行业中最受欢迎的游戏引擎。它旨在易于使用和高效生产。由于其相对容易的学习曲线以及它提供的免费版本,这促使一些学校将其作为游戏开发入门课程。

Unity 最大的优势是它能够轻松地将项目部署到大量平台,而无需对项目结构进行太多更改。Unity 的名字就来源于这种特定的优势。Unity 可以部署到 Windows、OS X、iOS、Android、Web 插件、Flash、Xbox 360、PlayStation 3 和 Wii U。这种广泛的覆盖范围在开发中使用 Unity 引擎时提供了很多机会。

Unity 允许您从三种语言中选择来编写脚本。可用的语言有 JavaScript、C# 或 Boo。Unity 随附一个定制的 MonoDevelop 版本,用于调试目的。在同一个项目中,可以使用这些语言中的任何一种来组合脚本,尽管建议在整个项目中只使用一种脚本语言,以避免任何冲突并使阅读和理解更加容易。在这本书中,我们将使用 C# 作为脚本语言。选择的原因是 Vuforia 使用 C# 编写脚本,这使得我们稍后将更容易与 Vuforia 脚本进行通信。此外,C# 是一种结构良好的语言,虽然它的学习曲线比 JavaScript 高,但它的鲁棒性更强,更不容易出错。它也是大多数专业工作室的首选语言。以下截图显示了 Unity 项目窗口:

Unity 3D 和它与 Vuforia 的兼容性

对于初学者来说,前面的截图可能会令人望而生畏,但通过这本书,我们将介绍 Unity 引擎的许多基础知识。在书中,我们将介绍如何创建新项目以及部署到 iOS 设备所需的部署过程。我们还将通过制作简单的 AR 游戏,介绍一些游戏开发技术,并说明用户如何与 AR 内容进行交互。

尽管 Vuforia 提供了一个我们可以用来创建 AR 应用的 OpenGL SDK,而无需使用 Unity,但 Unity 提供了许多仅使用 OpenGL 就无法在短时间内创建的工具。Unity 是一个游戏引擎,提供了许多工具,可以使 3D 内容看起来非常出色和逼真。在 iTunes 市场上,一些看起来最好的 iPhone 和 iPad 游戏都是使用 Unity 引擎制作的。其中一些游戏是 Dead Trigger 和 Shadowgun,这两个游戏在平台上看起来都非常出色。

此外,Unity 通过其提供的强大结构极大地简化了游戏逻辑。它提供了一个窗口,让我们可以看到 3D 图形将如何精确地呈现,甚至交互将如何呈现。Unity 使用 Vuforia 可以利用摄像头检测可追踪对象,甚至显示 AR 内容在可追踪对象上的确切外观,而无需首先在设备上部署。这节省了大量时间,否则这些时间可能被浪费在设备上部署以发现 3D 内容在可追踪对象上看起来或表现不正确。

最近,Unity 放宽了他们的许可选项,允许任何人免费部署到 iOS 和 Android。我们不需要购买他们的许可证就能部署简单的 Vuforia 应用。尽管 Unity Pro 提供了许多强大的功能,但在我们这本书的课程中它们并不是必需的。

摘要

在本章中,我们介绍了增强现实的意义和可能性。这是一个非常激动人心的领域,本章对其进行了简要介绍。我们了解了增强现实的多种形式以及它如何以智能手机的形式在用户手中体现出来。我们还了解到增强现实在为用户提供沉浸式体验方面是多么强大。

我们介绍了 Vuforia,这是高通提供的免费 AR SDK。我们了解到它如何能够提高为用户创建 AR 应用的流程。通过处理 AR 的技术细节,它让我们能够专注于创造更好的体验。我们知道 Vuforia 提供了许多跟踪技术,以及每种技术可以提供不同的体验。这应该使我们能够在未来更好地利用它们。

我们介绍了 Unity,我们对这个引擎的强大功能有一个模糊的认识,或者它如何使我们作为开发者能够以我们希望的方式创造性地构建 AR 体验。在本书中,我们将进一步探索 Unity 的表面力量。虽然我们无法在本书中涵盖 Unity 的所有内容,但我们将看到一些简单的组件知识如何创建令人印象深刻的 AR 应用。

在下一章中,我们将介绍如何设置我们的环境以开始创建 AR 应用。我们将设置 Unity 和 Vuforia,以便更好地理解它们如何协同工作。我们还将部署 Vuforia 示例应用到设备上,以测试最终应用的外观。

第二章 设置环境

在本章中,我们将介绍设置增强现实所需的环境,并部署我们的第一个工作增强现实应用。我们将了解最终产品的感觉以及如何部署它们。本章将简要介绍 Unity 平台设置和 Vuforia 预制件。然而,本章不会涵盖 iOS Apple 配置和 Xcode 管理,因为它们超出了本书的范围。

下载和安装 Unity 3D

在 Mac OS X 上下载和安装 Unity 的过程相当简单。只需访问其网站,下载 iOS 和 Android 的免费试用版,我们就可以在有限的时间内免费获得 Unity 大部分功能。要下载,请使用以下链接:unity3d.com/unity/download/。请注意,iOS 只能在 Mac OS X 上部署。

以下图片显示了带有免费试用版的 Unity 网站:

下载和安装 Unity 3D

下载 Unity 后,安装过程相当直接。我们可以选择试用版来试用具有更多功能的 Unity Pro。免费版仍允许我们将应用部署到 Android 和 iOS,但 Pro 版本包括着色器和播放视频文件。有关 Pro 版本包含内容的更多信息,请查看 Unity 网站。

下载和安装 Vuforia

Vuforia 在简化 SDK 安装过程和简化其工作流程上做了很多努力,以便不会让新开发者感到害怕。我们将介绍在 Mac OS X 上安装 Vuforia SDK 的过程,为部署我们的第一个增强现实应用做准备。

Vuforia 提供了多种不同的 SDK 版本,一开始可能会让人感到困惑;因此,我们将介绍它们:

  • Android 原生 SDK,用于与 Eclipse 和 Ant 一起部署在 Android 设备上,无需使用 Unity

  • 用于在 iOS 设备上使用 Xcode 部署,无需使用 Unity 的 iOS 原生 SDK

  • 用于在 Android 或 iOS 上部署的 Unity 扩展,用于在 Android 或 iOS 上使用 Unity 的跨平台功能

本书将涵盖 Vuforia Unity 的扩展。要下载它,请访问以下链接:

developer.vuforia.com/resources/sdk/unity

在下载 SDK 之前,有一个简单的注册过程。以下截图显示了 Vuforia SDK Unity 扩展:

下载和安装 Vuforia

下载文件是一个 Unity 包文件,正如我们很快就会看到的,它非常容易添加到 Unity 项目中。SDK 不需要其他文件。有了这个,我们就有了开始开发 iOS AR 应用所需的一切。Unity,这个将帮助我们渲染 3D 对象和游戏逻辑的游戏引擎,Vuforia 将提供增强现实组件,而 Xcode 将最终在设备上部署应用。

Vuforia 示例项目

Vuforia 为他们拥有的每个 SDK 版本提供了一个相当丰富多彩的示例项目,供用户了解 SDK 的使用方式。我们将利用这些示例项目作为我们了解一个完成的 Vuforia 项目的结构和如何在 iOS 和 Android 设备上部署它的入门点。

Vuforia 提供了他们的示例项目作为包。这个包包含了许多适用于 Vuforia SDK 的应用程序,但在这本书中我们将专注于图像目标。让我们从以下链接下载示例项目 developer.vuforia.com/resources/sample-apps

以下截图显示了 Vuforia 示例应用程序:

Vuforia sample projects

在下载压缩的项目样本后,解压缩文件夹并查看其内容。文件夹将包含许多名为 packages 的文件。这些文件基本上是 Unity 文件,可以轻松导入到 Unity 项目中。

开始一个 Unity 项目

现在我们已经下载了所有需要的文件,是时候开始一个 Unity 项目了。启动 Unity,从 文件 菜单中选择一个新项目。将项目放置在任何你想要的位置,但确保项目名称中不包含任何空格,以避免以后出现问题。你将看到 Unity 的项目窗口。这可能有点令人畏惧,如果你是第一次使用游戏引擎,可能会感觉有些陌生,但我们在构建项目的过程中会熟悉它。以下截图显示了 Unity 项目窗口。

Unity 场景

以下截图显示了 Unity 场景:

Unity scenes

我们将首先熟悉的概念是场景。场景主要是游戏关卡,所有内容都是在这里构建的。它是运行时加载并呈现给用户的内容。它包含所有游戏对象,如菜单和 3D 模型。这是我们为用户创建的世界。我们可以有多个场景,就像游戏有多个关卡一样。

如前截图所示,层次结构场景层次结构)表示场景中的对象及其相互之间的关系。例如,一个立方体对象可以是球体对象的父对象;这样,当立方体对象移动时,球体对象将跟随它。这对于构建复杂对象,例如汽车,特别有用,并且汽车部件会随着父对象一起移动,而不是单独移动。这个概念对于 Vuforia 在 Unity 中的工作方式非常重要和基本。

游戏游戏渲染)窗口是 Unity 中一个相当有用的工具。它提供了游戏工作方式和外观的预览,无需部署,节省了大量时间。当点击顶部的播放按钮并“运行”游戏时,任何脚本或场景场景编辑器)中的更改都会立即显示。这允许我们在不首先在设备上部署的情况下看到增强现实体验是如何进行的。

项目项目资源)面板是所有项目资源所在的地方。这是将模型和纹理导入到项目中,甚至导入 Vuforia SDK 的地方。这也是存储所有应用程序脚本的地方。始终保持资源文件夹的有序性和遵循一定的约定至关重要。如果项目资源层次结构没有遵循,项目可能会变得更大,跟踪资源的位置可能会非常困难。

检查器检查器面板)是调整组件和资源的地方。它显示项目层次结构中当前选定的场景对象的所有设置或来自项目项目资源)面板的资源。检查器是一个多功能的工具,在构建项目时被广泛使用。

现在 Unity 的 GUI 已经不再神秘,我们可以查看从 Vuforia 下载的示例项目文件夹。它将包含代表项目的多个包文件。包文件对于 Unity 来说非常重要。在游戏开发中,从一个项目传输资源到另一个项目的情况并不少见。通常,项目之间会共享公共资源,因此 Unity 需要一种高效的方法来在项目之间传输资源。这就是为什么 Unity 包文件应运而生。

在 Unity 中,可以选择从资源商店中选取某些文件,甚至整个场景,将其导出为包文件。有时整个项目也可以导出为包文件。稍后,该文件可以被导入到 Unity 项目中并立即使用。

Vuforia 示例项目以 Unity 包的形式存在,必须导入到 Unity 项目中才能部署这些项目。值得一提的是,Vuforia 的 SDK 也以 Unity 包的形式提供,可以导入到任何项目中并利用其 AR 组件。

Unity 中导入包

现在我们将示例项目导入到我们创建的 Unity 项目中。以下截图显示了 Unity 导入ImageTarget示例项目:

Unity 中导入包

导入包是一个相当简单的过程。前往顶部的资产菜单,选择导入包,然后选择自定义包。导航到 Vuforia 的示例项目所在位置,选择图像目标文件。将显示一个类似于之前截图的窗口。

这个窗口非常重要,因为它显示了正在导入到项目中的信息。我们可以选择我们想要导入的文件和不想导入的文件。它还会显示文件是否是新的,即尚未在项目中,或者旧的,意味着它已经在我们的资产文件夹中并且正在更新。目前我们需要包文件中的所有文件,所以请继续点击导入。以下截图显示了导入ImageTarget后的 Unity 项目:

在 Unity 中导入包

我们可以看到,许多文件已经导入到我们的资产文件夹中,包括一个高通增强现实文件夹,这是 Vuforia SDK。这是我们需要的所有可部署项目的文件,但场景层次结构仍然只包含一个主相机对象,而游戏面板仍然相当蓝色。这是因为我们已经加载了资产,但还没有加载场景文件。

Unity 场景文件

场景文件基本上是 Unity 存储场景层次结构和组合的方式。场景文件包含了编辑器中创建的世界及其所有细节。这在加载不同时间点的不同场景文件以及在同一应用程序中创建多个相关或不相关的世界时非常有用。这就是 Unity 处理多个游戏关卡和区域的方式。

现在要选择高通为我们创建的项目场景文件,我们可以转到项目文件中的场景文件夹,并双击名为Vuforia-4-ImageTargets的文件。以下截图显示了Vuforia-4-ImageTargets场景处于活动状态:

Unity 场景文件

现在 Unity 项目视图看起来更加生动。在游戏面板中已经可以看到渲染好的 3D 茶壶,而层次面板显示了场景的组件。很可能会发现场景编辑器仍然看起来像前面的图示那样空空如也;我们现在将看到如何导航到场景编辑器视图来在世界中移动。

我们需要做的第一件事是关注场景中我们拥有的一个对象,将其作为原点。我们可以通过从层次面板中选择第一个图像目标对象来实现,即ImageTargetChips,然后将鼠标指针放在场景面板上并按下键盘上的F键。这将放大对象,使其成为编辑器视图的原点。重要的是要将鼠标指针放在场景面板上,否则缩放不会在对象上发生。以下截图显示了选中的对象:

Unity 场景文件

现在对象已经聚焦,我们可以让编辑器相机围绕它旋转以在游戏中查看场景。我们可以通过按住Alt键并在场景上拖动来定位编辑器相机到任何我们想要的位置。我们还可以使用鼠标滚轮来放大和缩小聚焦的对象。

如我们所见,场景由三个不同的茶壶组成,它们位于一个带有图像的平面上。这是样本项目中的 AR 场景,它将根据ARCamera检测到的图像目标显示其中一个茶壶。对象的缩放和变换将与场景编辑器中相对于茶壶所在图像目标当前可见的变换相匹配。这使得在构建过程中可视化 AR 体验的播放方式变得非常容易。

可追踪文件

在项目文件夹中,我们将找到本项目中使用的可追踪图像。我们需要将它们打印出来以测试 AR 体验。要访问它们,导航到资产 | 编辑器 | QCAR | ImageTargetEditor。在里面将有两个文件夹,包含场景中使用的三个图像。要打开它们,在图像上右键单击并选择在 Finder 中显示以在 Mac OS X Finder 中打开文件。以下截图显示了项目中的目标图像位置:

可追踪文件

在打印图像时,确保它们填满整个页面,以获得最佳的 AR 体验效果。

Vuforia 有一个方便的功能,允许我们在不首先部署的情况下查看 AR 体验。这是通过在使用的 PC 上放置一个摄像头,Unity 利用摄像头的信息在游戏面板中显示体验的播放方式来实现的。这对于在不浪费部署周期的时间的情况下调试 AR 项目来说是必不可少的。

要利用此功能,只需单击 Unity 项目窗口顶部的播放按钮。以下截图显示了实时摄像头流的 AR:

可追踪文件

通过将目标图像放在相机前,Vuforia 将识别可追踪的图像,然后根据目标图像定位ARCamera对象并渲染 3D 内容。如果我们从层次面板中点击ARCamera组件,我们可以看到 ARCamera 随着目标图像在摄像头前移动而动态移动并相对于目标移动。

ARCamera实际上是通过用户可以查看我们在 Unity 内部创建的世界的窗口。通过将摄像头相对于目标图像移动,我们可以有效地模拟茶壶是真实世界的一部分。

尝试不同的目标,看看它们如何通过显示不同的茶壶以不同的方式响应。

当我们打开场景文件夹时,我们发现有很多场景。我们只选择了主场景,但现在我们需要了解其他场景的用途。

再次从资产文件夹中打开场景文件夹。这四个场景的命名如下

  • Vuforia-1-SplashScreen

  • Vuforia-2-AboutScreen

  • Vuforia-3-LoadingScene

  • Vuforia-4-ImageTargets

应用很少只有一个场景;通常它们是一系列场景的集合。对于这个示例项目,应用使用了四个场景。首先出现在用户面前的场景是SplashScreen场景。启动屏幕只会做它名字所暗示的事情;它将为用户显示启动屏幕两秒钟,然后它会自动加载下一个场景,即AboutScreen

AboutScreen场景将显示关于应用的屏幕。它将有一个按钮来关闭关于屏幕并加载下一个场景,即LoadingScene

加载场景执行一个简单的任务,即在后台加载主场景ImageTarget,并显示一个动画旋转器以指示正在加载。在加载大型场景时,这总是一个好主意。如果没有它,应用在加载下一个场景时似乎会冻结几秒钟;这可能会让用户认为应用崩溃或无响应。

如我们所见,四个场景的顺序构成了整个应用体验。您可以随意打开任何场景文件并点击播放按钮,以查看它们如何单独运行。但如果我们这样做,我们会注意到场景在动作完成后不会加载其后的任何场景;这是因为我们没有告诉 Unity 在应用启动时加载哪些场景文件。目前如果我们部署,设备上只会显示一个蓝色屏幕,因为没有加载任何场景。

构建设置

要标记应用中要加载的场景,我们需要访问构建设置窗口。为此,导航到文件 | 构建设置。以下截图显示了构建设置窗口:

构建设置

构建设置窗口在 Unity 中非常重要。从那里,我们可以控制我们正在部署的平台,要包含在部署中的场景,平台特定的设置,甚至可以直接从那里在平台上部署。

窗口顶部的框是标记场景以包含在应用中的地方。应用将使用的任何场景都必须在构建设置窗口中添加,以便在平台上工作。我们现在将添加我们的场景,但首先确保框中没有场景。如果没有指定场景,场景有时会自动添加。Unity 这样做是为了避免部署没有场景的构建。要删除任何场景,点击它并在键盘上按退格键。

非常重要的是要知道,窗口中的第一个场景将是应用首先打开的场景。这一点非常重要,否则应用流程将会出错。在我们的例子中,SplashScreen场景是第一个。它加载关于屏幕之后。这意味着我们需要首先添加SplashScreen场景,以便应用打开;之后场景的顺序并不重要,因为加载是通过项目中场景的名称来完成的。

要添加场景,只需将场景文件从场景文件夹拖动到窗口中。确保在添加任何其他场景之前先添加SplashScreen场景。添加所有四个场景。以下截图显示了构建设置

构建设置

注意构建中场景旁边的数字;它们是场景的数值表示,可以用作加载场景而不是它们的名称。数字0代表应用将自动加载的第一个场景。

为 Android 部署

我们将在本节中为 Android 进行部署;如果出于任何原因您选择不在该平台上部署,您可以跳转到处理 iOS 的下一节。

现在我们已经将所有场景添加到构建中的场景中,我们继续进行其他设置,为部署做准备。在构建中的场景窗口下,有一个名为平台的有趣框,里面收集了多种知名平台。这些是 Unity 可以部署项目的平台。如果我们没有从 Unity 部署到它们的许可证,其中一些将变为灰色。默认情况下,PC、Mac 和 Linux 独立平台被选中。这显然不是我们的目标平台,所以我们继续更改它。

选择Android平台,然后点击左下角的切换平台按钮。这将启动自动将所有资产转换为适合我们刚刚选择的平台的进程。

一旦 Unity 完成处理资产,点击玩家设置...按钮。在检查器面板中,我们将找到类似于以下截图的内容:

为 Android 部署

玩家设置揭示了特定于目标平台的设置,例如应用名称、启动画面、图标等。为每个我们部署的平台正确自定义设置非常重要,以实现更好的结果。

产品名称字段中的应用名称更改为Image Target。我们现在不会自定义图标和启动画面图像,尽管知道您可以从这里进行自定义。

在面板中特别隐藏的最重要设置之一是应用的标识字段。我们知道这对于应用在市场上保持其身份很重要,并且记住正确设置它很重要。要到达该设置,请点击以下图示中的其他设置

为 Android 部署

包标识符更改为适合应用的名称。请注意,其他设置都处理与平台相关的非常低级别的设置,例如 API 级别和要使用的 OpenGL。我们可以暂时将其保留为默认设置,它将在大多数设备上工作,但了解将来如何到达这些设置是有益的。

如我们所知,Android 应用使用密钥库进行部署。Unity 使创建密钥库的过程变得稍微简单一些。要访问密钥库设置,请点击如下截图所示的 发布设置

部署到 Android

现在选择 创建新密钥库,然后在两个字段中输入任何密码,如前述截图所示。这将告诉 Unity 为我们创建一个新的密钥库并在部署时使用它。需要注意的是,Unity 不会为我们存储密码;如果我们重启 Unity,我们必须在此处重新输入密码,否则构建将失败。

现在一切准备就绪,我们只需点击 构建和运行 来部署应用。它将询问我们保存 APK 的位置;任何地方都可以。应用将通过 USB 连接到机器的 Android 设备进行部署,因此我们需要确保它已正确连接。

如果 Unity 无法识别连接的 Android 设备,请确保已正确安装特定设备的 USB 驱动程序。它们可以在制造商的网站上找到。

部署到 iOS

选择 iOS 平台,然后点击左下角的 切换平台 按钮。你会注意到 Unity 正在重新构建和重新导入某些资源。这个过程是为了匹配目标平台的压缩方案和设置。这是一个 Unity 自动处理得很好的自动过程。

当 Unity 完成所有资源的再次导入后,就是时候继续调整我们的设置,以便在设备上构建项目了。在底部,有一个名为 Player Settings... 的按钮。点击此按钮,你会看到如下截图所示的内容:

部署到 iOS

与 Android 一样,PlayerSettings 是所有预期平台特定设置的集中地。现在我们已经切换到 iOS 平台,它将包括任何特定于 iOS 的设置。

首先,让我们更改应用名称。在 产品名称 中,将其更改为 Image Target。我们现在将保留默认图标和启动画面。现在我们调整 分辨率和展示 设置。点击 分辨率和展示 栏以展开设置区域。

默认方向 部分,从下拉框中选择 自动旋转 选项。它将在其下方展开一个复选框列表。取消选中第一个复选框,即 使用动画自动旋转。以下截图显示了 分辨率和展示 部分:

部署到 iOS

分辨率和展示 设置处理应用向用户展示的方式。它包括诸如支持设备方向和状态栏可见性等选项。我们刚刚为应用启用了自动旋转选项。我们还禁用了 使用动画自动旋转,因为这对于 AR 体验来说从来都不好看。这通常会让用户感到方向感混乱。

现在我们需要做的是设置应用的捆绑标识符。苹果开发者配置文件是按应用标识符发放的,其结构如下:

com.公司.产品名称

根据你的 Xcode 管理的配置文件公司名称,你需要在 Unity 设置中输入你的名称,以便通过 Xcode 进行部署。

要访问捆绑标识符设置,点击 检查器 区域底部最下面的另一个栏,并将 捆绑标识符 改为 Xcode 可以接受的正确名称。以下截图显示了 捆绑标识符 设置:

为 iOS 部署

现在我们已经完成了所有必要的设置,是时候将应用部署到设备上了。由于 Unity 强大的跨平台能力,部署过程非常简单。这个过程主要是自动的,几乎不需要开发者的干预。

首先,将设备连接到电脑。现在我们点击 构建和运行 按钮,在 构建设置 窗口的右下角。它会询问你希望将构建文件夹放在哪里;将其放在 Unity 项目文件夹内即可,但不要放在 Assets 文件夹内。给它起任何你喜欢的名字;不过,按照 Unity 项目文件夹的名字命名是个好习惯。

Unity 将自动开始为 iOS 构建项目的进程。它也会自动打开 Xcode。请尽量在进程结束前不要干扰这个过程。从 Unity 打开 Xcode 的过程是通过一个脚本完成的,该脚本切换焦点窗口并在 Xcode 上执行某些步骤。因此,最好让 Unity 控制你的电脑直到完成,不要切换到任何其他窗口。

在 Xcode 将应用复制到设备后,我们应该在我们的设备上找到一个完美工作的 AR 应用。应用将按预期工作,并展示 Unity 和 Vuforia 组合的强大功能。

以下截图显示了 Image Target 应用的 关于 屏幕:

为 iOS 部署

注意,当 Unity 部署到 Xcode 时,它会自动在打开的窗口之间切换并执行 Xcode 上的多个脚本。这就是为什么我们需要让 Unity 执行其常规操作,并让它控制桌面直到开始构建。如果我们强制阻止它自动切换到 Xcode,它将中断自动构建。注意,之后可以手动恢复。

摘要

在本章中,我们介绍了设置我们环境的过程。我们安装了 Unity 和 Vuforia。我们了解了 Unity 的 GUI 并开始了一个新项目。我们导入了 Vuforia 的示例应用,并看到了如何将其部署到我们的设备上。在这个过程中,我们介绍了与应用部署相关的许多 Unity 设置,以及一些 Vuforia 的基本功能。

通过这种方式,我们熟悉了部署的过程以及最终产品的样子。我们已经搭建了环境,能够使用 Vuforia 和 Unity 来构建 AR 应用,并看到了在目标设备上部署是多么简单。我们了解了 Unity 环境的简单设置,并为深入了解如何构建自己的场景和自己的 AR 体验奠定了基础。

在下一章中,我们将开始更熟悉 Vuforia,以及如何从头开始启动一个项目。

第三章:理解 Vuforia

在本章中,我们将介绍 Vuforia SDK 提供的组件以及如何构建 AR 场景。将 SDK 添加到项目中的方法以及如何包含和激活应用中要识别的可追踪数据将得到介绍。我们将从头创建一个非常简单的项目,类似于 Vuforia 提供的示例项目,以了解所有组件是如何组合在一起的。

使用 Vuforia 创建 Unity 项目

从上一章,我们知道如何从 Unity 中轻松创建一个项目。不要忘记在项目名称中排除任何空格。这将创建一个空项目,我们可以在其上构建我们的 AR 应用。

默认情况下,Unity 项目是预设为 PC 和 Mac 独立平台的。我们需要将其更改为 iOS。当前平台始终在窗口标题栏的顶部可见。

小贴士

下载示例代码

您可以从您在www.packtpub.com的账户下载您购买的所有 Packt 书籍的示例代码文件。如果您在其他地方购买了这本书,您可以访问www.packtpub.com/support并注册,以便将文件直接通过电子邮件发送给您。

以下截图显示了平台切换。

使用 Vuforia 创建 Unity 项目

在切换平台后,是时候将 Vuforia SDK 添加到我们的项目中了。为此,点击菜单栏中的资产菜单,然后在导入包 ...内部点击自定义包。这正是我们将 Vuforia 示例项目导入到我们项目中的方式。

现在找到 Vuforia SDK 的安装位置,并选择要导入到项目中的 Vuforia Unity 包。以下截图显示了导入 Vuforia 包的过程:

使用 Vuforia 创建 Unity 项目

现在已经将整个 Vuforia 库添加到项目中,我们可以开始查看它所包含的组件。所有构成 Vuforia 项目的组件都在项目中的Qualcomm 增强现实文件夹内。这个文件夹将包含控制 AR 体验行为的所有脚本。不仅包括脚本,还有一些着色器和纹理。它们主要用于 AR 应用的视频背景渲染。

幸运的是,我们不必直接处理大多数这些脚本,因为 Vuforia 将必要的组件捆绑在 Unity 预制件中,可以直接将其拖放到场景中。

Vuforia 预制件

预制件本质上是一种在 Unity 中创建的资产类型,用作可重复使用的游戏对象,存储在项目视图中。预制件可以插入到场景中任意多次,并应用任何对象变换。当添加到场景中时,它们基本上是原始预制件的实例,并与其链接。当对原始预制件应用更改时,所有其实例都将复制它,因为它们本质上是其克隆。

预制件是 Unity 不可或缺的工具。它使得创建标准场景组件变得容易得多。想象一下,如果我们正在制作一个包含许多非玩家角色敌人的游戏。手动构建每一个敌人将花费很多时间,但如果我们创建一个单独的敌人预制件并多次克隆它,这将使构建场景变得容易得多。此外,如果我们想要编辑整个敌人 NPC,我们只需编辑预制件,更改就会传播。

Unity 预制件还使得在项目之间共享组件变得容易,如果它们要导出为 Unity 包。这正是高通公司对 Vuforia 组件所做的事情。构成 AR 场景的所有组件都存储为预制件,随时可以拖放到场景中;我们只需调整其参数即可。

所有 Vuforia 预制件都可以在Qualcomm Augmented Reality文件夹中的Prefabs文件夹内找到。以下截图显示了Qualcomm Augmented Reality Prefabs文件夹:

Vuforia prefabs

Prefabs文件夹内,我们将找到之前解释的所有组件,例如ImageTarget预制件和FrameMarker预制件。我们还将找到ARCamera预制件,这是任何类型 AR 应用中的共同点。

默认情况下,当 Unity 创建一个新的场景时,它会向场景中添加一个相机,例如在Hierarchy面板中显示的那个。在我们的案例中,我们将使用 Vuforia 的专用ARCamera预制件。因此,我们需要首先从Hierarchy面板中删除Main Camera对象。

简单地从场景的Hierarchy中选择Main Camera,然后右键单击它,然后点击Delete。现在将ARCamera预制件拖放到场景中。场景的任何位置都可以。现在为了关注其位置,从Hierarchy面板中选择ARCamera,并按住F键盘键直到焦点在其上。当按住F键时,确保鼠标指针在场景面板上,否则焦点将不起作用。以下截图显示了添加到场景中的ARCamera预制件:

Vuforia prefabs

添加其余组件同样简单。现在我们已经将一个ARCamera预制件添加到场景中,我们还需要将ImageTarget预制件也添加到场景中。将ImageTarget预制件拖放到场景的任何位置。

这个预制件是我们将添加 3D 内容的平台。它还将持有应用程序将跟踪以定位ARCamera的方式,正如我们在示例应用中看到的那样。以下截图显示了添加到场景中的ImageTarget预制件:

Vuforia prefabs

根据将 ImageTarget 预制体放置在场景中的位置,变换部分中显示的游戏世界中的位置将不同。变换基本上是游戏对象在游戏世界中的位置。变换包含三个不同的向量,分别代表对象位置的不同数据。这些数据如下:

  • 位置:这是对象在三个轴(x、y 和 z)上的位置

  • 旋转:这是对象在三个轴(x、y 和 z)上的旋转

  • 缩放:这是对象与游戏世界中原始大小相比的尺寸比例

对象可以在世界的任何地方,但建议将世界的地板保持在 y=0。通过将地板保持在 0,当通过脚本更改对象的变换时,它将大大简化代码的许多其他方面。因此,现在将所有 ImageTarget 的位置更改为 (x=0y=0z=0)。这将使对象位于世界的原点,并简化后续游戏对象的定位方面。以下截图显示了图像目标检查器:

Vuforia 预制体

如检查器所示,有许多针对 Image Target 的设置,一开始可能会让人感到有些令人畏惧。其中之一是名为 Image Target 行为(脚本) 的组件,如上图所示;它负责将图像目标数据附加到图像目标对象上。目前,它还没有在应用中定义任何目标,因为我们还没有添加任何,因此图像目标的表示是白色的。

我们需要做的第一件事是将图像目标的数据添加到应用中。我们通过导入与书中内容一起提供的名为 exampleDataset.unitypackage 的数据集 Unity 包来实现。以导入所有其他 Unity 包相同的方式导入该包。以下截图显示了 exampleDataset.unityPackage

Vuforia 预制体

这个包本质上包含的是目标图像的数据,Vuforia 的跟踪算法可以从摄像头的视频流中有效地查找这些数据。它还携带了目标图像的纹理表示,以便在开发应用时在 Unity 编辑器中查看。

现在项目包含了跟踪数据,ImageTarget 预制体内部将出现一个新的选择,用于 Image Target 行为。我们将能够选择从目标包中导入的任何图像,并且 ImageTarget 预制体会立即采用它。

首先,我们需要选择包含图像的数据集。从下拉菜单中,我们可以选择唯一的可用数据集,名为 exampleDataset。从下面的下拉菜单中,我们可以选择特定的目标图像。选择目标图像石头。注意,游戏世界中的 ImageTarget 表示现在携带了目标图像。以下截图显示了数据集选择:

Vuforia 预制体

数据集本质上是一组图像目标,Vuforia 将同时跟踪其中任何图像。在我们导入的数据集中,我们有来自 Vuforia 示例项目的图像。应用将在任何给定时间跟踪所有三幅图像,直到找到任何图像来在其上渲染 3D 材质。

应用可以有多个数据集,每个数据集中可以有多达 100 个图像。这是 Vuforia 可以跟踪的大量图像。我们还有能力从编辑器或脚本中激活和停用任何数据集。

当我们将数据集添加到ImageTarget时,它立即在世界上表示了图像目标,但这并不一定意味着ARCamera会跟踪该数据集。为此,我们首先需要激活数据集,并告诉ARCamera开始跟踪该数据集。

层次结构面板中单击ARCamera对象。在检查器中,我们可以找到脚本组件数据集加载行为(脚本)。在该组件内部,将有一个带有标签加载数据集 exampleDataset的复选框。如果我们点击复选框,将出现另一个带有标签激活的复选框。也点击它。现在数据集已加载并激活。以下截图显示了在ARCamera中激活的数据集。

Vuforia prefabs

我们需要分别加载和激活数据集,这有一个特别的原因。如果添加到ARCamera组件,数据集将在场景开始时加载但不一定跟踪。从脚本中,我们可以然后启用和禁用任何数据集的跟踪,而无需加载开销。这种方式下,过程非常快。

现在我们知道 Vuforia 不仅知道要跟踪哪些可跟踪对象,而且正在积极跟踪它们。我们添加了ImageTarget预制件,并将其设置为Stones图像目标。如果我们按播放并给相机展示石头图像目标,除了控制台日志声明它已检测到图像目标外,不会发生任何事。我们甚至可能会注意到ARCamera在编辑器中疯狂地围绕图像目标在游戏世界中移动。这仅仅是因为我们还没有将任何 3D 内容附加到目标图像上。

导入和附加 3D 对象

Unity 能够从许多成熟的格式导入 3D 模型。模型可以从任何 3D 建模应用程序创建,例如 3D max、Maya 和 Blender。只要模型以 Unity 支持的格式导出,就可以轻松将其导入到项目中。

Unity 支持的格式如下:

  • Maya (.mb.ma)

  • 3D Studio Max (.max)

  • Cheetah 3D (.jas)

  • Cinema 4D (.c4d)

  • Blender (.blend)

  • Modo (.lxo)

  • Autodesk (.fbx)

  • COLLADA

  • Carrara

  • Lightwave

  • XSI 5.x

  • SketchUp Pro

  • Wings 3D

  • 3D studio (.3ds,在 Mac OSX 上不工作)

  • Wavefront (.obj)

  • 绘制交换文件(.dxf

列表相当广泛。可以相当安全地假设 Unity 将支持大多数已知的 3D 模型格式。注意,尽管如此,Unity 使用 3D 建模应用程序将模型格式转换为 FBX,然后可以被 Unity 导入。这个过程主要是自动的,并产生平滑的结果,大大简化了工作流程。

现在是时候将我们自己的 3D 模型添加到项目中了。首先,我们需要在项目中创建一个用于模型的文件夹。我们将使用它来包含项目中所有的模型。在Assets根文件夹中创建一个文件夹,并将其命名为Models

Assets菜单的顶部导入资产很容易完成。从菜单中选择Import New Asset,然后指向章节的资产文件夹并选择frog.fbx文件。Unity 将立即开始导入资产。以下截图显示了 Unity 导入的Frog资产:

导入并附加 3D 对象

现在我们已经在项目中有了 3D 模型,将模型添加到 Unity 项目是如此简单。这是一个好消息,因为对于游戏引擎来说,添加模型是项目中完成的最重要的任务之一。你在想为什么 3D 模型是青蛙吗?这是因为对于开发者来说,保持幽默感通常是件好事;这有助于。

当导入 3D 模型时,它为我们创建了两个文件夹和一个文件。这些文件夹包含 3D 模型的材质和 FBX 导入的设置。文件实际上是一个带有附加材质的 Unity 预制件,可以直接拖放到场景中。Unity 会自动为我们创建预制件。

现在我们可以将Frog预制件拖动并放入我们的场景中。青蛙 3D 模型将出现在我们的游戏世界中。以下截图显示了添加到场景中的青蛙模型:

导入并附加 3D 对象

就像当我们添加ImageTarget预制件时,青蛙在场景中的位置几乎肯定是不正确的。我们需要将其放置在ImageTarget的上方,并使其朝向正确的方向,但首先我们需要更好地估算其相对于ImageTarget的位置。记得当我们添加ImageTarget时,我们将其放置在游戏世界的原点(0,0,0)位置。我们将以青蛙作为第一步做同样的事情。

Hierarchy中选择青蛙,然后在Transform位置检查器面板中,将 x、y 和 z 设置为零。以下截图显示了青蛙在原点位置:

导入并附加 3D 对象

首先要注意青蛙的错误是它沉入了ImageTarget中。另一个问题是它对于ImageTarget来说太小了。

首先,我们将尝试将青蛙放置在ImageTarget上方。在 Unity 的左上角,确保您已选择方向十字按钮。这允许我们更改选中对象的位罝。注意从青蛙中伸出的绿色、蓝色和红色轴。它们是对象在游戏世界中的相对位置。绿色代表 y 轴,红色代表 x 轴,蓝色代表 z 轴。我们希望将对象在 y 轴上移动以使其位于ImageTarget上方。为此,只需拖动绿色轴并将鼠标向上移动;对象将随之一同上升。

将青蛙放置在ImageTarget的任何上方。现在不必完美。以下截图显示了青蛙在 y 轴上方的位置:

导入和附加 3D 对象

现在来看第二个问题,它的尺寸;我们需要将其放大很多才能适应ImageTarget

当青蛙被选中时,从左上角的菜单中点击缩放按钮。它是带有箭头从正方形中出来的最后一个图标右侧。

缩放按钮允许我们在场景中的任意轴或所有轴上缩放对象。由于我们需要对象在所有方向上均匀缩放以避免青蛙在一个方向上比另一个方向拉伸得更多,因此我们需要点击现在表示在物体上的三个轴原点处的正方形,然后拖动鼠标经过它。以下截图显示了放大后的青蛙对象:

导入和附加 3D 对象

在检查器中将缩放值设置为10应该足够,但由于没有约束,我们可以将其放大或缩小到我们想要的大小。

现在,我们需要使青蛙面向正确的方向,与它现在面向的方向相反。为此,我们需要在左上角的菜单中激活旋转按钮。

一旦激活旋转按钮,物体上的轴将看起来相当不同。首先,它们在本质上呈球形,而不仅仅是(x, y, 和 z)轴。

旋转功能与其他变换工具的外观不同,但工作方式相似。通过拖动(x, y, 和 z)轴,我们可以围绕任意一个轴旋转对象。剩余的白色轴是用于方便访问的对角旋转。

拖动绿色 y 轴以使物体朝向正确的方向旋转。注意检查器中的旋转数据在 y 轴周围变化。我们需要它达到180-180度。注意,我们只需在检查器的旋转部分输入那个数字即可达到相同的结果。以下截图显示了旋转后的青蛙对象:

导入和附加 3D 对象

现在青蛙已经旋转到相对于可追踪对象的方向正确,我们只需要将其位置提高,使其正好位于可追踪对象上方。我们可以用与之前相同的方式做到这一点。但这次我们需要更加小心,并且必须旋转编辑器相机几次,以确保青蛙从所有角度都定位正确。以下截图显示了正确定位的青蛙:

导入和附加 3D 对象

现在青蛙已经完美地定位在图像目标上方,一切正常。不过,你会注意到青蛙似乎颜色很暗淡。这主要是因为场景中没有任何光源;这正是我们接下来要添加的。

从顶部菜单中选择GameObject。从菜单中点击Create Other菜单下的Directional Light。这将在你的场景中添加一个名为 Directional Light 的对象。以下截图显示了添加到场景中的 Directional Light:

导入和附加 3D 对象

方向光是一种场景光,很容易添加且对设备资源便宜。它本质上就像太阳一样,照亮你指向的方向上的任何对象。我们只需要调整对象的旋转。它在游戏世界中的位置并不重要,因为它的光仅基于其方向,而不是其位置。

现在青蛙已经定位在我们想要的位置,看起来也很不错。我们可能会想现在就按下播放按钮来测试 AR 体验。如果我们这样做,并将可追踪对象展示给相机,青蛙将正确显示。但一旦可追踪对象从相机中丢失,我们会发现青蛙仍然停留在屏幕上。这是因为我们没有将青蛙与图像目标进行父化。

Unity 中的对象父化

Unity 的层次结构面板之所以被命名为这个名字,有一个很好的原因。那就是它代表了场景中对象的层次结构。如果我们点击层次结构面板中青蛙对象旁边的箭头,它将揭示其下的一组对象。这些对象实际上是青蛙对象的子对象。

父对象青蛙在层次结构下包含许多子对象,这本质上意味着子对象的变换将跟随父对象。当我们移动青蛙对象时,我们不需要单独移动子对象,它们会自动与父对象一起移动。这是幸运的,因为那样会花费很多时间。

在 Unity 中进行父化有多个原因。无论是脚本访问、变换还是简单的分组,Unity 的父化是一个非常重要的功能。

为了使图像目标能够正确工作,我们必须将它们作为任何它们将要显示的 3D 内容的父对象。这对于 Vuforia 能够控制何时以及如何显示 3D 内容以匹配图像目标来说是一个必须的条件。

要将其设置为父对象,我们只需将青蛙对象拖动并放置在层次结构面板中的ImageTarget对象上。以下截图显示了已设置为父对象的青蛙对象:

Unity 对象中的育儿

通过点击播放按钮来测试它后,我们的 AR 项目应该能够正常工作并正确显示青蛙。如果我们遵循上一章中解释的设置,我们可以在设备上部署它。

通过本章,我们学习了如何在 Unity 中从头开始构建 Vuforia 项目,如何导入和展示我们的 3D 对象,以及如何添加和设置 Vuforia 组件以正确显示它们。

摘要

在本章中,我们开始了我们的新 Unity 项目,并向我们介绍了添加 Vuforia SDK 后的项目。我们了解了术语 prefab 的含义,并探讨了 Vuforia SDK 内部包装的不同 prefab。我们看到了如何使用 Vuforia prefab 构建 AR 场景,特别是ARCamera prefab 和ImageTarget prefab。然后我们了解了将目标添加到项目中的方法以及如何在我们的项目中激活这些数据集。我们还看到了将 3D 模型添加到 Unity 项目并按我们的喜好在场景中定位以及添加适当光照的简便性。

在下一章中,我们将了解如何在目标管理器中创建我们自己的目标数据集,以及如何从我们选择的照片中获得最佳的目标结果。

第四章。可追踪项和追踪

可追踪项是 AR 体验的一个基本组成部分。它是我们构建的整个世界的基石。我们可以拥有世界上最好的 AR 内容,但如果可追踪项不适合,体验将大大降低。在本章中,我们将尝试了解如何创建和使用合适的可追踪项的细节。我们还将探讨如何修改可追踪项以增加其在应用程序中的可追踪性。

图像目标的可追踪项是什么?

可追踪项是 AR 应用程序可以追踪的一组特征。这可以是任何东西,从传统的二维码,其中一组黑白二进制代码决定了检测到的对象,到我们在上一章中体验到的图像目标,其中可追踪项只是一个图像。

对于图像目标,仅使用图像本身的自然特征作为在现实世界中检测图像的方式,并计算 AR 相机应该放置的位置。自然特征被分析、存储在数据库中,然后用于与相机输入流进行比较。这自然使得根据其特征,图像可以被跟踪得有多有效。

创建图像目标

使用 Vuforia 的 目标管理器 可以使这个过程变得简单。目标管理器是由高通提供的在线工具,它可以自动分析和创建用于在应用程序中部署的图像目标数据库。它还可以管理包含多个目标的多个数据集。

要到达这个目标管理器,只需访问以下网址:developer.vuforia.com/target-manager

以下屏幕截图显示了 目标管理器

创建图像目标

你应该会看到一个类似于上面的视图。这是目标管理器——我们将使用它来创建所有目标并维护它们的工具。目标管理器可以用于本地目标数据集和基于云的数据集。在这本书中,我们将专注于 设备数据库

首先,让我们创建一个数据库,我们将使用它来查看创建目标的过程。点击 创建数据库 按钮,并将数据库命名为第四章。以下图像显示了在 目标管理器 中创建的数据集:

创建图像目标

现在我们有一个数据集。目前我们的数据集是空的,但我们可以向数据集中添加多个图像目标,以便 AR 应用程序跟踪所有这些目标。我们甚至可以在这个视图中创建多个数据集,每个数据集都有自己的目标集。

现在我们需要做的是创建我们的第一个图像目标。首先,我们将使用之前在 Vuforia 示例项目中使用的石头图像。这将给我们一个关于如何创建示例项目的图像目标的思路。

点击数据库以打开它。我们将在右侧找到一个添加目标按钮;点击它。以下图像显示了目标创建:

创建图像目标

创建目标参数非常简单。对于名称,我们将选择“Stones”,就像在示例应用中一样。对于目标类型,我们将保持为“单张图像”。其他两种类型用于 Vuforia 中的多目标预制件,用于检测世界中的 3D 对象。

最后一个参数,目标尺寸,是一个重要的参数。这个数字是场景中图像目标的表现。它决定了出现在其上的对象如何缩放,以及它占据了场景中虚拟空间多少空间。换句话说,在 Unity 3D 环境中,这是一个很容易被忽略的值。这是由于 Unity 中可以轻松编辑的缩放属性。然而,在 OpenGL 环境中,这个值非常重要。目前,我们可以将其设置为 5 个单位。这是 Unity 3D 场景中的 5 个单位距离。

点击添加按钮,上传图像。目标将会有处理标签;处理需要几分钟时间。给它一些时间,然后点击目标以查看其详细信息窗口。以下图像显示了“Stones”目标的详细信息窗口:

创建图像目标

这是刚刚添加到数据库中的目标的详细信息窗口。在右侧,我们将找到有关目标的所有详细信息。它以目标在所有数据库中的唯一 ID 开始,包括基于云的和本地的。这对于目标的全球识别很有用。

目标 ID下方,我们将找到可增强分数。这是目标最重要的功能。它展示了目标在应用中的追踪效果。这个目标有 5 星中的 5 星;这是因为图像中的特征非常适合追踪。

可追踪分数

影响可追踪分数的因素有几个,但首先我们需要了解分数是如何影响图像的可追踪性的。

可增强分数基于 5 星。它如下表示增强性:

  • 4 到 5 星之间:可追踪目标非常适合 AR 应用。它可以处理部分图像被遮挡的情况,并且应用仍然能够追踪它。它也可以在低光和其他环境噪声中追踪。

  • 2 到 3 星之间:可追踪目标是可增强的。在理想条件下,它将运行良好。如果部分图像被遮挡,可能表现不佳。这是不会影响用户体验的最小分数目标。

  • 1 星:这是可追踪性的最低分数。这意味着图像将被应用识别,但体验会受到影响。务必避免获得这个分数。

  • 0 星:图像根本不适合可追踪性;图像中缺乏足够的可识别特征,使得应用无法识别。这个图像将完全不会被应用识别。

在追踪内容受限的情况下,并且我们知道在良好的光照和没有遮挡的情况下使用条件将是空闲的,我们可以争取 2 到 3 星。否则,最好争取 4 到 5 星,以便用户能够最优使用。任何低于 2 星的都应该完全避免。

什么决定了可追踪物的评分?

可追踪物是使用 Vuforia 进行 AR 体验的基础。理解和创建一个合适的可追踪物对于体验要稳健和有用至关重要。目标管理器中分配给可追踪物的分数是我们对目标图像将要表现出的稳健性的指示,但是什么决定了这个分数?

理解这一点的最好方式是了解 Vuforia 如何追踪图像。想法很简单;它在图像周围的所有集群中寻找对比边缘的位置。这些边缘被追踪,基于存储在数据集中的位置图,Vuforia 可以告诉可追踪物在现实世界中的相对位置,并相应地在其上方渲染 3D 内容。这特别意味着追踪图像并不是由其颜色或其中真正包含的内容决定的,而是由图像中对比边缘的数量以及它们在图像上的分布情况决定的。

为了更好地理解这一点,我们可以查看我们刚刚上传的图片中当前可识别的边缘。要做到这一点,只需简单地点击网页左上角的显示特征链接。以下图片显示了图像目标石头的特征:

什么决定了可追踪物的评分?

一旦点击了显示特征链接,图像目标管理器就会在目标图像上叠加一个覆盖层,显示它检测到的可识别边缘,这些边缘可以在 Vuforia 图像目标中进行追踪。注意,它只追踪石头之间的暗色边缘,而忽略图像中的其他部分。它甚至只追踪石头之间的高对比度边缘,而忽略一些较浅的边缘。

还要注意的是,图像中找到的边缘数量很多,并且均匀地分布在图像周围。这是使这张图像适合追踪的重要因素之一。

为了对比这张图片的结果,让我们尝试一个在目标管理器上尝试会得到 1 星评分的图片。以下图片显示了添加到目标图像中的景观图像:

什么决定了可追踪物的评分?

在添加这张图片之前,直观地,我们可能会认为这张图片适合追踪。它确实有很多广角景观的细节。但将这张图片添加到目标管理器后,得到了惊人的 1 星结果。

这张图片低分的主要原因在于整个图片都是绿色调。这极大地减弱了图片中的对比边缘。

如果我们点击顶部的显示特征链接,我们将能够看到目标管理器从图像中检测到的内容。以下图像显示了山景图像中的特征:

什么决定了可追踪的分数?

立即,我们注意到图像中检测到的特征数量比石头少得多。它只检测到了图像中物体阴影产生的边缘,这显然不足以给它评出超过 1 星的分数。

特征定义

为了帮助我们获得更高的分数,我们必须了解目标管理器正在寻找哪些特征。我们知道目标管理器在图像中寻找的主要是边缘,但具体是哪种边缘?为了理解这一点,我们需要了解特征的定义。

特征是图像中尖锐且刺状的细节,就像边缘的角落。特征必须非常对比鲜明才能被发现,并且必须均匀地分布在图像中,以随机的方式。以下图像显示了识别出的形状和特征:

特征定义

在上面所示的形状中,我们可以看到特征的黄色十字表示。表示如下:

  • 形状 1:它是一个完美的圆形,没有任何角落,因此,在它里面没有可识别的特征。

  • 形状 2:它左侧有一个边缘,有两个可识别的角落。这导致在形状中可识别的两个特征。

  • 形状 3:它是一个有四个边缘和四个角落的正方形。这导致在形状中有四个可识别的特征。

这意味着任何曲线物体几乎都不会产生特征。主要来说,由于人类和动物具有曲线性质,它们在可追踪性方面非常差。

通过增强对比度来提高分数

提高图像分数的最简单方法之一就是简单地增强图像的对比度。特征检测寻找像上面那样的尖锐边缘;当图像对比度低时,这样做非常困难。就像我们之前使用的风景图像一样,图像得分低的主要原因是图像对比度低。那么,当我们使用像 Photoshop 或 Gimp 这样的照片编辑应用程序增加图像的对比度和光级时会发生什么呢?以下图像显示了增强对比度的风景图像:

通过增强对比度来提高分数

分数从 1 星评分跃升至 4 星评分。如您所见,如果您将现在使用的图像与我们之前使用的图像进行比较,图像的对比度得到了极大的增强,目标管理器现在很容易检测到这样的阴影和边缘。让我们看看目标管理器检测到的特征。以下图像显示了高对比度图像中的特征:

通过增强对比度来提高分数

图像中检测到的特征远远多于之前图像中目标管理器找到的特征。大多数特征位于山和树影周围。注意绿色田野仍然产生很少的特征,但山和树木的特征足以产生 4 星的高分。

非常推荐增强用于 AR 应用的图像目标的对比度。拥有最佳的可追踪性对体验大有裨益。

图像目标上的特征分布

在图像上具有可识别的特征很重要,但它们的分布方式也同样重要。我们可以在图像的某一部分识别所有特征,而在另一部分则没有。这种不平衡会大大降低分数,因为它阻碍了 AR 应用在现实世界中检测图像相对位置的能力。例如,检查下面的图像目标。以下图像显示了湖泊目标:

图像目标上的特征分布

这是一张添加到图像目标管理器的湖泊图像目标。它有很多细节,但图像的左侧除了湖泊外几乎都是空的。这张图像得到了 2 星的评价,这是在增强图像对比度之后的结果。

要了解分数低的原因,让我们看看检测到的特征。以下图像显示了湖泊房屋目标中的特征:

图像目标上的特征分布

如预期的那样,检测到的所有特征都位于图像的右侧,而左侧则完全为空。这对 AR 应用中的遮挡管理和相对位置检测非常不利。它将进行跟踪,但目标将非常差。

如何增强特征分布

通过明显的方法增强特征分布,即向图像的空白空间添加对象。如果我们向上述图像的空侧添加纹理对象,新对象产生可检测的特征后,它自然会提高其分数。但如果对目标可以包含的内容有限制,那么在实际操作中改变目标的组成可能并不总是可行的选择。例如,如果目标是杂志或小册子的一部分,而我们无法控制可以向图像添加的内容。然而,我们始终可以控制从目标中移除什么。

如果我们能够从图像目标中移除空白空间,并取目标中细节丰富且特征分布良好的子集,我们就可以绕过这个问题。有趣的是,即使我们只提供子集的数据,AR 应用也会在大型图像上正常触发。例如,检查我们之前添加的湖泊目标的子集目标。以下图显示了湖泊图像目标的子集:

如何增强特征分布

如我们所见,上面的图像只是湖泊图像的一个子集,其中只可见湖泊房屋。现在,由于目标管理器可以聚焦于更小的区域,我们立即可以识别出更多特征。这也增强了图像上的特征分布。这使得这个可追踪目标的得分提升到 3 星。

AR 应用会触发到这个图像,无论它是以这个子集形式存在,还是在对湖泊房屋进行裁剪之前被原始图像所影响。这是在尝试为图像目标获得更高分数时需要记住的一个非常有用的功能。

AR 内容的定位需要根据相对于原始湖泊图像而不是子集进行调整。这可以通过在 Unity 中对 AR 内容的定位应用偏移量来轻松实现。

图像目标中的图案

我们现在明白在图像上需要有良好的特征分布,但有一点需要记住:图像上重复的图案只计算一次,这意味着如果我们整个图像目标上都有重复的图案,得分将会非常糟糕。请查看以下图像目标。以下图显示了雪花图案的图像目标:

图像目标中的图案

上述图像使用时得到的分数令人震惊,只有 0 星。这个图像主要是雪花的重复图案。如果我们检查检测到的特征,我们会看到如下图像。以下图显示了雪花图案中的特征:

图像目标中的图案

如我们所见,图像中检测到的特征足够多,可以有效地进行增强,但目标管理器却给它评了 0 星。从应用的角度来看,它将完全无法被检测到。

为了理解为什么会这样,我们需要问自己以下问题:如果我们从图像中心取一个子集,它是否与更大的图像可区分?答案是肯定的,图案在图像周围对称地重复。如果应用将检测到的特征与数据集中的特征进行比较,它将无法在现实世界中找到目标的相对位置。

将数据集导出到 Unity

现在我们知道了如何选择和创建我们的可追踪目标,将它们导出到 Unity 就变得容易多了。以下图显示了要导出的突出显示的目标:

将数据集导出到 Unity

从数据集的视图中,我们可以选择我们想要导出的目标。只需简单地选择任意数量的目标进行部署。一旦选择了目标,我们可以在左上角点击下载所选目标。以下图显示了下载所选目标

将数据集导出到 Unity

从开发选项列表中,选择Unity 编辑器作为选项。建议在目标管理器中保持数据库名称与目标名称相同,这样在以后更新数据集时会更加方便。这将下载一个我们可以轻松导入到项目中的 Unity 包文件,就像我们在示例项目中做的那样。

正如我们所看到的,在目标管理器中创建数据集相当简单,使得创建项目更加流畅。

摘要

在本章中,我们了解了使用高通的目标管理器创建自己的可追踪对象和数据集的过程。我们还探讨了如何设计和使用一个能够在我们应用中实现最佳追踪性的可追踪对象。我们看到了什么因素会使可追踪对象变得不好,例如图案和特征分布,以及什么因素会使它变得好,例如对比度和边缘。我们学到了一些提高我们可追踪对象追踪性评分的小技巧,例如从原始图像中取子集或在 Photoshop 或类似应用程序中增加对比度。有了这些知识,我们很容易优化 AR 最重要的基础,即我们的可追踪对象。

在下一章中,我们将从头开始创建一个将成为 AR 游戏的项目。技术和代码的级别将比本书迄今为止所探讨的更高,并将使我们更接近 Unity 和 Vuforia 的全部潜力。

第五章. 高级增强现实

在提供增强现实体验方面有很多可能性。在本章中,我们将讨论使用 Vuforia 与 Unity 结合时可用的大量高级功能。我们将通过开发一个小型街机增强现实游戏来实现这一点。这个游戏是一个经典的街机游戏,通过增强现实的变化使其感觉新鲜。我们将制作一个增强现实打地鼠游戏。

增强现实游戏

许多开发者误解了增强现实游戏的价值。许多人认为 AR 游戏由于大多数,如果不是所有 AR 游戏都无法病毒式传播且往往不畅销,因此无利可图且被边缘化。这可能是因为 AR 游戏往往需要动作、可追踪的物体,或者两者都需要,就像我们现在要制作的游戏一样。这些要求使得游戏不能在任何时候由用户玩,但很多人往往忽视的是,AR 游戏不病毒式传播是可以接受的。

AR 游戏,虽然不会产生下一个愤怒的小鸟,但可以为特定目的提供独特的体验。例如,AR 游戏可以非常有效地用于促销游戏。游戏可以在促销传单或杂志页面触发,然后产生一个竞争游戏,有机会赢得真实奖品,例如。这确保了用户以新鲜 AR 游戏的形式获得积极体验,同时,我们确信用户已经观看了促销并参与了比赛。AR 游戏也可以用于展览或商店的多种用途:促销或纯粹娱乐。

Unity 作为游戏引擎

当然,Unity 使得制作 AR 应用更加容易,并且可以部署到多个平台,但这并不是它的真正力量所在。Unity 首先是一个非常强大的现代游戏引擎。它被用来驱动一些行业知名的游戏,无论是在移动设备还是 PC 上。不利用这种力量来提供非常新鲜的 AR 体验是不可原谅的,因为理解引擎的工作方式相当容易。

在本章中,我们将介绍 Unity 中的一些元素,这些元素允许制作简单的游戏。我们将介绍如何向游戏添加音效,如何动画化对象,如何设置世界的物理,如何控制粒子效果,以及如何考虑用户交互。希望这足以展示在 Unity 中构建 AR 游戏的有效性。

设置环境

现在,我们可以开始创建我们正在制作的 Whack-A-Mole 游戏的新 Unity 项目。就像我们在书中之前做的那样,我们为 AR 应用设置了 Unity 的环境。以下步骤再次说明:

  1. Platform 的值从 File 菜单下的 Build Settings 修改为 IOS

  2. 通过导航到 Import Package | Assets 导入 Vuforia Unity 包。

  3. 导入之前在第三章中使用的exampleDataset.unitypackage文件,该文件包含可追踪数据的集,它们也包含在本章的资产中。

  4. Qualcomm 增强现实预制件文件夹中添加ARCameraImageTarget预制件。

  5. ImageTarget设置为使用我们导入的数据集,并在检查器中将其设置为使用Chips目标。

  6. ARCamera设置为加载我们的数据集并激活它。

  7. 将场景保存到资产文件夹中,并命名为Level

以下截图显示了为我们的 Whack-A-Mole 游戏创建的项目:

设置环境

我们应该对环境有类似的设置,如前述截图所示。现在它已经准备好,我们可以开始添加构成我们游戏的各种元素了。

Whack-A-Mole 游戏

在本节中,我们将讨论我们正在制作的游戏的架构。这是一个带有转折点的简单 Whack-A-Mole 游戏。在我们的目标上方,我们想要渲染一个充满地鼠洞的地面,地鼠会从这些洞中随机上下跳跃。用户将能够从设备向目标射击球,如果球击中地鼠,我们将通过音效使地鼠消失并产生粒子效果。

将不会有得分系统或清除关卡的方法。我们只是将这个游戏作为一个简单方式制作 AR 游戏的演示。本游戏中使用的所有资产都可在本章代码包的Assets文件夹中找到。

创建地鼠的地面

我们首先需要做的是创建一个基础层,这样地鼠就会从这个层中冒出来。我们需要创建一个平面,这个平面将直接覆盖在可追踪层上,并且附有一个地面纹理。

  1. 让我们从GameObject菜单创建一个平面。选择创建其他并点击Plane。这将创建一个场景中的平面。确保我们创建的平面与可追踪层具有相同的位置;两者都应位于全局原点,即(0, 0, 0)。

  2. 现在,通过点击左上角的工具栏上的调整大小按钮,像之前一样调整平面的尺寸。调整平面的宽度,使其正好覆盖可追踪层。平面的高度很可能比可追踪层大,但这没关系,只要可追踪层在场景中完全被覆盖即可。以下截图显示了 Z-缓冲区扭曲:创建地鼠的地面

我们可能已经注意到,在可追踪对象和我们刚刚添加的平面之间发生的扭曲。这是因为可追踪对象和平面在 y 轴上的位置完全相同。引擎不知道应该渲染在另一个之上,因此发生了所谓的 Z-Buffer 冲突,其中引擎不断在要渲染的组件之间交替。解决方案是简单地调整平面的 y 轴位置,使其略微高于可追踪对象的位置。

  1. 将平面命名为 Ground,并通过从 Hierarchy 列表拖动并放置到 ImageTarget 上来将其附加到可追踪对象上。

  2. 现在地面平面已经就位,我们首先会想要去除平面上默认的纯白色纹理。我们希望它看起来像真正的地面,因此我们将为其创建一个材质。Unity 的材质是组件,它们携带有关对象纹理和用于渲染它的着色器的信息。它非常重要,并且几乎在场景中的每个对象上都得到了广泛的应用。

  3. 首先,在 Unity 项目的 Assets 文件夹中创建两个文件夹。将其中一个命名为 Textures;这是我们将会保存材质纹理图像的地方,另一个命名为 Materials;这是我们将会创建材质的地方。

  4. 现在,将名为 Ground.jpg 的文件拖动并放置到我们刚刚创建的 Textures 文件夹中。我们也可以通过 Assets 菜单添加资产,就像之前看到的那样。这只是在项目中添加了地面的纹理图像。

  5. 现在,让我们创建材质;在刚刚创建的 Materials 文件夹中,从 Assets 菜单选择 Material。这会创建一个新的材质,我们将命名为 Ground。现在将我们创建的 Ground 材质附加到地面平面上。通过简单地拖动材质并将其放置在 Hierarchy 面板中的 Ground 平面上来完成此操作。

注意到平面保持白色,就像之前一样;这是因为我们还没有将纹理附加到材质上。为此,通过选择 Ground 平面并从 Inspector 中访问我们刚刚添加到 Ground 平面的材质;在这里我们将找到分配的 Material。在 Material 下有一个小的 Texture 属性,将我们之前添加的纹理拖动并放置到这个框中。以下截图显示了附加的 Ground 材质:

为老鼠创建地面

现在我们为我们的老鼠有了看起来不错的地面。请注意,该材质的着色器是 Diffuse。这种着色器适用于不透明材质,并且对于地面纹理来说效果非常好。稍后,我们可以为不同的材质使用不同的着色器以实现不同的效果,例如透明度或粒子着色器。

Whack-A-Mole 模型

现在我们有了可以建造的地面,是时候将我们的鼹鼠模型添加到项目中了。只需在Assets文件夹中创建一个文件夹,并将其命名为Models。将章节资源中名为WhackAMoleModel.fbx的文件拖放到文件夹中。Unity 将自动将模型导入到项目中,并为我们创建一个预制体。

  1. 就像我们之前做的那样,将为WhackAMoleModel创建的预制体拖放到我们的场景中。你可能不会自动看到模型被添加的位置;这主要是因为与地面平面相比,模型太小了。如果你通过按住F键来聚焦于模型,你会看到模型有多小。

    小贴士

    要改变这一点,我们可以使用之前的方法缩放模型,即从编辑器中进行缩放,或者我们可以更改 FBX 转换器的设置。FBX 转换器设置处理模型如何通过许多针对模型特定的设置插入到我们的场景中。如果我们要在编辑器中缩放模型,它将自然地没有模型与世界的 1:1 比例。这是实时进行的,占用资源,并使脚本编写更加复杂和令人沮丧。建议从模型设置中缩放对象。

  2. 在文件夹中单击模型的预制体,Inspector将显示FBX Converter设置。有一个缩放因子设置,默认设置为非常小的值,即0.01。这是模型相对于从 3D 建模应用程序中原始缩放的插入到场景中的大小。将此设置更改为0.7,然后单击应用。模型将在场景中自动调整大小,而不会改变场景本身的缩放变换。以下截图显示了缩放并定位在中间的WhackAMoleModelWhack-A-Mole 模型

  3. 将模型精确放置在地面的中心,并确保正确位于地面之上。之后,将WhackAMoleModel对象附加到Hierarchy中的ImageTarget,将其设置为父对象。

向场景添加碰撞器

Unity 为游戏中的对象模拟物理,但仅当我们指定要模拟的内容和方式时。这样做的原因是,在大多数游戏中,并非每个对象都由物理模拟。例如,并非每个游戏中的墙壁都是可破坏的。有一些静态对象只是在那里简单地违反物理定律,但对于游戏来说,这是完全可以接受的。

Collider是一个组件,我们可以将其附加到场景中的任何对象上,使该对象能够与其他可碰撞对象“碰撞”。例如,如果我们正在制作像使命召唤这样的射击游戏,如果我们没有将碰撞器附加到游戏中的所有墙上,游戏角色将能够简单地“穿过”墙壁。这当然是不希望的。

对于我们的游戏,我们需要能够“敲打”鼹鼠;如果鼹鼠上没有碰撞器,我们当然无法敲打它。此外,我们将要向鼹鼠射击的球体需要能够与地面碰撞,而不仅仅是穿过它。所有这些都可以通过碰撞器实现。

  1. 首先,从场景中选择WhackAMoleModel,并将其展开以显示MoleHill和角色。这些是我们需要添加碰撞器的两个组件。首先,从场景中选择角色,然后通过导航到Component | Physics选择Box Collider。这将添加一个围绕角色的盒子形状的碰撞器。盒子不会完全包裹角色,但它对资源的消耗很小,在我们的情况下足以模拟与我们将要向鼹鼠发射的球体良好的碰撞。

  2. 接下来,选择MoleHillMoleHill的形状不规则,我们需要球体与它的碰撞效果比盒子碰撞器能做得更有效。这就是为什么我们需要使用网格碰撞器。从相同的先前菜单,现在选择将Mesh Collider添加到MoleHill模型中。Mesh Collider的作用是添加一个与顶部模型形状完全相同的碰撞器,因此它模拟的碰撞与模型完全相同。

以下截图显示了添加到Mole模型中的碰撞器:

向场景添加碰撞器

注意,地面已经添加了碰撞器。这是因为,默认情况下,在编辑器中创建的任何原始对象都附有一个碰撞器。

为球枪创建球体

现在我们对游戏的整体感觉已经设定,我们需要创建枪的投射物。可以理解的是,因为这是一把球枪,所以它只会射击球体,我们可以通过脚本创建球体。但在我们能够这样做之前,我们需要一个脚本的角色模型来克隆并在场景中创建。所以,接下来我们将要处理的是创建枪的投射物预制件的基础。

  1. 层次面板中选择ARCamera,然后从GameObject菜单导航到Create | Other | Sphere。这将创建一个球体,位于ARCamera的位置;然而,它不会将其作为子对象添加到相机中。这在创建位于其他对象位置的对象时特别有用。将我们刚刚创建的球体的名称更改为Ball

  2. 现在,主要想法是让投射物占据至少相机视野的一半,并位于其中心,以便在向鼹鼠射击球体时给用户带来沉浸感。这很容易实现。只需将球体直接放置在相机前方,并调整其大小,直到你觉得它的大小适合相机。我们可以通过在编辑器中的Game面板或选择相机时场景面板右下角的Camera Preview来查看它将看起来有多大。

  3. 一旦位置和比例正确,在材质文件夹中创建一个材质,命名为ball。当选择这个材质时,在检查器中你会注意到一个默认设置为白色的颜色框。对于球体,我们不需要像地面那样的纹理,而只需要一种使其在环境中对比的颜色。所以,只需将颜色框设置为红色,然后将材质附加到球体上。以下截图显示了球体投射物在场景面板中的样子:为球体枪创建球体

注意到球体默认已经有一个碰撞器,这在我们需要球体实际与地鼠和地面碰撞时将非常有用。

有一个基本的事情需要指出;给对象添加碰撞器并不会使其在引擎中被物理模拟,它只会使其与其他碰撞器发生碰撞。但当然,我们希望投射物像真实投射物一样行动,并对重力及力做出反应。我们希望投射物以自然的方式从地板和地鼠上弹跳。这很容易在 Unity 中模拟,但我们需要告诉 Unity 要模拟什么以及如何模拟。

层次面板中选择球体对象,然后在组件菜单中,转到物理,并选择刚体。这将为球体添加一个刚体组件。刚体组件的作用是模拟它所附加对象上的物理,就像这个对象在现实世界中是一个刚体一样。它模拟重力、弹跳、外力以及所有你期望现实世界刚体会受到的影响,例如空气阻力。

默认情况下,刚体组件被设置为在对象上模拟重力。我们不需要在刚体中更改任何设置,因为它们现在都适合我们。只需点击播放按钮,我们就会立即看到球体在游戏世界中在重力作用下下落。

设置全局重力设置

我们可能已经注意到球体下落得太慢,以至于在游戏中感觉不自然。这主要是因为我们的比例不是 1:1 与游戏匹配。它实际上是 1:1 与现实世界匹配。这是因为它是一个增强现实应用,我们关心的是它与现实世界的交互感觉自然。然而,这却使得我们在使用增强现实游戏时,相对于游戏世界都变成了巨人。所以,并不是球体下落得太慢,而是有点爱因斯坦相对论的意味,相对于我们,球体下落了很长的距离。

为了解决这个问题,我们需要提高重力,以补偿我们所在巨人状态。如果重力更强,球体下落得更快,并给我们一种它在我们自己的真实世界中是自然的感受。幸运的是,在 Unity 项目中更改重力设置相当简单。

  1. Edit菜单中,转到Project设置,并选择Physics。在Inspector中,我们将看到与物理工作方式相关的多个设置。我们可以更改任何一个,但现在我们只需要更改一个。第一个设置与重力相关。现实世界中的重力作用于 y 轴,其大小大约为-9.81。我们需要将其强度增加到 6 倍,所以将其更改为-60.81

  2. 点击运行按钮,观察球体下落得更快,方式也更自然。以下截图显示了项目的重力设置:设置全局重力设置

这应该会处理物理补偿值,并在真实世界的 AR 环境中自然工作。

添加音频源

现在,我们需要在场景中创建声音源来处理游戏的声音效果。声音源是可以放置在世界上用于 3D 位置声音或简单 2D 声音的音频源。为了在游戏中听到声音效果,需要音频源来产生声音,但我们还需要一个监听器来实际捕获创建的声音并呈现给用户。

默认情况下,ARCamera已经添加了一个监听器组件,所以我们只需要将音频源添加到它上面。

  1. Assets文件夹中创建一个文件夹,并将其命名为Audio。将两个文件拖放到Audio文件夹中的章节资产中。这将导入名为ballFire.wavmoleHit.wav的两个音频文件。我们将第一个用于枪支发射球体的声音效果,第二个用于球体击中鼹鼠时。

    因为这是一个街机游戏,我们不需要 3D 声音位置;我们主要需要所有音频都是 2D 的,并且与声音源的距离远近无关。我们通过在检查器中更改我们刚刚导入的音频资源的设置来实现这一点。

  2. Audio文件夹中选择音频文件,并在Inspector中取消勾选名为3D Sound的复选框。对两个文件都做同样的事情。以下截图显示了音频文件的音频设置:添加音频源

  3. 现在,选择ARCamera,然后从GameObject菜单中选择Create Empty。这样做会在世界中创建一个空对象,并且靠近ARCamera。现在,将对象重命名为ballFireAudio。现在,选择我们刚刚创建的对象,从Component菜单导航到Audio | Audio source。重复相同的步骤来创建moleHitAudio

  4. Audio文件夹中的音频文件适当地拖放到我们刚刚创建的音频源组件中。这实际上在我们的场景中创建了声音源。只需取消勾选名为Play on Awake的复选框,因为我们需要通过代码来控制这个音频源。尽管这是一个在游戏面板中测试声音源如何播放的有用选项。以下截图显示了ballFireAudio的声音源设置:添加音频源

现在声音源已经设置好了,我们可以轻松地从脚本中调用它们,以增加应用程序的沉浸感。

编写球枪脚本

我们已经为枪创建了弹射物,我们也为它创建了声音源,但我们还没有让它像球枪一样工作;这就是脚本派上用场的时候了。

我们需要做的第一件事是为我们创建的弹射物创建一个预制体。这是为了能够通过脚本克隆弹射物并向可怜的鼹鼠发射。为此,只需在Assets文件夹中创建一个文件夹,并将其命名为Prefabs。从Hierarchy面板中将Ball对象拖放到你刚刚创建的文件夹中。现在我们有一个可以通过代码调用并创建任意数量球的预制体。

我们附加到相机上的球是没有意义的,因为我们将通过代码创建弹射物。所以,在我们已经制作了球的预制体之后,我们不再需要在场景中使用它,但在我们移除它之前,还有另一个步骤。我们需要有一个占位符,从该占位符中生成弹射物。这个占位符应该与场景中现在的球具有相同的位置和旋转。

首先,我们从GameObject菜单中添加一个空对象到场景中。现在,通过拖放将该对象附加到ARCamera对象上。将那个对象重命名为BallPlaceHolder。我们需要BallPlaceHolder对象与Ball对象具有完全相同的变换。不幸的是,Unity 中没有自动复制两个对象变换的功能,因此我们需要手动复制。点击Ball对象,复制该对象的位置和旋转,并将它们插入到BallPlaceHolder对象中。然后,删除Ball对象,因为我们不再需要它了。

以下截图显示了添加到场景中的BallPlaceHolder

编写球枪脚本

现在,是时候为我们的脚本创建一个文件夹了。在Assets中创建一个新的文件夹,并将其重命名为Scripts。在Scripts文件夹内,从Assets菜单导航到Create | C# Script。将创建的文件命名为ballGun。现在,双击它,Unity 将自动为我们打开其 MonoDevelop 编辑器。

以下截图显示了 Unity MonoDevelop 编辑器:

编写球枪脚本

Unity 在 MonoDevelop 编辑器中为我们自动创建了许多东西。首先,它创建了一个以脚本文件名命名的类模板。这就是为什么脚本文件名必须是类名的原因之一。它为我们添加了两个空函数,这对平台上的游戏开发至关重要。

Start()函数是一个 Unity 引擎在场景开始时自动调用的函数。它对于变量初始化非常有用,可以将其视为类的构造函数。

Update()函数是一个非常重要的函数,Unity 会在游戏中的每一帧自动调用它。这对于跟踪游戏对象状态、维护游戏逻辑以及许多其他用途非常重要。强烈建议不要在Update()函数中进行密集计算,因为这会降低游戏的帧率,因为 Unity 不会渲染下一帧,直到游戏中的所有Update()函数都完全执行完毕。

现在,让我们看看添加代码后的脚本,看看每个函数都做了什么。以下截图显示了ballGun.cs脚本:

球枪脚本

这就是控制球枪行为的脚本的样子。我们将把这个脚本附加到ARCamera对象上,并且它会响应用户在屏幕上的任何触摸,直接向用户指向的方向发射球。让我们看看这个脚本中的每个函数都做了什么。

我们首先看到的是脚本中声明的变量。它们的语法与您从 C#语言中期望的类似:

public GameObject projectile;
public Transform projectilePlaceHolder;
private GameObject ballFireAudio;
private Gameobject Trackable;

在 Unity 中,变量的publicprivate状态非常重要。这是因为public变量会出现在编辑器中,并且可以在检查器中设置它们的值。这一点特别有用,应该牢记在心。

projectile变量是我们将用于链接到预制件的变量。它是public的,因为我们将在稍后从编辑器设置其值。projectileGameObject类型,它是游戏中任何对象的通用类型。它包含大量相关函数和变量,这些函数和变量经常很有用。wer sadfas

变量projectilePlaceHolderTransform类型。它将保存场景中BallPlaceHolder对象的变换信息,该对象用于生成弹射物。

对于变量ballFireAudio,正如其名称所暗示的,我们将使用它来链接到我们之前创建的音频源对象。

Trackable变量将用于链接到ImageTarget对象。我们将使用它将生成的弹射物作为其子对象。我们将这样做,以便在Trackable从视线中消失时,球能够消失:

void Start() {ballFireAudio = this.gameObject.transform.FindChild("
ballFireAudio").gameObject;Trackable = GameObject.Find("ImageTarget").gameObject;
}

这就是我们的Start()函数看起来像什么。在这个函数中,我们初始化了ballFireAudioTrackable变量。我们通过从场景中找到GameObject并将其附加到变量来实现这一点。注意,我们是通过名称找到GameObject的;如果名称不同,相应地更改它,否则变量将无法正确初始化:

void Update () {if(Input.GetMouseButtonDown(0)){ballFireAudio.audio.Play();GameObject obj = Instantiate(projectile,projectilePlaceHolder.position,this.gameObject.transform.rotation) as GameObject;obj.gameObject.rigidbody.AddRelativeForce(Vector3.forward * Time.deltaTime * 1100000);obj.transform.parent = Trackable.transform;Destroy(obj.gameObject,5f);}
}

这是我们的Update()函数,它将在每一帧被调用。它主要监听用户交互;如果用户触摸屏幕或用鼠标点击,就会实例化一个球体预制体,并对其施加力以向前推进,同时发出声音效果。重复点击或触摸将产生更多的球体。

Input.GetMouseButtonDown(0)的作用是,如果用户点击鼠标或触摸屏幕,则返回true。这就是我们如何监听用户是否与屏幕交互。如果是true,我们就继续执行游戏逻辑。

我们首先播放附加到游戏对象ballFireAudio的音频,以播放球体射击的声音效果。

接下来,我们从附加到投射物变量的预制体球体中实例化一个新的克隆。我们将其实例化到变量obj中,位置为projectilePlaceHolder的变换,旋转为摄像机的旋转,以确保它总是向前发射。

然后我们将相对力应用到实例化对象的Rigidbody组件上,以向前发射。方向是Vector3.forward,这是对象的正向。我们将其乘以Time.deltaTime;我们这样做是为了使力不受帧率的影响(Time.deltaTime是上一帧以来的时间)。这样做可以避免由于任何原因帧率下降时球体变慢。然后我们乘以力的功率。注意,力实际上很大;这是因为我们需要球体快速向前发射,并且还需要补偿游戏世界与现实世界之间的比例,正如我们通过重力所看到的那样。

然后我们将实例化对象设置为ImageTarget的父对象,以便它能够正确地与图像目标一起工作。

最后,我们延迟 5 秒后销毁对象。我们这样做是因为我们绝对不希望投射物消失,因为这会真正降低应用程序的性能。

  1. 现在我们的脚本已经准备好了,我们需要将其附加到ARCamera对象。通过将脚本拖动并放置在ARCamera对象上完成此操作。脚本组件将出现在ARCamera中,我们将会注意到两个公共变量投射物投射物占位符检查器中是可见的。

  2. 现在,我们需要将球体预制体从预制体文件夹拖放到检查器中的投射物变量。我们还需要将球体占位符对象从场景拖放到检查器中的投射物占位符变量。以下展示了附加了ballGun.cs脚本的ARCamera球枪脚本

  3. 现在我们已经正确地将脚本附加到ARCamera对象上,我们可以在Game视图中尝试它。点击运行并点击面板。相机将射出球体。以下截图显示了ballGun.cs脚本在运行中的样子:脚本化球枪

  4. 在测试脚本时,我们可能会注意到球体相对于鼹鼠来说有点太小。我们可以通过从Prefabs文件夹中的Ball预制体方向进行更改。选择它,然后更改(x, y, z)的缩放值到20。这是一个很好的例子,说明了预制体在进行更改时的有用性,因为它会自动将更改传播到整个项目中。

Vuforia 可追踪事件处理

更多的时候,我们需要在可追踪对象被找到时触发某种行为。为此,我们必须了解如何跟踪可追踪事件,例如可追踪对象被找到或丢失。Vuforia 通过提供一个名为DefaultTrackableEventHandler的模板脚本,使我们能够轻松地做到这一点。默认情况下,此脚本会附加到任何ImageTarget预制体上。现在它应该已经存在于场景中的ImageTarget对象中了。

脚本所执行的操作是处理可追踪对象被找到或丢失的事件。当可追踪对象被找到时,它负责渲染 3D 内容,当它丢失时,使其消失。需要注意的是,它并不负责可追踪对象上的视角或ARCamera的位置,这部分由另一个脚本处理,这超出了我们的范围。

Vuforia 建议我们使用DefaultTrackableEventHandler脚本作为模板来创建自己的可追踪事件处理脚本。这正是我们现在将要做的,通过向脚本中添加一个非常小的函数。

打开名为DefaultTrackableEventHandler的脚本,该脚本位于Qualcomm Augmented reality文件夹下的Scripts文件夹中。它应该看起来类似于以下截图,其中显示了DefaultTrackableEventHandler.cs脚本:

Vuforia 可追踪事件处理

从此脚本中,以下三个函数是重要的:

  • OnTrackableStateChanged: 每当可追踪对象的状态发生变化时,无论是被找到还是丢失,都会调用此函数。然后它确定是否被检测到或丢失,并相应地调用事件函数。

  • OnTrackingFound: 当可追踪对象被找到时,会调用此函数。它负责渲染ImageTarget对象的全部子对象,并开启它们的碰撞器。

  • OnTrackingLost: 当可追踪对象丢失时,会调用此函数。它负责关闭ImageTarget的所有子对象的渲染,并关闭它们的碰撞器。

这些是脚本中的三个关键函数。我们将保持它们不变,但进行一个修改。我们需要添加一个新函数,该函数返回可追踪对象的状态,告诉我们是否检测到可追踪对象。当我们在稍后看到动画的土拨鼠角色时,这将对我们很有用。

Scripts文件夹中创建一个新的 C#脚本,并将其命名为MoleTrackableEventHandler。现在将DefaultTrackableEventHandler脚本中的所有代码复制并粘贴到我们刚刚创建的脚本中。重要的是要将类名从DefaultTrackableEventHandler更改为MoleTrackableEventHandler,否则由于类名与文件名不匹配,Unity 中会出现错误。

修改后,脚本将类似于以下截图,其中显示了MoleTrackableEventHandler.cs脚本:

Vuforia 可追踪事件处理器

我们添加了变量TrackableStatus,我们希望它保存可追踪对象的状态。如果它是可见的,则为true,如果不可见,则为false。然后我们创建了一个函数,并将其命名为trackableVisible,该函数将返回变量TrackableStatus

然后,我们在OnTrackableStateChanged()函数中简单地将TrackableStatus设置为true,当找到时,设置为false,当未找到时。

现在,如果我们调用trackableVisible()函数;它将有效地告诉我们可追踪对象是否可见。

现在,我们需要将MoleTrackableEventHandler附加到场景中的ImageTarget对象上。我们现在不需要将DefaultTrackableEventHandler附加到ImageTarget上,因此我们需要删除该组件或简单地禁用它。

DefaultTrackabeEventHandler可以稍后进行自定义,以实现各种效果,例如当找到可追踪对象时播放声音或视频,或控制特定的 GUI 对象以响应可追踪对象。它为我们提供了对 AR 应用行为的很大控制,因此始终记住这一点是有益的。

添加粒子预制体

在 Unity 中,粒子是一个非常实用的工具,许多开发者都在使用它。使用它,可以创建雾气、灰尘、火焰、爆炸以及各种效果。对资源的影响通常很小,因为粒子使用小的 2D 图像动画来产生所需的效果,因此得名“粒子”。

对于我们的应用,添加当我们用球击打土拨鼠时出现的灰尘粒子将会很有用。尽管学习如何创建粒子超出了本书的范围,但我们将看到我们如何将一个粒子添加到已经制作好的场景中,因为 Unity 商店中有许多可用的免费粒子。

  1. 将名为DustParticles的包导入到项目中。将我们刚刚导入的预制体添加到场景中。你将自动注意到编辑器中正在模拟尘云。现在,我们只需要适当地将其定位在鼠丘上方,使其看起来像尘土从洞中升起,然后将其设置为 Mole 对象的子对象。不久后,我们将看到如何通过代码调用这个粒子系统并激活它。

  2. 角色对象的位置调整到地面以下,因为游戏开始时它们应该在那里。这也会给我们一个很好的想法,看看没有角色时尘土会是什么样子。只需将Character在 y 轴上移动,直到它刚好在地面以下且不可见。以下截图显示了场景中添加的尘粒:添加尘粒预制体

Unity 是一个伟大的工具,但像其他所有东西一样,它并不完美。然而,它所缺乏的通常会被一个非常活跃的社区所弥补,他们会为它创建附加组件和脚本。对于 Unity 来说,最有用且免费的脚本之一是 iTween。

iTween是一个脚本,允许我们通过脚本轻松地动画化对象。它非常可定制,适合大多数游戏对象动画需求。例如,iTween 可以轻松地用来在游戏中动画化导弹,使其以流畅的方式飞向目标。在我们的案例中,我们将使用 iTween 来动画化老鼠从鼠丘中出来又回去。

iTween 可以从 Unity 的 Asset 商店轻松添加。它是免费的;只需在 Unity Asset 商店中搜索它,它可以通过窗口菜单访问,然后下载并导入到项目中。现在,我们可以从代码中轻松访问 iTween 函数。

iTween 的文档可以在itween.pixelplacement.com/documentation.php找到。

编写老鼠角色的脚本

现在,iTween 已经设置好了,让我们看看如何编写老鼠角色的脚本以利用 iTween 并正确地动画化角色。在这个阶段,我们希望通过老鼠脚本实现的是让它从鼠丘上下跳动。动画应该从两个范围之间的随机时间开始,以避免行为的重复和可预测性。

让我们看看这个脚本的样子。以下截图显示了moleAnimator.cs脚本:

编写老鼠角色的脚本

Start()函数的前三行相当简单。我们找到并附加了击中老鼠的声音源到moleHitAudio,以便我们在脚本中使用。我们找到并附加了尘粒系统作为击中效果。然后我们找到ImageTarget对象,并且只使用脚本组件MoleTrackableEventHandler。我们这样做是为了能够调用添加的功能,即trackableVisible,以检查可追踪对象是否可见。这是在 Unity 中访问其他类函数的一种方式。

Start() 函数中的最后一行启动了动画序列;让我们看看它是如何做到的:

iTween.MoveBy(gameObject, iTween.Hash("y", 40, "easeType", "easeInOutQuad", "speed", 20, "delay", Random.Range(0.3f, 5f), "oncomplete", "animComplete_Up");

这是启动鼹鼠角色整个动画序列的代码行。MoveBy() 是 iTween 类中的一个函数,它允许通过沿着给定轴移动对象来在给定轴上动画化对象。我们首先给它当前的游戏对象,该脚本附加的对象,即鼹鼠角色,然后我们传递 iTween.Hash 参数来设置我们想要的动画类型。

iTween.Hash 的参数非常重要,但很容易理解。它遵循 (参数名称字符串,参数值) 的语法。首先,我们给出我们想要在其实际轴上动画化的轴,在我们的例子中是 y 轴。然后,我们为 easyType 设置一个值,它控制动画的减速和加速,使其不会感觉突兀;easeInOutQuad 对我们的角色来说是一种完美的自然感觉。我们将动画速度设置为 20。现在对于延迟,这是动画开始前的延迟,我们添加一个随机值,使鼹鼠在不同的时间动画化,而不是同时,因为在我们场景的后期阶段我们将有不止一个鼹鼠。oncomplete 参数是在动画完成后要调用的函数的名称。因为这一行动画化角色向上并从洞中出来,所以它调用了 animComplete_up,这反过来又会将角色动画化回洞中,正如我们接下来将要看到的。

如果我们查看 animComplete_Up 函数,我们会看到它只包含一行代码,这行代码执行的操作与 Start() 函数在其最后一行代码中执行的操作类似,但方向相反。它将角色动画化回洞中,这是有道理的,因为我们不希望角色从鼹鼠丘上弹跳。注意,oncomplete 参数调用了 animComplete_Down,这是我们接下来要查看的。

animComplete_Down 函数中,我们做了两件事。首先,我们通过调用 trackableVisible() 函数来检查可追踪对象是否可见,这是 MoleTrackableEventHandler 的一个成员。如果目标可见,我们打开 renderercollider 对象。这使得对象可见并可碰撞。我们这样做是因为当球击中鼹鼠时,我们将使鼹鼠消失,但只有当可追踪对象可见时,我们才应该使其重新出现,否则它将干扰 ImageTarget 渲染对象的方式,并且当没有追踪目标时,我们将在相机上看到漂浮的对象。接下来,它将对象动画化回原位,然后 oncomplete 依次调用 animComplete_Up,形成一个完美的递归循环。

最后一个函数,即 OnCollisionEnter,是 Unity 事件,每当两个碰撞体相互碰撞时都会触发。它发送到任何附加了碰撞体的对象。我们使用此事件来检查是否有球击中了鼹鼠。如果击中了鼹鼠,我们就播放击打音效和灰尘粒子。然后我们关闭对象的渲染器使其消失,并关闭碰撞体以避免干扰其他球。

这是将为我们处理鼹鼠行为的脚本。现在我们只需将其附加到 WhackAMoleModel 对象内部的 Character 对象上,然后播放。我们可以立即看到鼹鼠正在正确且随机地动画化。此外,如果球击中它,会播放音效和灰尘粒子,表示击打正确。

现在我们完成了鼹鼠对象,将其整个预制件放入 Prefabs 文件夹中,然后将多个鼹鼠对象添加到场景中,以便有不止一个鼹鼠。添加尽可能多的鼹鼠,但我相信四个就足够了,考虑到可追踪物的大小。

遮罩着色器

我们的游戏开发基本完成。我们已经设置了所有对象的行为,并准备部署;但我们还缺少最后一件事。我们可能已经注意到,当鼹鼠钻入地下时,它们仍然可以从侧面看到。当将应用程序部署到 AR 环境中的设备上时,这也会很明显。我们有一个简单的解决方案可以隐藏在 AR 环境中地下钻入的鼹鼠,那就是使用深度遮罩着色器。

  1. 将名为 DepthMask.shader 的着色器资产添加到章节的资产中。然后,我们想在场景中创建一个与地面平面一样大的立方体,命名为 mask,并隐藏其后的所有鼹鼠,如下面的截图所示。下面的截图还显示了添加到场景中的 Mask 对象:Mask shader

  2. 当然,这个对象目前还没有作为遮罩使用,它只是一个普通的立方体。为了给它遮罩属性,我们需要在 Materials 文件夹中为其创建一个材质,命名为 Mask。因为我们添加了 DepthMask 着色器,它应该会自动出现在材质的 Shader 下拉列表中。只需从那里选择 DepthMask 着色器,然后将材质附加到 Mask 对象上。下面的截图显示了激活的 DepthMask 着色器:Mask shader

我们立即注意到立方体消失了,但进一步的检查发现,不仅立方体不可见,而且其后的鼹鼠也不可见。这有效地解决了我们的问题,通过隐藏地下鼹鼠。

摘要

在本章中,我们详细介绍了在 Unity 中高级 AR 开发的众多内容。我们创建了一个功能完善且有趣的游戏,该游戏利用了 Unity 和 Vuforia 中的许多概念。现在我们所需做的只是将游戏部署到设备上并玩它。也许可以添加一个得分系统,或者也许可以添加有限数量的球来击打鼹鼠。天空是你的极限。尝试各种可能性,并创造一个用户会欣赏的体验。

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

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

相关文章

Winform/C# 输出到Release VS中Release模式下生成去掉生成pdb文件

前几天发布项目,有时候就发布那几个dll,但是一个dll同时还有一个pdb文件,而且pdb文件貌似还挺大。 pdb文件包含了编译后程序指向源代码的位置信息,用于调试的时候定位到源代码,主要是用来方便调试的. 在程序发布为r…

成都响应网站建设网站文章标题

一、实验内容与目的 实验要求&#xff1a; 利用CP226实验仪上的小键盘将程序输入主存储器EM&#xff0c;通过指令的执行实现微程序控制器的程序控制。 实验目的&#xff1a; 1.掌握模型机的操作码测试过程&#xff1b; 2.掌握模型机微程序控制器的基本结构以及程序控制的基本原…

表格上传网站建设网游小说

1. 引言 在任何编程语言中,错误处理都是一个至关重要的部分。在 Go 语言中,错误处理方式独具特色,它并没有采用异常处理机制(try-catch),而是通过显式的错误返回值来处理错误。这种方式让代码更加明确、易于维护,也使得错误处理更加透明。 在这篇博客中,我们将深入探…

做外贸好的网站有哪些百度识图在线

目录 0、基本信息1、研究动机2、创新点2.1、核心思想&#xff1a;2.2、思想推导&#xff1a; 3、准备3.1、符号3.2、互信息3.3、JS散度3.4、Deep InfoMax方法3.5、判别器&#xff1a;f-GAN估计散度 4、具体实现4.1、局部-全局互信息最大化4.2、理论动机 5、实验设置5.1、直推式…

校园二手网站开发与设计任务书行政单位单位网站建设

1.实现一个纵横字谜 2.支持14x14的网格 3.可以查看答案 4.猜测错误会提示答案信息 5.从txt读取词汇 6.每次游戏开始 随机生成纵横字谜 n’h

网站推他网站wordpress教程登陆

1.为什么要有缓冲区 缓冲区分成语言层面的缓冲区和操作系统层面的缓冲区 先说结论&#xff0c;语言的缓冲区可以减少系统调用的次数进而提高向文件写入和读取的效率。 2.举例子 向屏幕打印&#xff0c;无非就是向屏幕这个文件的缓冲区写入&#xff0c;然后在由操作系统刷新…

重庆工程建设信息网站4399谁做的网站

log函数是指数函数y bx 的反函数,用于求数字以某个数为底的对数。log函数的定义:设b>0,b≠1,对于任意实数x > 0,如果存在唯一的实数y,使得 b^y x,则称y为以b为底x的对数,记为:y log_b(x)这里b称为对数的底数。对数运算的底数通常取10和e。常见的对数运算有:1. 常用对数…

公司核名在哪个网站网站提交搜索引擎后出现问题

作者&#xff1a;Zarten知乎专栏&#xff1a;Python爬虫深入详解知乎ID&#xff1a; Zarten简介&#xff1a; 互联网一线工作者&#xff0c;尊重原创并欢迎评论留言指出不足之处&#xff0c;也希望多些关注和点赞是给作者最好的鼓励 &#xff01;介绍MongoDB是一种面向文档型的…

供应商协同平台:打造高效安全供应链的关键

供应商协同平台通过整合技术资源,解决了传统供应链中文件传输混乱、数据更新延迟、安全管控薄弱等问题。结合“Ftrans B2B企业间⽂件安全交换系统”的加密传输与权限管理功能,平台实现了设计图纸、订单数据等关键信息…

互斥锁和信号量机制

互斥锁 特性: 1.需要忙等,进程时间片用完才下处理机,违反让权等待 2.优点:等待奇迹不用切换进程上下文,多处理机系统中,若上锁的时间短,则等待的代价很低 3.常用于多处理机,一个核忙等,其他核照常工作,并快速…

NSIS为当前用户安装和为所有用户安装的选择

一、为当前用户和所有用户安装选择 确定 NSIS 脚本中应使用 SetShellVarContext all 还是 current,主要取决于你的软件安装目标和用户访问需求。可以通过以下几个核心问题来判断: 1. 软件是否需要被系统中所有用户访…

在 Unity 中运用 SoundTouch 插件控制音频倍速播放

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

网站的商桥怎么做国内产品设计公司前十名

内容管理模块 - 课程预览、提交审核 文章目录 内容管理模块 - 课程预览、提交审核一、课程预览1.1 需求分析1.2 freemarker 模板引擎1.2.1 Maven 坐标1.2.2 freemaker 相关配置信息1.2.3 添加模板 1.3 测试静态页面1.3.1 部署Nginx1.3.2 解决端口问题被占用问题1.3.3 配置host文…

网站建设综合实训报告公司建设网站需要什么条件

介绍: lag() 是一种常用的窗口函数&#xff0c;它用于获取某一行之前的行的值。它可以用来在结果集中的当前行之前访问指定列的值。 用法: lag() 函数的语法如下&#xff1a; lag(列名, 偏移量, 默认值) over (partition by 列名1, 列名2, ... order by 列名 [asc|desc], .…

数据中台厂商选型|解决方案厂商与独立中台厂商详细解读

上一轮关于数据中台厂商的分享,获得了不少同行伙伴的积极反馈与认可。大家普遍认为内容具有较好的参考意义,并希望进一步了解“解决方案厂商”与“独立数据中台厂商”各自的特点。这份关注令我感到十分荣幸,也让我更…

深度学习项目全流程实践与核心技术解析:从数据处理到模型优化 - 教程

深度学习项目全流程实践与核心技术解析:从数据处理到模型优化 - 教程pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: &q…

基于 SciPy 的矩阵运算与线性代数应用详解 - 详解

基于 SciPy 的矩阵运算与线性代数应用详解 - 详解2025-09-29 10:15 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; displa…

直接使用的NLog帮助类

1.先引入NLog.dll包 2.新建类: public static class LogHelper { public static void Info(object msg, params object[] parameters) { var log = LogManager.GetLogger("CameraApp"); log.Info(msg); } pu…

【每日一面】setTimeout 延时为 0 的情况

基础问答 问题:你在写代码的过程中,在什么时候才会设置 setTimeout 的延时为 0? 回答:有如下几种情况避免同步任务阻塞 UI,即在渲染较多数据的时候,可以通过 setTimeout 分批渲染。const data = new Array(1000)…

honeywell扫码枪设置

honeywell扫码枪设置1.2.如何使用Tera Term发送十六进制数给扫码枪? 使用 Tera Term 宏(TTL 脚本)如果你需要发送重复的或更复杂的十六进制序列,或者需要处理大于 0x7F 的字节(在某些字符集设置下可能会有问题),…