![Unity 2018 AR与VR开发快速上手](https://wfqqreader-1252317822.image.myqcloud.com/cover/133/36862133/b_36862133.jpg)
5.8 相关的程序控制
EasyAR的程序控制主要是通过继承相关的父类,然后通过在子类中扩展功能来实现。之前的例子中的脚本都继承了父类,但是没有进行扩展。
5.8.1 图片识别后的控制
AR程序的很多控制是发生在识别以后,常见的是当图片被识别和识别图片从屏幕中消失的时候。图片识别后的控制是通过继承并扩展父类“ImageTargetBaseBehaviour”来实现的。
(1)在项目中添加一个新的脚本,命名为“ImageTargetShow”。
脚本内容如下:
![](https://epubservercos.yuewen.com/8A3A4C/19549639508907106/epubprivate/OEBPS/Images/Figure-P137_25503.jpg?sign=1739015658-roVbm9CRyKNQ6pCBIHWgLzOt9xgdGwbE-0-857c67039a1ee2ba190185ad26735c72)
脚本说明
①引用EasyAR:
using EasyAR;
②将父类从MonoBehaviour改为ImageTargetBaseBehaviour:
public class ImageTargetShow : ImageTargetBaseBehaviour
③重写Awake事件。因为父类变了,所以原来默认的事件有些也要修改。官方明确了4个(如果使用到)需要重写的事件。
protected virtual void Awake() protected virtual void OnDestroy() protected virtual void Start() protected virtual void Update()
④在Awake事件中订阅对应事件:
![](https://epubservercos.yuewen.com/8A3A4C/19549639508907106/epubprivate/OEBPS/Images/Figure-P139_6863.jpg?sign=1739015658-G1REBJ5DI2ZVeHGoZoJfK0j5eQoTPdK7-0-63fdd124af7322cd9a0fc0b49d126b3c)
⑤响应事件,并在对应的事件处理方法中添加需要控制的内容。在这个例子里只是把识别对象的名称显示到控制台和屏幕上。
void OnTargetFound(TargetAbstractBehaviour behaviour) { Debug.Log("Found: " + Target.Name); // 输出到控制台 // 输出到UI文本 uiText.text = "Found: " + Target.Name + "\r\n" + uiText.text; }
(2)新建一个场景(Scene),如5.5.3小节中前两步那样添加识别图片,再添加“EasyAR_ImageTracker-1”游戏对象并设置,接着添加“ImageTarget”游戏对象,如图5-77所示。
![](https://epubservercos.yuewen.com/8A3A4C/19549639508907106/epubprivate/OEBPS/Images/Figure-P139_6880.jpg?sign=1739015658-tdNZyymo7hVnaL8nsfXdMk1Wmrvsa2lA-0-2602ed5e7cb12d4512d60d07f52573d5)
图5-77
(3)移除“ImageTarget”游戏对象中的脚本组件,如图5-78所示。
![](https://epubservercos.yuewen.com/8A3A4C/19549639508907106/epubprivate/OEBPS/Images/Figure-P140_6915.jpg?sign=1739015658-tOSeo7mjcrioIHsAtD0jE6xINBFJupfv-0-98a2003a9ca99dc2343a8d546e17e346)
图5-78
(4)将刚才写好的脚本ImageTargetShow拖入“ImageTarget”游戏对象中,如图5-79所示。
![](https://epubservercos.yuewen.com/8A3A4C/19549639508907106/epubprivate/OEBPS/Images/Figure-P140_6916.jpg?sign=1739015658-9WoD312UQEIfFLQGFdIZ5FFKeC5yfjvJ-0-448edb7e884abe1e735617b6cf6d7fd7)
图5-79
(5)“ImageTarget”游戏对象的设置和5.5.3小节一样。
(6)在场景中添加一个用于文本显示的游戏对象(执行“GameObject→UI→Text”菜单命令即可),如图5-80所示。
![](https://epubservercos.yuewen.com/8A3A4C/19549639508907106/epubprivate/OEBPS/Images/Figure-P140_6918.jpg?sign=1739015658-ihqTHNVeZISM6wCncpqCUVfIgTF9tMYy-0-9cb8c35a044b672afee91cff4a0b590d)
图5-80
(7)设置“Text”游戏对象的属性、大小、定位、文字颜色。
(8)运行效果如图5-81所示。
![](https://epubservercos.yuewen.com/8A3A4C/19549639508907106/epubprivate/OEBPS/Images/Figure-P141_6937.jpg?sign=1739015658-lhwpixg1YZ69vylGJsmJQbM4V0cy9z9e-0-f82f26b927746b717acca6435e5da32c)
图5-81
当图片被识别时,就会在控制台和屏幕上显示被识别图片的name,即“ImageTarget”游戏对象中“Name”参数的值。
5.8.2 通过程序控制图片识别
通过程序控制图片识别也是通过继承并扩展父类ImageTargetBaseBehaviour来实现的。
ImageTargetBaseBehaviour提供了3个方法可以用来动态设置识别图片信息,分别是SetupWithImage、SetupWithJsonString和SetupWithJsonFile。初学推荐使用SetupWithImage。
bool SetupWithImage(string path,StorageType storageType,string targetname,Vector2 size)的4个参数分别是图片的路径、路径类型、名称和大小。和在Unity的Editor界面上设置的基本一致。
关于SetupWithJsonString和SetupWithJsonFile的使用,可以参考官方文档,地址为https://www.easyar.cn/doc/EasyAR%20SDK/Unity%20Plugin%20Reference/2.0/ImageTargetBaseBehav iour.html。
(1)在项目中新建一个脚本,并命名为ImageTargetDynamic:
![](https://epubservercos.yuewen.com/8A3A4C/19549639508907106/epubprivate/OEBPS/Images/Figure-P141_25532.jpg?sign=1739015658-HtKS1itIGrakIoSq4WWLELFgwwKOVWhT-0-d3f635d829c6890ef1315ce9793f8d59)
其中,调用SetupWithImage方法分别设置所在游戏对象的识别对象是namecard.jpg和idback.jpg。
(2)新建一个Scene(场景),如5.5.3小节中前两步那样添加识别图片,添加“EasyAR_ImageTracker-1”游戏对象并设置,再添加“ImageTarget”游戏对象。
(3)移除“ImageTarget”游戏对象中的脚本组件。
(4)将刚才写好的脚本ImageTargetDynamic拖入“ImageTarget”游戏对象中。
(5)将场景中的“ImageTracker”游戏对象拖入“ImageTarget”游戏对象“ImageTargetBehaviour”组件的“Loader”属性中赋值。
(6)将“Active Target On Start”选项的勾选取消。在启动以后,这个图片识别目标不会被激活,如图5-82所示。
![](https://epubservercos.yuewen.com/8A3A4C/19549639508907106/epubprivate/OEBPS/Images/Figure-P142_6970.jpg?sign=1739015658-Yx1b1n1qS4FAZhXsfB7KSja8SX75Pk0T-0-88b09c4c6e41ab44bbea4105f07efde1)
图5-82
(7)在“ImageTarget”游戏对象下添加一个方块。
(8)在场景(Scene)中添加2个按钮。
(9)分别设置两个按钮的单击事件是“ImageTarget”游戏对象下的ShowNamecard和ShowIdback方法,如图5-83所示。
![](https://epubservercos.yuewen.com/8A3A4C/19549639508907106/epubprivate/OEBPS/Images/Figure-P142_6971.jpg?sign=1739015658-V5y40W150c7KjGmlIyjtKHlurcf7TEG7-0-14e18ecb8b1e23e9a9a9be503723051f)
图5-83
运行结果如下:
②启动之后,摄像头对准识别图片并没有反应,如图5-84所示。
![](https://epubservercos.yuewen.com/8A3A4C/19549639508907106/epubprivate/OEBPS/Images/Figure-P143_7002.jpg?sign=1739015658-gqrUCtQUJVvu0qFHKzKNafJGtkghCZtR-0-610d469f621ba8620b5f39c3e38cf43d)
图5-84
②单击“id back”按钮后,会识别身份证背面的图片。即运行了如下的程序脚本,运行结果如图5-85所示。
SetupWithImage("idback.jpg", StorageType.Assets, "id back", new Vector2(1f, 0.618f));
![](https://epubservercos.yuewen.com/8A3A4C/19549639508907106/epubprivate/OEBPS/Images/Figure-P143_7004.jpg?sign=1739015658-IkpiV2t1LRID9feHwRGFq3iWBUMECx1J-0-be73baaa2c31df0f9f9adead7211569f)
图5-85
③单击“name card”按钮后,会识别另外的图片。即运行了如下程序脚本:
SetupWithImage("namecard.jpg", StorageType.Assets, "name card", new Vector2(1f, 0.6f));
5.8.3 物体识别后的控制
物体识别后的控制脚本和前面小节图片识别后的控制基本上是一致的,只需要改动几个地方就可以了。物体识别后的控制是通过继承并扩展父类ObjectTargetBaseBehaviour来实现的。
(1)在项目中添加一个新的脚本,命名为ObjectTargetShow:
![](https://epubservercos.yuewen.com/8A3A4C/19549639508907106/epubprivate/OEBPS/Images/Figure-P143_25540.jpg?sign=1739015658-518JzGMXQTOHAuB2Zxaq0P0OhzyT5fS3-0-7753e237789145bcad29d15014ec18ae)
和图片识别后的控制脚本不同的地方如下:
①继承的父类不一样,图片识别控制继承的父类是ImageTargetBaseBehaviour,而物体识别控制继承的父类是ObjectTargetBaseBehaviour。
public class ObjectTargetShow : ObjectTargetBaseBehaviour {
②OnTargetLoad方法和OnTargetUnload方法的参数不同。
![](https://epubservercos.yuewen.com/8A3A4C/19549639508907106/epubprivate/OEBPS/Images/Figure-P144_25548.jpg?sign=1739015658-KdT2siMBRN3Jxm2B8C9kJ935kwpVulFA-0-c6ff84d773a57fbe403641f230a26c36)
(2)在Unity下新建“Models”目录(也可以是其他目录),导入一组3D信息文件。这里导入的文件将用于在Unity的场景中显示和定位物体。
(3)在Unity下新建“StreamingAssets”目录,再次导入这一组3D信息文件。这里导入的文件是供EasyAR识别使用的。
(4)新建一个场景,删除原有的“Main Camera”,从目录“EasyAR/Prefabs/Composites”里将预制件“EasyAR_ObjectTracker-1”拖动添加到场景中,并将EasyAR的“SDK License Key”复制到“EasyARBehaviour”组件的“Key”属性中。
(5)将“EasyAR/Prefabs/Primitives”目录下的预制件“ObjectTarget”添加到场景中。
(6)将“ObjectTargetBehaviour”游戏对象上的脚本组件删除,将新写的脚本“ObjectTargetShow”拖到“ObjectTargetBehaviour”游戏对象上,如图5-86所示。
![](https://epubservercos.yuewen.com/8A3A4C/19549639508907106/epubprivate/OEBPS/Images/Figure-P145_7043.jpg?sign=1739015658-M5z8d4r8QipsWbbKlZo6niR6afe8x20T-0-a256ad00c17e6a599b86296c4ae29cce)
图5-86
(7)将场景中的“ObjectTracker”游戏对象拖入“ObjectTarget”游戏对象的“ObjectTargetShow”组件的“Loader”属性中赋值。
(8)将要识别的3D模型(.obj)的路径填写在“ObjectTargetShow”组件的“Path”属性中,路径以“StreamingAssets”目录为根目录。
(9)设置“ObjectTargetShow”组件的“Storage”属性为“Assets”,如图5-87所示。
![](https://epubservercos.yuewen.com/8A3A4C/19549639508907106/epubprivate/OEBPS/Images/Figure-P145_7044.jpg?sign=1739015658-QiqGddaWLzAOJZpHAFGWHmiMo3DFn4A4-0-5095802139eb0b8a5e1764b451196e04)
图5-87
(10)将“Models”目录下的3D模型文件(.obj)拖到“ObjectTarget”游戏对象下,成为其子对象。
(11)修改3D模型文件的角度,设置“X”为90,“Z”为-180。这里如果没有设置角度,识别后的位置会偏移。
(12)选中场景中的3D模型“hexagon”游戏对象,将“Models”目录下的材质文件(.jpg)拖到3D模型上。
(13)在场景中添加一个用于文本显示的游戏对象。
(14)设置“Text”游戏对象的属性、大小、定位、文字颜色。
运行效果如图5-88所示。当图片被识别时,就会在控制台和屏幕上显示被识别物体的name,即“ObjectTargetShow”组件中“Name”参数的值。
![](https://epubservercos.yuewen.com/8A3A4C/19549639508907106/epubprivate/OEBPS/Images/Figure-P146_7058.jpg?sign=1739015658-Go9zpeFYGYh0iaTpRNdvG1HtrTKKhktI-0-f8a7c987980f56a6d10603310f928ad2)
图5-88
5.8.4 视频播放控制
视频播放时,如果需要暂停并重新播放,则要通过继承并扩展父类VideoPlayerBaseBehaviour来实现。
(1)在项目中新建一个脚本,并命名为VideoPlayerController:
![](https://epubservercos.yuewen.com/8A3A4C/19549639508907106/epubprivate/OEBPS/Images/Figure-P146_25557.jpg?sign=1739015658-aZBGX7tKLrsrTXKWMTUuH1W3cYwHCtVQ-0-569d0742ffc15bc74167bf2443e8f463)
脚本说明
①引用EasyAR:
using EasyAR;
②将父类从MonoBehaviour改为VideoPlayerBaseBehaviour:
public class VideoPlayerController : VideoPlayerBaseBehaviour
③定义事件委托:
private System.EventHandler videoReayEvent; private System.EventHandler videoErrorEvent; private System.EventHandler videoReachEndEvent;
④添加事件委托对应的处理方法:
videoReayEvent = OnVideoR eady; videoErrorEvent = OnVideoError; videoReachEndEvent = OnVideoReachEnd;
⑤添加事件订阅:
![](https://epubservercos.yuewen.com/8A3A4C/19549639508907106/epubprivate/OEBPS/Images/Figure-P147_7072.jpg?sign=1739015658-HDVkZRit9HeI7g6psoUjYtAnShtFTxtE-0-348e206e4ed28c4b3c052682e88e671e)
⑥手动加载视频:
protected override void Start() { ... Open(); }
⑦因为父类变了,所以原来默认的事件有些也要修改。官方明确了4个(如果使用到)需要重写的事件:
protected virtual void Awake() protected virtual void OnDestroy() protected virtual void Start() protected virtual void Update()
⑧响应事件,当视频加载成功、失败和播放完成时,将对应的信息显示在屏幕上:
void OnVideoReady(object sender, System.EventArgs e) { Debug.Log("Load video success"); txt.text = "load video success"; }
(2)将5.6.1小节中“Plane”游戏对象中的“VideoPlayerBehaviour”组件删除,替换成“VideoPlayerController”。
(3)其他设置和原来一样,只是把选项全部去掉。
(4)在场景中添加一个用于文本显示的游戏对象。
(5)设置“Text”游戏对象的属性、大小、定位、文字颜色。
(6)在场景中添加3个按钮,操作命令如图5-89所示。
![](https://epubservercos.yuewen.com/8A3A4C/19549639508907106/epubprivate/OEBPS/Images/Figure-P148_7096.jpg?sign=1739015658-KLPwXzZSlK1PE1Kiqm3UPwowX30Ao2Fd-0-4ce68debe64a1e2323a27263bb950316)
图5-89
(7)分别设置3个按钮的单击事件是“Plane”游戏对象下的VideoStop、VideoPlay和VideoPause方法,如图5-90所示。
![](https://epubservercos.yuewen.com/8A3A4C/19549639508907106/epubprivate/OEBPS/Images/Figure-P149_7116.jpg?sign=1739015658-d5pd113EuerQraHKVklxxXX83bRWnQRa-0-6d4334191b4bfdbdb85b9b3028fd666a)
图5-90
(8)打包应用,复制并安装到安卓设备后,运行效果如图5-91所示。当识别到图片以后,不会立即播放;单击“Play”按钮,视频会开始播放;单击“Pause”按钮,视频会暂停;单击“Stop”按钮,视频播放会停止。
![](https://epubservercos.yuewen.com/8A3A4C/19549639508907106/epubprivate/OEBPS/Images/Figure-P149_7117.jpg?sign=1739015658-3CFRamYoykvCk2lBnyJH1Lhi7JX59udE-0-5f0c1674fff1a3e6900d912a825c7031)
图5-91