本节书摘来自华章出版社《AR与VR开发实战》一书中的第2章,第2.10节,作者 张克发 赵兴 谢有龙,更多章节内容可以访问云栖社区“华章计算机”公众号查看。
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) { }
AI 代码解读
}
该类的作用是实现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);
}
AI 代码解读
}
接下来在当前类中创建两个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;
AI 代码解读
}
同理,OnButtonReleased实现方法基本相同,代码如下:
switch (vb.VirtualButtonName)
{
case "showCube":
cube.SetActive(false);
break;
case "showSphere":
sphere.SetActive(false);
break;
AI 代码解读
}
5.功能实现
运行Unity并扫描识别图,由于我们在最开始将两个物体隐藏起来了,所以看不到东西。

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

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

到此,VirtualButton功能实现完毕。
关于虚拟按钮,有以下几点需要注意:
本节只是实现了一个简单的功能,大家可以根据自己的需求自定义VirtualButton事件。
可以使用PS等图像处理软件给识别图加上虚拟按钮的图像,这样会更直观。
为了达到更好的体验效果,识别图可以复杂一些,尤其是在虚拟按钮的位置。