AR与VR开发实战
上QQ阅读APP看书,第一时间看更新

第2章

SDK开发AR应用

2.1 准备Vuforia开发环境

1.Vuforia简介

Vuforia是一款能为现实世界物体带来互动体验的AR开发平台,旨在帮助开发者打造全新级别的真实世界物品与虚拟物品的互动。它使用计算机视觉技术来实时地识别和跟踪平面图像以及简单的3D物体,使开发者能够在现实世界和数字体验之间架起桥梁。

Vuforia通过Unity游戏引擎扩展提供了C、Java、Objective-C和 .NET语言的应用程序编程接口,能够同时支持iOS和Android的原生开发,使得开发者在Untiy引擎中开发的AR应用很容易移植到iOS和Android平台上。

2.注册成为Vuforia用户

(1)打开Vuforia官网https://developer.vuforia.com/

(2)如果你已经是Vuforia 注册用户 ,就可以直接输入邮箱和密码登录Vuforia管理后台;如果你还没有注册过Vuforia用户,则需要点击注册并填写相关注册信息。

(3)在完成注册信息填写后,Vuforia会给注册邮箱发送一封激活邮件,登录邮箱按照提示操作即可激活Vuforia账户。

(4)在激活Vuforia账户后就可以点击登录进入Vuforia管理后台了,如下图所示。

3.下载Vuforia SDK for Unity

(1)点击上图中的Downloads链接并按照下图所示完成操作,注意在下载列表中选择Download for Unity。

(2)本节下载的Vuforia SDK版本为vuforia-unity-5-0-5。下载解压完成后会得到后缀名为.unitypackage的Unity插件包。

4.Vuforia 5.0.5 SDK支持的环境

(1)Android平台支持的最低版本是Android 4.0.3。

(2)Unity支持版本为4.6.7—5.1.3p1(本节使用的Unity版本为5.0.2f1)。

5.新建Unity工程

运行Unity程序,按照步骤创建一个新的Unity工程,也可以直接打开已有的Unity工程来进行Vuforia SDK导入。

6.导入Vuforia SDK for Unity插件

双击在步骤3中下载的.unitypackage插件包,弹出以下窗口后点击Import。

也可以在菜单栏中选择Assets→Import Package→Custom Package,然后再选择.unitypackage文件来导入插件。

如果出现以下界面,点击“I Made a Backup.Go Ahead! ”按钮即可。

在导入完成后,Project 窗口中显示如下:

至此,Vuforia SDK已经成功导入了新建的Unity项目中,接下来可以创建开发Demo。

2.2 创建Vuforia案例

在开始本节内容之前,如果你还没有创建Vuforia账号,请先参照上一节完成注册,如果你已经是Vuforia开发者,请继续阅读接下来的内容。

1.获取License Key

在官网点击Develop,按照下图完成操作:

完成以上操作后,在License Manager中点击自己创建的应用名称,进入下面的界面:

2.导出新建应用的数据包

根据下图先创建一个新的数据库:

数据包名最好与新建的应用名相同,以便于后期查找和导出。创建好之后进入以下界面:

打开新建的数据包,添加识别目标:

本书选择Single Image(单个图像)作为识别图:

添加成功后会显示如下界面:

上图中的星号表示该图片的识别度,星级越高则识别度越高。勾选已上传图片,下载并导入Unity工程中。

导入成功后如下图所示:

3.创建Vuforia案例

在Unity Project视图下选择Vuforia→Prefabs文件夹,并将ARCamera和ImageTarget两个预制件拖入层级视图Hierarchy中,同时将场景自带的Main Camera删除。

预制件ARCamera上带有AR摄像机以及App相关设置;预制件ImageTarget代表一张识别图像,并且带有识别事件处理等相关脚本。

点击ARCamera,在Inspector面板中找到License Key,将步骤1中创建应用时生成的License Key复制并粘贴到该区域。

ARCamera设置完成后点击ImageTarget,按照下图进行设置:

右击ImageTarget创建一个三维物体模型,调整三维物体与识别图像的位置关系以使其外于合适位置。

最后,点击运行来测试效果。

至此,一个简易的Vuforia案例创建成功。

2.3 创建AR视频

本节将介绍AR视频的创建,AR视频即识别某张图像并播放与所识别图像对应的视频文件,一般用于企业宣传册、广告、书籍等相关领域。我们将会继续使用Unity和Vuforia SDK来开发AR视频应用,关于Vuforia SDK的相关配置可参阅前面的章节。

Unity默认支持的视频格式分别有.mov、.mpg、.mpeg、.mp4、.avi和.asf,我们在项目应用中一般采用.mp4文件进行视频的播放。在本节中,我们将介绍一款用于移动手机视频播放的Unity插件,该插件名为Easy Movie Texture,通过简单的设置即可完成视频的播放。

1.插件导入

下载Easy Movie Texture 2.36插件并导入Unity中,在EasyMovieTexture文件夹下找到VideoManager预制件并将其放置到层级视图Hierarchy中,将VideoManager作为识别图像的子物体,该预制件可以将视频以当前面片(Plane)的大小比例进行播放。

注意:

在Assets文件夹中找到StreamingAssets文件夹,将视频文件放在该文件夹下。如果Assets中没有该文件夹,则需要手动创建该文件夹,如果视频放在其他文件夹下,将无法加载视频。

2.设置视频播放选项

选中VideoManager,在Inspector面板的Str File Name选项中填入视频名称,如a.mp4。该组件还可以设置是否自动播放(B Auto Play)、是否循环播放(B Loop)等属性。该预制件本质上是一个面片和控制播放的Media Player Ctrl组件,所以可以手动调整面片相对于识别图的大小和位置。

3.注意事项

(1)Easy Movie Texture插件不支持PC端的视频播放,只支持Android操作系统和iOS平台。

(2)如果需要从网络加载视频文件,则只需将视频文件的网络URL添加到Str File Name属性上,无需其他操作。

2.4 文字识别

本节介绍如何使用Vuforia和Unity实现文字识别功能。Vuforia对文字识别有一定的要求,首先,Vuforia能够识别的文字大多为英文,不能识别数字和中文。其次,默认能够识别的英文单词必须是官方词库中的单词(10万个),当然,还可以自定义添加英文单词。接下来我们通过Vuforia官方自带的案例来看一下文字识别的实现步骤。

1.插件导入

登录Vuforia官网,在下载页面中找到Samples,该页面中有Vuforia SDK提供的基本功能对应的案例,下载下图所示文件。

下载并解压之后找到下图所示Unity包并导入。

如果在导入Unity插件包的过程中出现下图所示的对话框,点击“I Made a Backup. Go Ahead! ”按钮即可。

2.实现文字识别

插件包成功导入Unity工程后删除场景自带的Main Camera,同时在Vuforia文件夹中找到如下文件,拖到层级视图Hierarchy中。

选择场景中新添加的TextRecognition物体,在Inspector面板中添加Text Event Handler脚本。

在Inspector面板中,Additional Word File表示添加自定义词库,类型为.vwl文件。上图中,在第二个线框标定区域可以自定义添加需要识别的单词,如ARinChina。MaxSimultaneous Words属性是指最大同时存在的物体的单词。

Black_List表示黑名单,即将某个单词加入该名单之后就无法再识别;相对应的White_List则表示白名单,加入该名单的单词会优先进行识别。

点开Word,将子对象Text文字改为我们自定义的文字ARinChina,并在场景中的Word物体下创建一个识别之后要显示的物体,然后调整其位置和大小,比如创建一个Cube,最后运行并查看识别效果。

2.5 柱形识别

Vuforia SDK提供了带有图像的柱形物体识别功能,柱形识别只针对柱形物体,配合包裹在柱体表面的图像来进行识别,比如识别饮料瓶。本节将介绍柱形识别的实现步骤和方法。

1.Vuforia官方案例包

登录Vuforia官网,进入Downloads页面,点击Samples选项,然后下载如下插件并解压。

在解压完成后找到Cylinder Targets包并导入Unity工程。

在Project视图中的Vuforia文件夹下找到ARCamera预制件和CylinderTarget预制件,将这两个预制件拖至层级视图Hierarchy中,同时删除场景中的Main Camera。

2.创建数据库

在Vuforia官网的Develop页面下创建一个新的数据库,命名为CylinderTargets。

创建完成后打开CylinderTargets数据库,选择Add Target,在弹出的文件选项面板中选择第三种Cylinder,然后按照页面要求填写圆柱体的尺寸。其中的三个属性分别代表圆柱体的以下信息:

● Bottom Diameter:底面直径。

● Top Diameter:顶面直径。

● Side Length:边长。

在创建好识别目标后,点击新创建的识别目标,然后选择Upload Image来上传图片,这个图片是指包裹在圆柱体上的识别图案。

图片上传标准:

● 长度:Top Diameter(或者Bottom Diameter)×π。

● 宽度:按照具体圆柱高度确定,本书使用可口可乐易拉罐,所以宽度为易拉罐高度11.5cm。

注意:

上传图片的长度一定要和上下两面图片的圆形周长相同,图片的宽度即圆柱的高,如果图片尺寸不合适,则无法成功添加。

3.实现柱形识别功能

这里我们使用官方自带的案例来做示范。在Unity工程中选中CylinderTarget,在Inspector面板中选择数据包为系统自带的数据包。

接下来,在CylinderTarget下创建一个子物体模型,这里选择Shpere,然后调节到合适的位置及大小。

最后,点击运行以测试圆柱体识别的效果。

2.6 立方体识别

Vuforia SDK提供了立方体识别功能,该功能可以识别被图案包裹的立方体,常用于产品包装盒等物体的AR展示效果,本节我们将介绍通过Unity以及Vuforia SDK制作立方体识别的步骤和方法。

1.下载并导入插件

登录官网,点击下载如下插件并解压。

在解压完成后找到Multi Targets包并导入Unity工程。

在工程视图Project中的Vuforia目录下找到ARCamera和MultiTargets两个预制件,将其拖到层级视图Hierarchy中,同时删除场景中的Main Camera。

2.创建数据库

在官网的Develop页面下选择Target Manager并创建一个新的Database,命名为MultiTarget。点击新建的MultiTarget数据库,在弹出的文件选项面板中选择Cuboid。

上图中,Dimension中的属性是为了确定立方体的尺寸,分别为宽、高、长三个维度的尺寸。相应的,物体的长度对应Front、Bottom、Top和Back识别图的长度,宽度对应Left、Top、Right和Bottom识别图的宽度,高度则对应Front、Left、Right和Back识别图的宽度。遵循上述步骤,各识别图上传时相对应位置的尺寸必须一致,否则会出现识别图无法上传的问题。

3.实现立方体识别功能

这里我们使用官方自带的MultiTarget,选中MultiTarget,调节下图所示属性。

在MultiTarget下创建一个扫描后要显示的模型,我们可以创建一个Unity自带的Cube来显示识别之后的物体,调整好对应关系后点击运行即可实现立方体识别效果。

2.7 3D物体识别

2.5节和2.6节讲解了柱体识别和立方体识别,这两节的内容都只是针对简单几何体进行识别,在本节中,我们将介绍不规则三维物体的识别步骤和方法。

1.下载并导入插件

登录官网,点击Downloads下的Tools,下载Vuforia Object Scanner (Vuforia物体扫描器)。Vuforia Object Scanner是一个用于扫描物体表面识别点信息的App,只支持Android操作系统。根据官网规定,建议大家采用Samsung Galaxy S5和Google Nexus 5这两款安卓手机进行操作,当然也可以尝试使用其他Android手机。

下载完毕并解压后会得到以下两部分内容:

● Media文件夹:三维物体扫描图,需要采用A4纸打印出来。

● scanner.apk:用于三维物体扫描,需要安装在上述两款安卓手机中。

接下来,我们依然按照之前介绍的方法下载Samples插件包并将其导入工程,下图中的Object Recognition表示对应的插件包中包含物体识别案例。

2.扫描三维物体识别信息(点云数据)

将打印出来的纸张放在桌面上,在右上角坐标区域放置需要识别的三维物体。打开已经安装的扫描数据App,360°扫描物体后将生成后缀名为.od的数据文件。

3.创建数据库

接下来登录Vuforia开发者官网并创建数据库,这次我们选择3D Object,点击Browse按钮选择上一步中生成的数据文件。

创建成功后点击下载数据包并将其导入Unity工程。

4.实现三维物体扫描

在Vuforia文件夹中找到ARCamera和ObjectTarget两个预制件并拖到层级视图Hierarchy中。

选择ObjectTarget,在Inspector面板中选择三维数据包。

然后在ObjectTarget下创建一个扫描成功后要显示的子对象,并调节到合适的位置及大小,在此我们直接创建Unity自带的三维模型Sphere。

最后点击运行以测试三维物体的识别效果。

2.8 云识别

在开发项目的过程中,当我们需要将识别图放置在服务器后台而不是App内部的时候,需要使用Vuforia的云识别功能,在本节中,我们将介绍Vuforia云识别的实现步骤和方法。

1.创建License Key

登录Vuforia开发者官网,点击Develop,在License Manager下面创建一个License Key,该License Key是为了验证App的合法性。

2.创建云数据库

选择上图中的Target Manager选项,然后点击Add Database来创建云识别数据库,在下图中选择Cloud即可添加云识别目标。

选择刚才创建的License Key。

创建好之后打开,选择添加图片(与本地图片识别一样)。

3.下载插件

点击官网中的Downloads,下载下图所示的Unity包。

4.创建Unity工程

新建一个Unity工程,命名为CloudTest并打开,解压下载好的插件包,找到Cloud Recognition包并将其导入Unity工程。

导入完成后在Assets文件夹中找到Scenes文件夹并打开Vuforia-3-CloudReco工程。

选择CloudRecognition,在Inspector面板中找到Access Key和Secret Key,通过这两个密钥可以找到云连接的图片。

再次进入Vuforia开发者官网,在Develop选项下找到下图所示的页面选项。

将上图中的两个密钥分别复制到Unity工程中要求输入密钥的地方。

选择ARCamera,将刚才专为云识别创建的License Key复制进去。

最后运行以测试云识别效果,与本地识别的区别是,云识别测试需要设备处于连网状态。

2.9 智能地形

之前介绍了如何通过扫描单个识别图或物体来实现增强现实,可它们都是相对独立的,并且与现实场景没有互动。那么,如何使通过增强现实技术加载出的模型与现实场景互动呢?这就要用到本节介绍的SmartTerrain。

1.插件下载

访问https://developer.vuforia.com/downloads/sdk,进入如下界面,并下载Vuforia SDK的Unity版本。

2.创建Unity工程

新建一个Unity工程并将下载好的插件导入Unity。

3.效果实现

将场景中的Main Camera删除,在Vuforia文件夹下的Prefabs里将ARCamera、ImageTarget以及SmartTerrain中的SmartTerrain拖入场景。

在Vuforia的Develop页面中的License Manager下获取License Key并填入下图所示的框内。

然后在Target Manager页面中上传一张识别图,下载识别目标数据文件并将其导入当前工程(关于如何下载识别目标数据,之前的章节中有详细的介绍)。

在ARCamera的Inspector面板中进行如下设置。

在ImageTarget的Inspector面板下进行如下设置。

在这里选择你的识别图。为了方便观察,我们改变一下SmartTerrain中组件的材质颜色,步骤如下。

将这个材质球赋给上面的Primary Surface,并设置如下。然后对PropTemplate的材质进行设置。

注意:

颜色可自由选择,没有特殊规定。

运行Unity扫描识别图,并在场景中置入一个随机物体,效果图如下。

扫描成功后会出现暗紫色的阴影部分,随后如果扫描出了场景中的三维物体,就会在该物体上生成一个浅绿色的立方体盒子(不同设置下的颜色不同)。

至此,Vuforia的SmartTerrain地形就创建完毕,大家可以根据自己的需求在出现浅绿色立方体盒子的地方添加相应的模型与交互事件,从而完善你的SmartTerrain应用。

注意:

若想实现更好的效果,还可以结合PrimeSense Capri进行开发。

2.10 虚拟按钮

使用Vuforia实现增强现实之后,有时需要与这些虚拟模型进行交互,同时为了使交互方式更加魔幻,我们期望可以在真实的识别图像上进行点击,从而触发App中的某些行为。Vuforia SDK为我们提供了Virtual Button功能来实现这样的交互,本节我们将带领大家使用这一特性实现两个模型之间的切换。

1.插件下载

访问https://developer.vuforia.com/downloads/sdk,进入如下界面,并下载Vuforia SDK的Unity版本。

2.创建Unity工程

新建一个Unity工程并将下载好的插件导入Unity,同时将识别图数据包导入该工程。

3.场景搭建

首先删除场景中的Main Camera,接着从Vuforia→Prefabs中将ARCamera和ImageTarget拖入场景,在ARCamera的Inspector面板下添加App License Key,并激活当前识别图信息。

然后在ImageTarget的Inspector面板下设置相应识别图信息。

接着在ImageTarget下分别创建一个Cube和一个Sphere,并将Project视图中Vuforia→Prefabs下的Virtual Button预制件拖入ImageTarget。这里将Cube的棱长设置为0.3,将Sphere的半径设置为0.4,然后使它们的位置相同。为了便于观察,我们新建两个材质球,分别将Cube和Sphere设置为不同的颜色。最后在Virtual Button的Inspector界面里分别设置两个Virtual Button的名字。

4.脚本编写

在Project下新建一个C#脚本,命名为VirtualButtonTest.cs,并在脚本中添加以下代码:

        using UnityEngine;
        using System.Collections.Generic;
        using Vuforia;

        public class VirtualButtonTest: MonoBehaviour, IVirtualButtonEventHandler
        {
            void Start ()
            {
            }

            public void OnButtonPressed(VirtualButtonAbstractBehaviour vb) { }
            public void OnButtonReleased(VirtualButtonAbstractBehaviour vb) { }
        }

该类的作用是实现IVirtualButtonEventHandler这个接口,该接口中定义了OnButton Pressed和OnButtonReleased两个方法,这两个方法能够监听虚拟按键的按下和释放事件。为了触发这两个事件,我们还需要将之前添加的两个VirtualButton对象注册到事件系统中,因此需要在Start()方法中查找这两个物体,并调用VirtualButtonBehaviour类中的RegisterEventHandler方法将当前对象作为参数传入,具体的代码实现如下:

        void Start ()
        {
            //在所有子物体类中找到所有VirtualButtonBehaviour组件
            VirtualButtonBehaviour[] vbs = GetComponentsInChildren<VirtualButtonBehaviour>();
            for (int i = 0; i < vbs.Length; ++i)
            {
                //在虚拟按钮中注册TrackableBehaviour事件
                vbs[i].RegisterEventHandler(this);
            }
        }

接下来在当前类中创建两个GameObject类型的字段,分别对应之前创建的立方体和球体。

        private GameObject cube;
        private GameObject sphere;

接着在Start方法中查找这两个物体并赋值给相应的字段。

        cube = transform.FindChild("Cube").gameObject;
        sphere = transform.FindChild("Sphere").gameObject;

在程序开始的时候,我们希望它们都不显示,所以要先把它们藏起来。这就是Start方法的最后一步需要做的事情:

        cube.SetActive(false);
        sphere.SetActive(false);

现在我们开始实现OnButtonPressed方法中的功能,此方法的唯一一个参数vb是VirtualButtonAbstractBehaviour类型。在这个参数中可以获取被按下的虚拟按键的名称VirtualButtonName,将传递的名称和场景中创建的名称进行对比,就可以知道我们具体按下的是哪一个虚拟按键,具体代码实现如下:

        switch (vb.VirtualButtonName)
        {
            case "showCube":
                cube.SetActive(true);
                break;
            case "showSphere":
                sphere.SetActive(true);
                break;
        }

同理,OnButtonReleased实现方法基本相同,代码如下:

        switch (vb.VirtualButtonName)
        {
            case "showCube":
                cube.SetActive(false);
                break;
            case "showSphere":
                sphere.SetActive(false);
                break;
        }

5.功能实现

运行Unity并扫描识别图,由于我们在最开始将两个物体隐藏起来了,所以看不到东西。

当我们“按下”左边的showCube按钮时,画面如下。

接着,我们“按下”右边的showSphere按钮,效果如下。

到此,VirtualButton功能实现完毕。

关于虚拟按钮,有以下几点需要注意:

● 本节只是实现了一个简单的功能,大家可以根据自己的需求自定义VirtualButton事件。

● 可以使用PS等图像处理软件给识别图加上虚拟按钮的图像,这样会更直观。

● 为了达到更好的体验效果,识别图可以复杂一些,尤其是在虚拟按钮的位置。

2.11 帧标记识别

在使用Vuforia进行开发时,我们总是强调识别图的识别度星级越高,越容易识别。那么假如在商业项目中,客户要使用的识别图的识别星级为0,该怎么办呢?这就是FrameMarker大展拳脚的时候了。本节我们将为大家介绍一个名叫FrameMaker的神奇功能。

1.插件下载

访问https://developer.vuforia.com/downloads/sdk,进入如下界面,并下载Vuforia SDK的Unity版本。

2.创建Unity工程

使用插件,导入新建的Unity工程。

然后拖入ARCamera和FrameMaker,并在FrameMaker下新建一个Cube作为识别后呈现的对象。

3.效果实现

在ARCamera里填写App License Key,识别效果如下。

这里要说明的是,其实FrameMaker和ImageTarget识别很像,但是,ImageTarget识别需要先将识别图上传到Vuforia,再从资源库中以.unitypackage格式下载并导入工程中使用。而FrameMaker则无需上传,官方提供了512张FrameMaker的识别图供使用。

所以当我们使用ImageTarget的时候要在ARCamera上勾选如下设置,而使用FrameMaker的时候则无需设置。

所以我们在制作的时候,只需使用PS将自己的识别图和官方提供的FrameMaker进行合成即可,因为所识别的是帧识别图,与底图内容无关。但要注意一点,你所使用的帧识别图的序号需在场景中的FrameMaker中进行设定,默认为0(即第一张)。

官方提供的识别图已打包好,解压后可直接使用,路径如下。

所以当我们遇到识别图不清楚、识别效果差或者识别图较多又相似的问题时,就可以考虑使用FrameMaker来解决这一问题,因为其主要是识别FrameMaker,而和底图没有关系。这就是帧标记识别,快使用它让那些0星级的识别图“重获新生”吧!

2.12 自定义目标识别

在AR开发过程中,很多人会觉得将识别图上传到官网数据库然后再从数据库下载这个过程难免有些繁琐,尽管有FrameMaker和云识别这些强大的功能,但还是会有人觉得麻烦。那么,如何在使用时实时创建识别图,就是本节我们要给大家介绍的新功能,自定义目标识别。

有必要提前介绍一下自定义目标识别的工作原理,打开摄像头开始扫描后,以扫描到的某一固定场景作为识别图,实现这一步骤的方法就是使用摄像头进行拍照,这时就需要一个触发拍照的指令,我们用一个Button来实现。所以最终的效果就是画面中会一直有一个Button,当我们扫描到我们要自定义的识别图时,按下Button,然后识别图创建完成,扫描该识别图,模型出现。

1.插件下载

访问https://developer.vuforia.com/downloads/sdk,进入如下界面,并下载Vuforia SDK的Unity版本。

2.创建Unity工程

新建一个Unity工程并将下载好的插件导入Unity。

3.场景搭建

删除场景中原有的Main Camera,接着从Vuforia→Prefabs路径下将ARCamera、ImageTarget以及UserDefi nedTargetBuilder拖入场景。

接着在ARCamera的Inspector面板下添加App License Key。随后在ImageTarge的Inspector面板下将ImageTarget类型设置为UserDefi ned。

接下来需要添加模型,这里用Cube来代替,我们在ImageTarget下添加一个Cube。最后创建Button按钮,这也是我们创建自定义识别图时最重要的一步。

4.编写脚本

在Project下新建一个C#脚本,脚本主框架如下:

        using UnityEngine;
        using System.Collections;
        using System.Collections.Generic;
        using System.Linq;
        using Vuforia;
        public class UDTTest: MonoBehaviour, IUserDefinedTargetEventHandler
        {
            void Start ()
            {

            }
              public  void  OnFrameQualityChanged(ImageTargetBuilder.FrameQuality
    frameQuality) { }
            public void OnInitialized() { }
            public void OnNewTrackableSource(TrackableSource trackableSource) { }
            public void BuildNewTarget()
            {
            }
        }

这个类中比较关键的是IUserDefi nedTargetEventHandler这个接口,其中定义了OnFrame QualityChanged、OnInitialized和OnNewTrackableSource三个方法。我们实现这个接口中的三个方法,并将脚本附加到UserDefi nedTargetBuilder上。

首先需要声明一个UserDefi nedTargetBuildingBehaviour类型的变量,接着在Start函数里将当前类注册为该类型事件。

        UserDefinedTargetBuildingBehaviour mTargetBuildingBehaviour;
            void Start ()
            {
                mTargetBuildingBehaviour = GetComponent<UserDefinedTargetBuildingBehaviour>();
                if (mTargetBuildingBehaviour)
                {
                    mTargetBuildingBehaviour.RegisterEventHandler(this);
                    Debug.Log("Registering User Defined Target event handler.");
                }
            }

接下来要实现接口中的三个函数,首先是OnInitialized,用来初始化一些数据,我们在这个函数里写入下面的代码:

        public void OnInitialized()
            {
                mObjectTracker = TrackerManager.Instance.GetTracker<ObjectTracker>();
                if (mObjectTracker ! = null)
                {
                    mBuiltDataSet = mObjectTracker.CreateDataSet();
                    mObjectTracker.ActivateDataSet(mBuiltDataSet);
                }
            }

这里用到两个新的变量,需要提前声明,如下:

        ObjectTracker mObjectTracker;
        // 新定义的数据集添加到DataSet里
        DataSet mBuiltDataSet;

接着是OnFrameQualityChanged这个函数,用来更新当前帧质量。我们在函数里写入下面的代码:

        public void OnFrameQualityChanged(ImageTargetBuilder.FrameQuality frameQuality)
        {
            mFrameQuality = frameQuality;
            if (mFrameQuality == ImageTargetBuilder.FrameQuality.FRAME_QUALITY_LOW)
            {
                Debug.Log("Low camera image quality");
            }
        }

这里的mFrameQuality 是一个用来记录当前帧图像质量的枚举类型,声明如下:

        ImageTargetBuilder.FrameQuality mFrameQuality = ImageTargetBuilder.FrameQuality.
    FRAME_QUALITY_NONE;

最后也是最重要的一个方法OnNewTrackableSource的代码如下:

        public void OnNewTrackableSource(TrackableSource trackableSource)
        {
            mTargetCounter++;
            // Deactivates the dataset first
            mObjectTracker.DeactivateDataSet(mBuiltDataSet);

            // Destroy the oldest target if the dataset is full or the dataset
            // already contains five user-defined targets.
            if (mBuiltDataSet.HasReachedTrackableLimit() —— mBuiltDataSet.GetTrackables().
    Count() >= 5)
            {
                IEnumerable<Trackable> trackables = mBuiltDataSet.GetTrackables();
                Trackable oldest = null;
                foreach (Trackable trackable in trackables)
                {
                    if (oldest == null —— trackable.ID < oldest.ID)
                        oldest = trackable;
                    }
                if (oldest ! = null)
                {
                    Debug.Log("Destroying oldest trackable in UDT dataset: " + oldest.Name);
                    mBuiltDataSet.Destroy(oldest, true);
                }
            }

            // Get predefined trackable and instantiate it
            ImageTargetBehaviour imageTargetCopy = (ImageTargetBehaviour)Instantiate(Imag
    eTargetTemplate);
            imageTargetCopy.gameObject.name = "UserDefinedTarget-" + mTargetCounter;

            // Add the duplicated trackable to the data set and activate it
            mBuiltDataSet.CreateTrackable(trackableSource, imageTargetCopy.gameObject);

            // Activate the dataset again
            mObjectTracker.ActivateDataSet(mBuiltDataSet);
        }

这个函数里需要提前声明的变量有两个,如下:

        int mTargetCounter;
        //声明一个公开的ImageTargetBehaviour,然后在Unity中赋值
        public ImageTargetBehaviour ImageTargetTemplate;

最后一个就是我们自定义的函数BuildNewTarget,代码如下:

        public void BuildNewTarget()
        {
            mTargetBuildingBehaviour.BuildNewTarget("test", 50);
        }

然后还需要返回Unity中进行一些细微的设置调整,将我们的脚本拖到UserDefi ned TargetBuilder下,并为ImageTargetTemplate进行赋值。

然后在Button上添加点击事件,步骤如下。

然后在UserDefi nedTargetBuilder上勾选Start scanning automatically,表示开启自动扫描。

5.运行工程

首先拍摄一张图片,界面如下。

将我们需要自定义的识别图置于取景框内,点击Button便可识别出Cube,将识别图移出摄像头取景范围,模型消失,再次扫描刚才的识别图,依然出现模型。

至此,Vuforia的自定义目标识别介绍完毕,大家可以根据自己的需求发挥想象力,制作出属于自己的炫酷AR产品。