2018年1月12日 星期五

Unity Vuforia 的可追蹤事件處理程序

自從 Unity 2017.2 與 Vuforia 整合之後,想要使用 Unity 製作 AR 應用變得更加簡單,即使你沒有任何基礎,只要跟著 Vuforia Developer Library 網站上這篇 Getting Started with Vuforia in Unity 的步驟,就能快速體驗自己親手實作 AR 專案的成果。不過,這篇真的很陽春,單純就是辨識圖像之後直接顯示數位內容(Digital Content),如果想要辨識圖像成功、圖像離開畫面等等的時機做些其它事情,又該如何做呢?



Getting Started with Vuforia in Unity 一文中的做法,是要將數位內容放在 ImageTarget 遊戲物件(GameObject)之下成為其子物件(Child GameObject),在執行開始時,會將這些子物件全部隱藏,直到辨識圖像成功後才會將這些子物件顯示出來;所以,如果用來做為 AR 數位內容的遊戲物件不是放在 ImageTarget 遊戲物件之下的話,這些遊戲物件就會與圖像辨識或追蹤結果無關。

該篇文中的 Adding digital assets 這一段裡有提示去查看 DefaultTrackableEventHandler.cs 這個 C# 腳本(Script)內容,而從這個腳本中可以得知,當 Vuforia 開始以及找不到目標圖像時,會去關閉它所附屬的遊戲物件的所有子物件的 Renderer、Collider、Canvas 這些組件(Component),當辨識或追蹤到目標圖像時,則會開啟這些組件。


由此可知,其實未必要把所製作數位內容的遊戲物件都放到 ImageTarget 遊戲物件之下才行,只要能夠獲得可追蹤行為(Trackable Behaviour)的狀態變化,就能夠自行去開啟或關閉遊戲物件或組件;同樣的,也可以藉此而在不同時機進行其它事情。

參考 DefaultTrackableEventHandler.cs 的內容,可以了解到如何獲得可追蹤行為的狀態,同時,為了讓腳本能夠重複利用並且更有彈性,將配合 UnityEvent 來編寫程式碼。UnityEvent 的用法可參考「Unity:使用 UnityEngine.Events 讓程式更靈活、穩定」。

以下就來寫一支能夠察覺可追蹤行為狀態改變並提供事件的名為 UETrackableEventHandler 的 C# 腳本。因為會使用到 Vuforia 相關功能,最開頭要先 using Vuforia。同時,也會用到 UnityEvent,所以也要 using UnityEngine.Event。


ImageTarget 遊戲物件能夠在運行時做為追蹤圖像目標,主要是因為它具有 ImageTargetBehaviour 這個組件。


而 ImageTargetBehaviour 這類可追蹤目標行為主要是繼承自 TrackableBehaviour 類,所以,要想獲得可追蹤行為的狀態,就要先取得所追蹤目標的 TrackableBehaviour。

在此,希望可透過 Inspector 視窗手動指定,並在 Start() 確認是否指定,如果未指定則透過 GetComponent 來從所在的遊戲物件中嘗試取得:


為了要接收到狀態改變的事件,所以必須實作 ITrackableEventHandle 介面(Interface)的 OnTrackableStateChanged 方法(Method):


要使實作的 OnTrackableStateChanged 方法能被執行到,就要將實作 ITrackableEventHandle 介面的物件註冊到所追蹤目標的 TrackableBehaviour 中,所以,在此要將物件本身提供給先前取得的 TrackableBehaviour 的 RegisterTrackableEventHandler 方法:


因為要在察覺到狀態改變時,可以在 Inspector 視窗介面上提供事件欄位來配置其它遊戲物件,以對該遊戲物件指定執行某個組件的某個方法或賦值給某個組件的屬性(Property),所以,參考 DefaultTrackableEventHandler.cs 內容有用到的,在此就添加 5 個型別(Type)為 UnityEvent 的欄位(Field):


以上都寫好之後,剩下的就是 OnTrackableStateChanged 方法的實作內容,依照不同狀態調用不同的 UnityEvent 即可:


以下是完整程式碼:


完成的腳本,直接拖拉附加到 ImageTarget 上,由於與 TrackableBehaviour 組件(這裡是 Image Target Behaviour)在同一個遊戲物件上,所以在 Inspector 視窗上,Trackable Behaviour 欄位可以不用指定;接著,On Tracked 事件可以配置當追蹤到 AR 辨識目標時要做什麼事、On Not Found 事件可以配置當追蹤目標離開畫面時要做什麼事等等。


如此,應該就可以不使用 ImageTarget 遊戲物件原本具備的 Dafault Trackable Event Handler 組件的功能,也就是說,提供給 AR 的數位內容就不用非得要放在 ImageTarget 遊戲物件之下才行,同時也可以自己決定哪些狀態時要做什麼事,例如辨識成功播放音效、開始背景音樂或開啟網頁(用圖像辨識取代 QR Code)等等。

而這個腳本也不一定要附加在 ImageTarget 遊戲物件上,只要將 Trackable Behaviour 欄位指定好就行了,擁有更多的自主權,實作更彈性,應用也就更廣了。