归海一啸
管理员
管理员
  • 社区居民
  • 最爱沙发
  • 忠实会员
  • 喜欢达人
  • 原创写手
阅读:21858回复:20

(Unity3d)Vuforia开发高阶三-用户自定义Target(第二部分)

楼主#
更多 发布于:2015-07-01 23:13
前面介绍UDT基础开发,这里介绍怎么使用UDT的多Target对应不同模型的问题。

对于UDT的示例,我觉得有必要把这个类单独拿出来讲一下,
UserDefinedTargetEventHandler:这种类型的类在VuforiaAPI中很常见。Event Handler可以理解为事件控制器。


using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Vuforia;
public class UserDefinedTargetEventHandler : MonoBehaviour, IUserDefinedTargetEventHandler
{
    #region PUBLIC_MEMBERS
    /// <summary>
    /// Can be set in the Unity inspector to reference a ImageTargetBehaviour that is instanciated for augmentations of new user defined targets.
    /// </summary>
    public ImageTargetBehaviour ImageTargetTemplate;
    public int IndexForMostRecentlyAddedTrackable
    {
        get
        {
            return ( mTargetCounter - 1 ) % 5;
        }
    }
    #endregion PUBLIC_MEMBERS
    #region PRIVATE_MEMBERS
    private UserDefinedTargetBuildingBehaviour mTargetBuildingBehaviour;
    private ObjectTracker mObjectTracker;
    // DataSet that newly defined targets are added to
    private DataSet mBuiltDataSet;
    // currently observed frame quality
    private ImageTargetBuilder.FrameQuality mFrameQuality = ImageTargetBuilder.FrameQuality.FRAME_QUALITY_NONE;
    // counter variable used to name duplicates of the image target template
    private int mTargetCounter;
    private SampleAppUIButton mNewUserDefinedTargetButton;
    #endregion PRIVATE_MEMBERS
    /// <summary>
    /// Registers this component as a handler for UserDefinedTargetBuildingBehaviour events
    /// </summary>
    public void Init()
    {
        mTargetBuildingBehaviour = GetComponent<UserDefinedTargetBuildingBehaviour>();
        if (mTargetBuildingBehaviour)
        {
            mTargetBuildingBehaviour.RegisterEventHandler(this);
            Debug.Log ("Registering to the events of IUserDefinedTargetEventHandler");
        }
        mNewUserDefinedTargetButton = MakeUIButton();
        mNewUserDefinedTargetButton.TappedOn += OnTappedOnNewTargetButton;
    }
    public void Draw()
    {
        mNewUserDefinedTargetButton.Draw();
    }
    #region IUserDefinedTargetEventHandler implementation
    /// <summary>
    /// Called when UserDefinedTargetBuildingBehaviour has been initialized successfully
    /// </summary>
    public void OnInitialized ()
    {
        mObjectTracker = TrackerManager.Instance.GetTracker<ObjectTracker>();
        if (mObjectTracker != null)
        {
            // create a new dataset
            mBuiltDataSet = mObjectTracker.CreateDataSet();
            mObjectTracker.ActivateDataSet(mBuiltDataSet);
        }
    }
    /// <summary>
    /// Updates the current frame quality
    /// </summary>
    public void OnFrameQualityChanged(ImageTargetBuilder.FrameQuality frameQuality)
    {
        mFrameQuality = frameQuality;
    }
  
    /// <summary>
    /// Takes a new trackable source and adds it to the dataset
    /// This gets called automatically as soon as you 'BuildNewTarget with UserDefinedTargetBuildingBehaviour
    /// </summary>
    public void OnNewTrackableSource(TrackableSource trackableSource)
    {
        mTargetCounter++;
        // deactivates the dataset first
        mObjectTracker.DeactivateDataSet(mBuiltDataSet);
        // Destroy the oldest target if the dataset is full or the dataset 
        // already contains five user-defined targets.
        if (mBuiltDataSet.HasReachedTrackableLimit() || mBuiltDataSet.GetTrackables().Count() >= 5)
        {
            IEnumerable<Trackable> trackables = mBuiltDataSet.GetTrackables();
            Trackable oldest = null;
            foreach (Trackable trackable in trackables)
                if (oldest == null || trackable.ID < oldest.ID)
                    oldest = trackable;
              
            if (oldest != null)
            {
                Debug.Log("Destroying oldest trackable in UDT dataset: " + oldest.Name);
                mBuiltDataSet.Destroy(oldest, true);
            }
        }
        // get predefined trackable and instantiate it
        ImageTargetBehaviour imageTargetCopy = (ImageTargetBehaviour)Instantiate(ImageTargetTemplate);
        imageTargetCopy.gameObject.name = "UserDefinedTarget-" + mTargetCounter;
        // add the duplicated trackable to the data set and activate it
        mBuiltDataSet.CreateTrackable(trackableSource, imageTargetCopy.gameObject);
        // activate the dataset again
        mObjectTracker.ActivateDataSet(mBuiltDataSet);
        //Extended Tracking with user defined targets only works with the most recently defined target.
        //If tracking is enabled on previous target, it will not work on newly defined target.
        //Don't need to call this if you don't care about extended tracking.
        StopExtendedTracking();
        mObjectTracker.Stop();
        mObjectTracker.ResetExtendedTracking();
        mObjectTracker.Start();
    }
    #endregion IUserDefinedTargetEventHandler implementation
    #region PRIVATE_METHODS
    /// <summary>
    /// Instantiates a new user-defined target and is also responsible for dispatching callback to 
    /// IUserDefinedTargetEventHandler::OnNewTrackableSource
    /// </summary>
    private void BuildNewTarget()
    {
        // create the name of the next target.
        // the TrackableName of the original, linked ImageTargetBehaviour is extended with a continuous number to ensure unique names
        string targetName = string.Format("{0}-{1}", ImageTargetTemplate.TrackableName, mTargetCounter);
        // generate a new target name:
        mTargetBuildingBehaviour.BuildNewTarget(targetName, ImageTargetTemplate.GetSize().x);
    }
    private void OnTappedOnNewTargetButton()
    {
        BuildNewTarget();
    }
    /// <summary>
    /// This method only demonstrates how to handle extended tracking feature when you have multiple targets in the scene
    /// So, this method could be removed otherwise
    /// </summary>
   private void StopExtendedTracking()
    {
        StateManager stateManager = TrackerManager.Instance.GetStateManager();
        //If the extended tracking is enabled, we first disable OTT for all the trackables
        //and then enable it for the newly created target
        //UDTUIEventHandler uiMenuEventHandler = FindObjectOfType(typeof(UDTUIEventHandler)) as UDTUIEventHandler;
        if(UDTUIEventHandler.ExtendedTrackingIsEnabled)
        {
            //Stop extended tracking on all the trackables
            foreach(var behaviour in stateManager.GetTrackableBehaviours())
            {
                var imageBehaviour = behaviour as ImageTargetBehaviour;
                if(imageBehaviour != null)
                {
                    imageBehaviour.ImageTarget.StopExtendedTracking();
                }
            }
            List<TrackableBehaviour> list =  stateManager.GetTrackableBehaviours().ToList();
            ImageTargetBehaviour bhvr = list[IndexForMostRecentlyAddedTrackable] as ImageTargetBehaviour;
            if(bhvr != null)
            {
                Debug.Log("ExtendedTracking enabled for " + bhvr.name);
                bhvr.ImageTarget.StartExtendedTracking();
            }
        }
    }
    private SampleAppUIButton MakeUIButton()
    {
        Rect rect = new Rect(0.36f * Screen.width, Screen.height - (130 * Screen.width)/800.0f, 0.28f * Screen.width, (100.0f * Screen.width)/800.0f);
        GUIStyle style = new GUIStyle();
        style.normal.background = Resources.Load("UserInterface/capture_button_normal_XHigh") as Texture2D;
        style.active.background = Resources.Load("UserInterface/capture_button_normal_XHigh") as Texture2D;
        style.onNormal.background = Resources.Load("UserInterface/capture_button_normal_XHigh") as Texture2D;
        style.alignment = TextAnchor.MiddleCenter;
        Texture imageForButton = Resources.Load("UserInterface/icon_camera") as Texture;
        return new SampleAppUIButton(rect, style, imageForButton);
    }
    #endregion PRIVATE_METHODS
}

OnNewTrackableSource这个方法,新建一个Target的时候调用,即当你取了一个场景之后,就会掉用这个方法,并且mTargetCounter这个变量会自动增一。所以,对于不同的场景,自定义后渲染不同的模型,必然在这个方法中实现,并且个mTargetCounter这个变量密切相关。
/// <summary>
    /// Takes a new trackable source and adds it to the dataset
    /// This gets called automatically as soon as you 'BuildNewTarget with UserDefinedTargetBuildingBehaviour
    /// </summary>
    public void OnNewTrackableSource(TrackableSource trackableSource)
    {
        mTargetCounter++;
          
        // deactivates the dataset first
        mObjectTracker.DeactivateDataSet(mBuiltDataSet);
  
        // Destroy the oldest target if the dataset is full or the dataset 
        // already contains five user-defined targets.
        if (mBuiltDataSet.HasReachedTrackableLimit() || mBuiltDataSet.GetTrackables().Count() >= 5)
        {
            IEnumerable<Trackable> trackables = mBuiltDataSet.GetTrackables();
            Trackable oldest = null;
            foreach (Trackable trackable in trackables)
                if (oldest == null || trackable.ID < oldest.ID)
                    oldest = trackable;
              
            if (oldest != null)
            {
                Debug.Log("Destroying oldest trackable in UDT dataset: " + oldest.Name);
                mBuiltDataSet.Destroy(oldest, true);
            }
        }
        // get predefined trackable and instantiate it
        // 
        ImageTargetBehaviour imageTargetCopy = (ImageTargetBehaviour)Instantiate(ImageTargetTemplate);
        imageTargetCopy.gameObject.name = "UserDefinedTarget-" + mTargetCounter;
          
        // add the duplicated trackable to the data set and activate it
        mBuiltDataSet.CreateTrackable(trackableSource, imageTargetCopy.gameObject);
  
        // activate the dataset again
        mObjectTracker.ActivateDataSet(mBuiltDataSet);
  
        //Extended Tracking with user defined targets only works with the most recently defined target.
        //If tracking is enabled on previous target, it will not work on newly defined target.
        //Don't need to call this if you don't care about extended tracking.
        StopExtendedTracking();
        mObjectTracker.Stop();
        mObjectTracker.ResetExtendedTracking();
        mObjectTracker.Start();
// 根据mTargetCounter 判断是第几个Target,1表示第一个,2表示第二个,以此类推。
// 当然,数量很多的时候,使用switch会更好。这里判断是第几个标志,然后对应添加不同的模型。如果需要使用非Unity原生模型,使用GameObject.Find方法获取模型对象即可。
        if (mTargetCounter == 1) {
            GameObject cube = GameObject.CreatePrimitive (PrimitiveType.Cube);
            cube.name = "mycube";
            cube.transform.parent = imageTargetCopy.transform;
            cube.transform.localScale = new Vector3 (0.25f, 0.25f, 0.25f);
            cube.transform.localPosition = new Vector3 (0, 0, 0);
            cube.transform.localRotation = Quaternion.identity;
        }  else if (mTargetCounter == 2) {
            GameObject sphere = GameObject.CreatePrimitive (PrimitiveType.Sphere);
            sphere.name = "mySphere";
            sphere.transform.parent = imageTargetCopy.transform;
            sphere.transform.localScale = new Vector3 (0.25f, 0.25f, 0.25f);
            sphere.transform.localPosition = new Vector3 (0, 0, 0);
            sphere.transform.localRotation = Quaternion.identity;
        }
    }
AR学院(www.arvrschool.com),从这里感触未来!

欢迎分享

citysix
贫民
贫民
  • UID111
  • 粉丝0
  • 关注0
  • 发帖数2
  • 社区居民
沙发#
发布于:2015-08-28 00:15
太厉害了!!!!受教了!!!
Mrzhang2015
侠客
侠客
  • UID342
  • 粉丝0
  • 关注0
  • 发帖数34
板凳#
发布于:2015-11-22 16:53
学习了!!!!!!!!!!!!!
lulu1971cn
新手
新手
  • UID109
  • 粉丝0
  • 关注1
  • 发帖数7
地板#
发布于:2016-01-06 16:13
老大,请问User Defined Targets可以在程序退出前保存下来,在下次重新进入程序时继续使用吗?
归海一啸
管理员
管理员
  • 社区居民
  • 最爱沙发
  • 忠实会员
  • 喜欢达人
  • 原创写手
4楼#
发布于:2016-01-06 17:27
lulu1971cn:老大,请问User Defined Targets可以在程序退出前保存下来,在下次重新进入程序时继续使用吗?回到原帖
理论上应该是可行的
AR学院(www.arvrschool.com),从这里感触未来!
lulu1971cn
新手
新手
  • UID109
  • 粉丝0
  • 关注1
  • 发帖数7
5楼#
发布于:2016-01-14 12:01
归海一啸:理论上应该是可行的回到原帖
具体该怎么保存,可以提示一下吗?我是新手,谢谢了!
归海一啸
管理员
管理员
  • 社区居民
  • 最爱沙发
  • 忠实会员
  • 喜欢达人
  • 原创写手
6楼#
发布于:2016-01-18 09:49
lulu1971cn:具体该怎么保存,可以提示一下吗?我是新手,谢谢了!回到原帖
这个功能我还没看,等有空看了再发帖哈
AR学院(www.arvrschool.com),从这里感触未来!
wangyong
侠客
侠客
  • UID778
  • 粉丝0
  • 关注0
  • 发帖数25
7楼#
发布于:2016-01-18 11:05
这个 写了一个类吗?怎么没看到
1739516172
精灵王
精灵王
  • UID748
  • 粉丝0
  • 关注3
  • 发帖数60
  • 社区居民
  • 忠实会员
8楼#
发布于:2016-02-24 15:58
新的vuforia的sdk好像找不到UserDefinedTargetEventHandler,怎么找到mTargetCounter呢?大大神
LennyYi
侠客
侠客
  • UID1658
  • 粉丝0
  • 关注0
  • 发帖数25
  • 忠实会员
9楼#
发布于:2016-08-01 17:59
学到这里的时候,我发现用U3D必须有足够的细心,才能学的快。一个小小的地方没有配置好就不能运行。先把心得写在这里。我会越来越强的。
归海一啸
管理员
管理员
  • 社区居民
  • 最爱沙发
  • 忠实会员
  • 喜欢达人
  • 原创写手
10楼#
发布于:2016-08-02 10:32
LennyYi:学到这里的时候,我发现用U3D必须有足够的细心,才能学的快。一个小小的地方没有配置好就不能运行。先把心得写在这里。我会越来越强的。回到原帖
AR学院(www.arvrschool.com),从这里感触未来!
归海一啸
管理员
管理员
  • 社区居民
  • 最爱沙发
  • 忠实会员
  • 喜欢达人
  • 原创写手
11楼#
发布于:2016-08-02 10:34
1739516172:新的vuforia的sdk好像找不到UserDefinedTargetEventHandler,怎么找到mTargetCounter呢?大大神回到原帖
新的版本API改了,你需要去官网查询下APIhttps://developer.vuforia.com/library/api-list
AR学院(www.arvrschool.com),从这里感触未来!
lqbhmj
贫民
贫民
  • UID2470
  • 粉丝0
  • 关注0
  • 发帖数2
12楼#
发布于:2016-08-24 14:12
lulu1971cn:具体该怎么保存,可以提示一下吗?我是新手,谢谢了!回到原帖
@归海一啸:这个问题解决了吗?搞了几天还没找到解决方案
15527472812
贫民
贫民
  • UID2744
  • 粉丝0
  • 关注1
  • 发帖数3
13楼#
发布于:2016-10-08 19:18
请问 这个功能要怎么用啊? 直接挂脚本吗?可以我的Vuforia的script文件夹下面没有UserDefinedTargetEventHandler这个脚本啊。        我现在想完成的是 比如我有五本书,每本书里面有5个Imagetarget。 我选择进入不同的书的时候就能识别这本书里面对应的模型。  但是现在项目运行起来后,每次都只能识别到第一本书里面的5个模型,当返回选择后面几本书然后去识别的时候就出不来模型了。   我把书本的顺序改变了之后也是一样只能识别第一本书里面的模型,就想问是什么原因呢,是不是需要用到你这本教程所说的知识啊? 麻烦了
88234213
贫民
贫民
  • UID1934
  • 粉丝0
  • 关注0
  • 发帖数3
14楼#
发布于:2016-10-15 15:24
每个版本API都不一样。。。
上一页
游客

返回顶部