您的位置:首页 > 移动开发 > Unity3D

AR—如何在Unity中使用UserDefineTarget

2016-03-23 15:56 656 查看
所谓的UDT在Untiy中的意思就是User Defined Targets 也就是用户自定义Target,接下来要实现的内容是,如何在Untiy中实现当用户点击按键的时候创建一个简单的ImageTarget来实现将用户拍摄的图片变成一个ImageTarget,这样不仅给用户带来更大的自由度,也解决了固定ImageTarget带来的麻烦。好了,下面就来说说相应的解决步骤:

第一步,创建一个新的Unity项目;

第二步,导入Vuforia Unity Extension package(vuforia-unity-android-ios-X-Y-Z.unitypackage);

第三步,将Unity中的MainCamera从场景中删掉;

第四步,然后在Project视图中打开Assets/Vuforia/Prefabs 文件夹;

第五步,拖拽ARCamera, UserDefinedTargetBuilder和ImageTarget这三个预制体到你的场景当中;这几步完成之后界面应该是这样的;(这个步骤使用过的应该很好理解,但是为了大部分人就配上图吧)



在这里需要注意一个地方就是ARCarmera中需要AppLicenseKey,这个可以在Vuforia官网进行注册就可以下载,然后粘贴到这里就可以了,具体的帖子有很多,这里就不再赘述;



全部拖拽完成了之后,就来进行相应的属性设置

ImageTarget属性设置:

1, Type类型更改为:User Defined;(也就是用户可以自定义ImageTarget)

2, 然后你可以在场景中随便创建一个对象(cube),然后将其设为Imagetarget的子级(在这里你可以自己定义好cube的位置和大小等属性和非用户自定义的步骤是一样的)

3, 如果你的场景中没有Directional Light 就再添加一个上去;

4, 选中一件添加上去的UserDefinedBuilder然后会看到有几个需要勾选的地方,将第一个勾选上也就是Start Scanning Automatically这个选项,这个选项的意思就是在开始的时候可以自动的进行摄像头的扫描;



下面咱们就开始写代码吧:

1, 创建一个C#脚本名字叫SimpleUDTHandler.cs并且将这个脚本挂到创景中的UserDefinedTargetBuilder上,下面就开始实现这个脚本,并且讲述这个脚本的具体内容。

SimpleUDTHandler.cs~~:

//在这里我们为SimpleUDTHandler引用IUserDefinedTargetEventHandler接口;下面我们就实现接口中的方法,注意:要全部都实现哦;

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

public class SimpleUDTHandler : MonoBehaviour, IUserDefinedTargetEventHandler
{
private UserDefinedTargetBuildingBehaviour mTargetBuildingBehaviour;
private ObjectTracker mObjectTracker;
private DataSet mBuiltDataSet;

private bool mUdtInitialized = false;
//这部分定义的是照相机拍摄下来图片的品质,也就是说在图片拍摄下来之后通过这个方法会返回一个枚举类型的参数
//通过这个参数判断这张图片识别的品质是否可以使用;
private ImageTargetBuilder.FrameQuality mFrameQuality = ImageTargetBuilder.FrameQuality.FRAME_QUALITY_NONE;

public ImageTargetBehaviour ImageTargetTemplate;

void Start()
{
mTargetBuildingBehaviour = GetComponent<UserDefinedTargetBuildingBehaviour>();
if (mTargetBuildingBehaviour)
{
mTargetBuildingBehaviour.RegisterEventHandler(this);
}
}
//IUserDefinedTargetEventHandler接口中OnInitialized方法的实现;
//这个方法是用来进行初始化使用的;
public void OnInitialized()
{
//这里用来实例化mObjectTracker里面的信息
mObjectTracker = TrackerManager.Instance.GetTracker<ObjectTracker>();

if (mObjectTracker != null)
{
//创建一个新的数据集,放在本地用来存放用户拍摄的ImageTarget
mBuiltDataSet = mObjectTracker.CreateDataSet();
//将数据集的状态变为激活状态;(数据集仅在没有跟踪图片的方法没有运行的时候才是激活状态)
mObjectTracker.ActivateDataSet(mBuiltDataSet);
//记录组件已经被初始化了
mUdtInitialized = true;
}
}
//IUserDefinedTargetEventHandler接口中OnFrameQualityChanged方法的实现;
//这里需要注意:这个方法只是用来接收摄像头扫描的图片品质,具体判断方法是内部封装
//ImageTargetBuilder.FrameQuality frameQuality 也就是图片的品质
/*具体的方法是这样一个抽象类,内部识别的方法我们是看不到的;
public abstract class ImageTargetBuilder
{
protected ImageTargetBuilder();
public abstract bool Build(string targetName, float sceenSizeWidth);
public abstract FrameQuality GetFrameQuality();
public abstract TrackableSource GetTrackableSource();
public abstract void StartScan();
public abstract void StopScan();
public enum FrameQuality
{
FRAME_QUALITY_NONE = -1,
FRAME_QUALITY_LOW = 0,
FRAME_QUALITY_MEDIUM = 1,
FRAME_QUALITY_HIGH = 2
}
}
*/
public void OnFrameQualityChanged(ImageTargetBuilder.FrameQuality frameQuality)
{
//将获取到的图片的品质传给mFrameQuality
mFrameQuality = frameQuality;
}
//IUserDefinedTargetEventHandler接口中OnNewTrackableSource方法的实现;
//这个方法是在初始化出现错误的时候才会被访问;
public void OnNewTrackableSource(TrackableSource trackableSource)
{
//首先关闭数据集;
mObjectTracker.DeactivateDataSet(mBuiltDataSet);
//下面这部分的作用是当数据集饱和也就是满了的时候,就会删除最开始创建的ImageTarget以此类推;
if (mBuiltDataSet.HasReachedTrackableLimit())
{
//此部分是用来加载出数据集中全部的ImageTarget对象;
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)
{
mBuiltDataSet.Destroy(oldest, true);
}
}

//获取到已经追踪到的Tarckable也就是用户拍摄的ImageTarget并且实例他就可以了;
ImageTargetBehaviour imageTargetCopy = (ImageTargetBehaviour)Instantiate(ImageTargetTemplate);
//将是实例过的ImageTarget添加到相应数据集当中;
mBuiltDataSet.CreateTrackable(trackableSource, imageTargetCopy.gameObject);
//将数据集设置为激活的状态;
mObjectTracker.ActivateDataSet(mBuiltDataSet);
}
//具体的方法咱们调用完成了之后,下面就来编写UI界面的部分啦,咱们就用OnGUI来简单的实现吧;
void OnGUI()
{
//判断是否进行了初始化 ,如果没有则返回不再执行接下来的程序;
if (!mUdtInitialized) return;
//下面我们来根据画面的画质来显示相应的界面,如果用户拍摄的图片的品质在中 高状态下我们就拍摄按键显示出来
if (mFrameQuality == ImageTargetBuilder.FrameQuality.FRAME_QUALITY_HIGH ||
mFrameQuality == ImageTargetBuilder.FrameQuality.FRAME_QUALITY_MEDIUM)
{
if (GUILayout.Button("UserDefineTarget"))
{
//如果点击了拍摄按钮我们就执行创建Target按钮;
BuildNewTarget();
}
}
}
//创建ImageTarget按钮;
private void BuildNewTarget()
{
//在这里我们可以自己定义ImageTarget名字;
string newTargetName = "MyUserDefinedTarget";
//调用创建的方法;
mTargetBuildingBehaviour.BuildNewTarget(newTargetName, ImageTargetTemplate.GetSize().x);
}
}


下面就来看看咱们的成果吧:



在运行的时候回出现这样的对话框,我们要注意的是一定要选择第二项,也就是允许使用摄像头;



画面识别的品质为中 高品质的时候,图像上就会出现一个GUI按钮;



当画面识别的品质为低品质的时候GUI按钮就会消失;

当点击按钮的时候就会在你拍摄的ImageTarget上显示出来相应的模型(我这里就用一个cube来代替了)



Hierarchy界面是这样:



这样就完成了用户自定义创建ImageTarget的功能啦,谢谢大家观看,有意见多多提呀;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: