1. 程式人生 > >利用Vuforia開發一個AR卡牌對戰(一):多圖識別+EventHandler框架

利用Vuforia開發一個AR卡牌對戰(一):多圖識別+EventHandler框架

卡牌對戰1:多圖識別+EventHandler框架

這個系列主要講解實現一個簡易的AR卡牌對戰的功能,這次首先實現多圖識別和EventHandler的框架介紹。

首先我們來實現多圖識別。

1.上傳識別圖並下載資料包,然後得到LicenseKey。這裡用了兩個識別圖,一次打包兩個識別圖下載下來。

 

兩個識別圖分別是

2.Vuforia外掛匯入Unity,並將識別圖資料包匯入,拖入ARCamera和兩個ImageTarget

 

3.設定ARCamera:輸入LicenseKey,然後設定Max Simultaneous Tracked Images為最多識別的圖片數目(這裡設定為2),這是單圖識別和多圖識別的主要區別。

 

4.分別設定兩個ImageTarget,同一個Database下兩個不同圖片

 

5.不要忘記設定他們的材質的TextureShape2DEditor-Vuforia-ImageTargetTextures下選擇識別圖材質然後設定。

6.測試效果,分別在兩個識別圖下放一個Cube和一個Sphere.

可以看到,在選擇一個ImageTarget的時候兩個ImageTarget的圖片卻變成相同的了,不過這並不影響我們的識別的功能。

 

7.執行測試,多圖識別就基本好了。

 

二、Trackable Event Handler 框架的介紹:

一般我們做識別是不會在別人的原始碼上直接修改的,所以這邊我們複製他的DefaultTrackableEventHandler

指令碼程式碼,自己新建一個指令碼

My_DefaultTrackableEventHandler2,然後複製他的程式碼到這個指令碼上並修改類名為自己的指令碼名字。下面是程式碼和註釋,都是一些個人的理解。

using UnityEngine;
namespace Vuforia
{
    /// <summary>
    /// A custom handler that implements the ITrackableEventHandler interface.
    /// </summary>
    public class My_DefaultTrackableEventHandler2 : MonoBehaviour,
                                                ITrackableEventHandler //實現ITrackableEventHandler介面,該介面函式是OnTrackableStateChanged
    {
        #region PRIVATE_MEMBER_VARIABLES
 
        private TrackableBehaviour mTrackableBehaviour;
 
        #endregion // PRIVATE_MEMBER_VARIABLES
 
 
        #region UNTIY_MONOBEHAVIOUR_METHODS
 
        void Start()
        {
            mTrackableBehaviour = GetComponent<TrackableBehaviour>();
            if (mTrackableBehaviour)
            {
                mTrackableBehaviour.RegisterTrackableEventHandler(this); //註冊追蹤事件
            }
        }
 
        #endregion // UNTIY_MONOBEHAVIOUR_METHODS
 
 
        #region PUBLIC_METHODS
 
        /// <summary>
        /// Implementation of the ITrackableEventHandler function called when the
        /// tracking state changes.
        /// </summary>
        //該方法功能是監測攝像頭的追蹤狀態,檢測到識別圖的時候執行OnTrackingFound();丟失的時候執行OnTrackingLost();
        //在丟失的時候和追蹤到的時候分別都執行一次,而不是在丟失的狀態下一直執行,在找到的狀態下一直執行。
        public void OnTrackableStateChanged(
                                        TrackableBehaviour.Status previousStatus,
                                        TrackableBehaviour.Status newStatus)
        {
            if (newStatus == TrackableBehaviour.Status.DETECTED ||
                newStatus == TrackableBehaviour.Status.TRACKED ||
                newStatus == TrackableBehaviour.Status.EXTENDED_TRACKED)
            {
                OnTrackingFound();
            }
            else
            {
                OnTrackingLost();
            }
        }
 
        #endregion // PUBLIC_METHODS
 
 
        #region PRIVATE_METHODS
 
        //識別到的時候
        //將所掛在這個指令碼的ImageTarget下的所有子物體的Renderer和Collider開啟(enabled)
        private void OnTrackingFound()
        {
            Renderer[] rendererComponents = GetComponentsInChildren<Renderer>(true);
            Collider[] colliderComponents = GetComponentsInChildren<Collider>(true);
 
            // Enable rendering:
            foreach (Renderer component in rendererComponents)
            {
                component.enabled = true;
            }
 
            // Enable colliders:
            foreach (Collider component in colliderComponents)
            {
                component.enabled = true;
            }
 
            Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " found");
        }
 
        //識別丟失的時候
        //將所掛在這個指令碼的ImageTarget下的所有子物體的Renderer和Collider關閉(disabled)       
        private void OnTrackingLost()
        {
            Renderer[] rendererComponents = GetComponentsInChildren<Renderer>(true);
            Collider[] colliderComponents = GetComponentsInChildren<Collider>(true);
 
            // Disable rendering:
            foreach (Renderer component in rendererComponents)
            {
                component.enabled = false;
            }
 
            // Disable colliders:
            foreach (Collider component in colliderComponents)
            {
                component.enabled = false;
            }
 
            Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " lost");
        }
 
        #endregion // PRIVATE_METHODS
 
        //丟是識別圖的時候,是不再渲染模型和不再計算碰撞了,而不是消除了物體(有需要的話也可以這麼做來動態載入物體)
    }
}


由於我們做的是AR卡牌對戰,所以下一節需要在OnTrackingFound和OnTrackingLost方法中做一些修改,來達到我們想要的目的。

三、準備工作和模型的匯入。

我們要實現的基本功能:AR多卡識別;兩張卡距離滿足一定條件的時候觸發對戰事件,否則就待機;遠端人物攻擊時炮彈能追蹤目標;卡片距離到一定距離的時候人物開始向對方移動,然後到了攻擊範圍就開始攻擊;雙方有各自的血條。

人物模型和動畫的匯入:我這邊隨意的準備了人物模型,這邊修改動畫和觸發條件,動畫分別為IdleRunAttackTauntDeadDie 5個動畫(RunIdle需要迴圈播放),這些轉換條件

 

只有最下面的是Trigger,其他都是Bool型別,將AnyStateDie的觸發條件,IdleRunRunAttack觸發條件中的HasExitTime去掉

 

分別設定轉換條件,設定完成後任務動畫基本就OK了,接下來在製作一個血條,一個白色的長方形圖片就可以了,這裡命名為Blood,然後設定為Sprite

將人物模型拖到識別圖下,並給模型新增剛體和碰撞,不需要重力和其他受力旋轉啥的,所以都去掉。

 

給給近戰角色的武器上新增一個碰撞器,勾選Trigger

給遠端人物新建一個球來當他的子彈,球上也要掛碰撞(Trigger)。

 

最後再把血條加上去:在模型的下面分別新增Cavans,換成世界座標,然後新增Image,將Blood.jpg賦值上去,調整大小和顏色到下圖所示:

 

到這我們的基本的準備工作就OK了,有什麼不合理的地方或者缺什麼,下一次邊做邊修改。

本文內容部分參考自Think加速想象力出版的《ARVR開發實戰》教程,更多學習資料也請關注www.arvrthink.com