Unity Vuforia中脱卡和多目标追踪的实现

脱卡功能:【当丢失追踪目标时,追踪目标显示在屏幕中央】

  • 实现思路:默认的追踪方式是实现ITrackableEventHandler接口,当追踪到识别图,调用OnTrackingFound()函数,当丢失时,调用OnTrackingLost()函数。脱卡功能主要是修改当丢失追踪目标时的函数。
    脱卡功能实现:一张是改变ARCamera的位置,一种是改变追踪模型的位置。本文主要是通过第一种方式,先保存好ARCamera的位置,当丢失时,将之前的保存好的ARCamera位置给ARCamera.localPosition;
using UnityEngine;
using Vuforia;
public class ChangeTargetEventHandler : MonoBehaviour, ITrackableEventHandler
{
    private GameObject ARCamera;
    private bool isFirstFound = false;
    private Vector3 LostARCameraPosition = new Vector3(0.013f,0.111f,-1f);//ARCamera位于屏幕中心位置
    public void Awake()
    {
        ARCamera = GameObject.Find("ARCamera");
    }
    protected TrackableBehaviour mTrackableBehaviour;

    protected virtual void Start()
    {
        mTrackableBehaviour = GetComponent();
        if (mTrackableBehaviour)
            mTrackableBehaviour.RegisterTrackableEventHandler(this);
    }

    protected virtual void OnDestroy()
    {
        if (mTrackableBehaviour)
            mTrackableBehaviour.UnregisterTrackableEventHandler(this);
    }

    public void OnTrackableStateChanged(
        TrackableBehaviour.Status previousStatus,
        TrackableBehaviour.Status newStatus)
    {
        if (newStatus == TrackableBehaviour.Status.DETECTED ||
            newStatus == TrackableBehaviour.Status.TRACKED ||
            newStatus == TrackableBehaviour.Status.EXTENDED_TRACKED)
        {
            Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " found");
            OnTrackingFound();
        }
        else if (previousStatus == TrackableBehaviour.Status.TRACKED &&
                 newStatus == TrackableBehaviour.Status.NOT_FOUND)
        {
            Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " lost");
            OnTrackingLost();
        }
        else
        {
            OnTrackingLost();
        }
    }
    /// 
    /// 当追踪到时遍历ImageTarget下的子物体,显示为可见状态
    /// 
    public void OnTrackingFound()
    {
        var rendererComponents = GetComponentsInChildren(true);
        var colliderComponents = GetComponentsInChildren(true);
        var canvasComponents = GetComponentsInChildren(true);

        // Enable rendering:
        foreach (var component in rendererComponents)
            component.enabled = true;

        // Enable colliders:
        foreach (var component in colliderComponents)
            component.enabled = true;

        // Enable canvas':
        foreach (var component in canvasComponents)
            component.enabled = true;
        isFirstFound = true;
    }
    /// 
    /// 当追踪识别,相机移到屏幕中心位置(与默认的追踪方式,是将ImageTarget下的子物体隐藏起来)
    /// 
    public void OnTrackingLost()
    {
        if (isFirstFound)
        {
            ARCamera.transform.localPosition = LostARCameraPosition;
            ARCamera.transform.localRotation = Quaternion.Euler(Vector3.zero);
        }
    }
}

  • 实现结果
    追踪到时:
    Unity Vuforia中脱卡和多目标追踪的实现_第1张图片
    丢失时:
    Unity Vuforia中脱卡和多目标追踪的实现_第2张图片

  • 多个ImageTarget追踪的实现

  • 实现思路:新建一个脚本管理ImageTarget,追踪之前,所有模型隐藏,当追踪到指定图片时,显示指定模型


using UnityEngine;
using Vuforia;
public class ChangeTrackableEventHandler : MonoBehaviour, ITrackableEventHandler
{

    private bool IsFirstFound = false;
    protected TrackableBehaviour mTrackableBehaviour;
    protected void Awake()
    {
        MoreTargetManger.Instance.TotalImageTarget.Add(this.transform);//将所有含有该脚本的Transform添加到列表当中
    }
    protected virtual void Start()
    {
        mTrackableBehaviour = GetComponent();
        if (mTrackableBehaviour)
            mTrackableBehaviour.RegisterTrackableEventHandler(this);
    }

    protected virtual void OnDestroy()
    {
        if (mTrackableBehaviour)
            mTrackableBehaviour.UnregisterTrackableEventHandler(this);
    }

    public void OnTrackableStateChanged(
        TrackableBehaviour.Status previousStatus,
        TrackableBehaviour.Status newStatus)
    {
        if (newStatus == TrackableBehaviour.Status.DETECTED ||
            newStatus == TrackableBehaviour.Status.TRACKED ||
            newStatus == TrackableBehaviour.Status.EXTENDED_TRACKED)
        {
            IsFirstFound = true;
            if (MoreTargetManger.Instance.LastTrackingName == mTrackableBehaviour.TrackableName)//当前追踪的图片和丢失的图片是相同的名字时,返回空
            {
                return;
            }
            else
            {
                MoreTargetManger.Instance.HideImageTarget();//隐藏掉所有模型
                Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " found");
                OnTrackingFound();//显示指定模型
            }

        }
        else if (previousStatus == TrackableBehaviour.Status.TRACKED &&
                 newStatus == TrackableBehaviour.Status.NOT_FOUND)
        {
            if (IsFirstFound)
            {
                MoreTargetManger.Instance.LastTrackingName = mTrackableBehaviour.TrackableName;//找到丢失ImageTarge的名字
                MoreTargetManger.Instance.Lost = true;//开启脱卡
            }
        }
        else
        {
            OnTrackingLost();
        }
    }
    protected virtual void OnTrackingFound()
    {
        var rendererComponents = GetComponentsInChildren(true);
        var colliderComponents = GetComponentsInChildren(true);
        var canvasComponents = GetComponentsInChildren(true);

        // Enable rendering:
        foreach (var component in rendererComponents)
            component.enabled = true;

        // Enable colliders:
        foreach (var component in colliderComponents)
            component.enabled = true;

        // Enable canvas':
        foreach (var component in canvasComponents)
            component.enabled = true;
    }

    public virtual void OnTrackingLost()
    {
        var rendererComponents = GetComponentsInChildren(true);
        var colliderComponents = GetComponentsInChildren(true);
        var canvasComponents = GetComponentsInChildren(true);

        // Disable rendering:
        foreach (var component in rendererComponents)
            component.enabled = false;

        // Disable colliders:
        foreach (var component in colliderComponents)
            component.enabled = false;

        // Disable canvas':
        foreach (var component in canvasComponents)
            component.enabled = false;
    }
}

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

public class MoreTargetManger : MonoBehaviour {
    private GameObject ARCamera;
    private Vector3 LostARCameraPosition = new Vector3(0.004f, 0.158f, -0.413f);
    public static MoreTargetManger Instance;
    public List TotalImageTarget = new List();
    public string LastTrackingName = "";
    public bool Lost = false;
    public static MoreTargetManger instance
    {
        get
        {
            return Instance;
        }
    }
    private void Awake()
    {
        Instance = this;
        ARCamera = GameObject.Find("ARCamera");
    }
    // Use this for initialization
    void Start () {
        
	}
	
	// Update is called once per frame
	void Update () {
        if (Lost)
        {
            Lost = false;
            ARCamera.transform.localPosition = LostARCameraPosition;
            ARCamera.transform.localRotation = Quaternion.Euler(Vector3.zero);
        }
    }
    public void HideImageTarget()
    {
        foreach (Transform ImageTarget in TotalImageTarget)
        {
            ImageTarget.GetComponent().OnTrackingLost();
        }
    }
}

  • 实现结果
    Unity Vuforia中脱卡和多目标追踪的实现_第3张图片
    Unity Vuforia中脱卡和多目标追踪的实现_第4张图片

你可能感兴趣的:(Unity Vuforia中脱卡和多目标追踪的实现)