This article explains how to create a basic Vuforia app with User Defined Targets (UDT) in Unity. The app in question allows the user to click on a button and create a UDT with a simple augmentation (e.g. a cube 3D model).
Steps:
- create a new Unity project
- import the Vuforia Unity Extension package (vuforia-unity-android-ios-X-Y-Z.unitypackage)
- remove the Main Camera from your scene
- browse your Project view to the 'Assets/Qualcomm Augmented reality/Prefabs' folder
- drag the ARCamera and the UserDefinedTargetBuilder prefabs into your scene
- also drag an ImageTarget prefab into the scene
- select the ImageTarget object that you just dragged into the scene and change its Type to User Defined (in the Inspector panel)
- select the UserDefinedBuilder object in your scene and look at the Inspector panel
- within the inspector, tick the "Start Scanning Automatically" checkbox (i.e. enable automatic scan at start)
- create a C# script called for example 'SimpleUDTHandler.cs'
- attach this script to the UserDefinedTargetBuilder object in your scene
- implement the SimpleUDTHandler script as explained in the following:
- implement the IUserDefinedTargetEventHandler interface and register it with the UserDefinedTargetBuilder, as shown in this example:
public class SimpleUDTHandler : MonoBehaviour, IUserDefinedTargetEventHandler { private UserDefinedTargetBuildingBehaviour mTargetBuildingBehaviour; private ImageTracker mImageTracker; 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); } }
- implements the OnInitialized() callback method of the IUserDefinedTargetEventHandler interface; in particular, this is where you should set the mUdtInitialized variable to true and create a Dataset to host all your UDT targets :
public void OnInitialized() { // look up the ImageTracker once and store a reference mImageTracker = TrackerManager.Instance.GetTracker<ImageTracker>(); if (mImageTracker != null) { // create a new dataset mBuiltDataSet = mImageTracker.CreateDataSet(); mImageTracker.ActivateDataSet(mBuiltDataSet); // remember that the component has been initialized mUdtInitialized = true; } }
- implements the OnFrameQualityChanged() callback method of the IUserDefinedTargetEventHandler interface; for instance, this is where you typically simply store the current frame quality value in a private variable called mFrameQuality:
public void OnFrameQualityChanged(ImageTargetBuilder.FrameQuality frameQuality) { mFrameQuality = frameQuality; }
- implements the OnNewTrackableSource() callback method of the IUserDefinedTargetEventHandler interface; this is the callback where a new trackable source is reported by Vuforia when a new UDT target is built; for example, the following code will first clone an template image target (i.e. the variable called ImageTargetTemplate) and then use it to create the actual trackable via the mBuiltDataSet.CreateTrackable:
public void OnNewTrackableSource(TrackableSource trackableSource) { // deactivates the dataset first mImageTracker.DeactivateDataSet(mBuiltDataSet); // get predefined trackable (template) and instantiate it ImageTargetBehaviour imageTargetCopy = (ImageTargetBehaviour)Instantiate(ImageTargetTemplate); // add the trackable to the data set and activate it mBuiltDataSet.CreateTrackable(trackableSource, imageTargetCopy.gameObject); // Re-activate the dataset mImageTracker.ActivateDataSet(mBuiltDataSet); }
- In the code above, note that the ImageTargetTemplate is a public member variable that we have defined in our class; this variable must be assigned to an ImageTarget object in our scene; to do this, go to the scene view in your Unity editor, and drag the ImageTarget object (in your scene) onto the "Image Target Template" field in the Inspector view of your UserDefinedTargetBuilder (to which this script is attached).
- Next, implement the OnGUI() method, where you can put some GUI code to show a "Build New Target" "Button on the screen; this button will allow the user to build a UDT upon click. Note that the button should only be displayed if the current frame quality is sufficiently high to allow UDT creation (i.e. MEDIUM or HIGH quality):
void OnGUI() { if (!mUdtInitialized) return; // If Frame Quality is medium / high => show Button to build target if (mFrameQuality == ImageTargetBuilder.FrameQuality.FRAME_QUALITY_HIGH || mFrameQuality == ImageTargetBuilder.FrameQuality.FRAME_QUALITY_MEDIUM) { if (GUI.Button(new Rect(200, Screen.height - 100, 200, 90), "Build New Target")) { BuildNewTarget(); } } }
- finally, implement the BuildNewTarget() method (which is called from the OnGUI() code above):
private void BuildNewTarget() { string newTargetName = "MyUserDefinedTarget"; mTargetBuildingBehaviour.BuildNewTarget(newTargetName, ImageTargetTemplate.GetSize().x); }
- Save the script, go back to the unity editor, save the current scene, build and run
- Enjoy the result!