Create and Load Targets in Unity

Use the Vuforia Engine C# API to create, load, and modify Vuforia targets at runtime. You can create Vuforia targets from databases stored locally on the device or download them from a server.

Introduction

Create and load targets at runtime with API scripting. Scenarios for this could, for example, be solely for tracking targets, switching between targets, or receiving databases at runtime.

See also Instant Image Targets, which lets you generate an Image Target from a suitable image source rather than from a database.

ObserverFactory

The ObserverFactory class has the methods for creating Observer Behaviours, including Model Targets, Area Targets, and Image Targets. Each method also has an asynchronous method you can use to avoid blocking the main thread.

Database path

When you create a Vuforia target at runtime, you load the database and assets from the device’s local storage. In Unity projects, this is generally done by placing the needed files - .xml and .dat files – in the StreamingAssets/Vuforia folder before building the app. At runtime, Vuforia targets are loaded and created from the local storage on the main thread. If you are dealing with larger databases or wish to keep the main thread free, use the Async creator functions.

For details on loading assets from device storage, see Loading from an SD card.

See also Building Large Vuforia Engine Apps in Unity if you are building a large application.

Create a Target from a Device Database at Runtime

Create an Image Target by specifying a storage path and target name. For larger apps, the device database may be bundled with the application in StreamingAssets/Vuforia. Also, note that the paths might differ depending on your target platform. In the following example, we only load the data needed for tracking an Image Target.

123456789101112131415161718192021222324252627282930313233343536
Copy
using System.IO; using UnityEngine; using Vuforia; public class CreateFromDatabase : MonoBehaviour { string dataSetPath = "Vuforia/mydevicedatabase.xml"; string targetName = "mars_target_images_astronaut"; // Start is called before the first frame update void Start() { VuforiaApplication.Instance.OnVuforiaInitialized += OnVuforiaInitialized; } void OnVuforiaInitialized(VuforiaInitError error) { if (error == VuforiaInitError.NONE) OnVuforiaStarted(); } // Load and activate a data set at the given path. void OnVuforiaStarted() { // Create an Image Target from the database. var mImageTarget = VuforiaBehaviour.Instance.ObserverFactory.CreateImageTarget( dataSetPath, targetName); mImageTarget.OnTargetStatusChanged += OnTargetStatusChanged; } void OnTargetStatusChanged(ObserverBehaviour behaviour, TargetStatus status) { Debug.Log($"target status: {status.Status}"); } }

Runtime Model Target

To create and load a Model Target, the above script can be modified by replacing the ObserverFactory method with CreateModelTarget(). A Model Target has additional parameters where hasOcclusion and hasCollision are optional:

12345678
Copy
var mModelTarget = VuforiaBehaviour.Instance.ObserverFactory.CreateModelTarget( databasePath: "/YourDatabasePath/", targetName: "TargetName", hasOcclusion: false, hasCollision: false, trackingOptimization: TrackingOptimization.DEFAULT, enhanceRuntimeDetection: false );

See also Model Target Runtime Scripting for more code samples for loading and activating Model Targets.

Runtime Area Target

Create and load an Area Target using CreateAreaTarget(). It has several parameters, but only the path, name, and location prior are mandatory:

12345678
Copy
var mAreaTarget = VuforiaBehaviour.Instance.ObserverFactory.CreateAreaTarget( databasePath: "/YourDatabasePath/", targetName: "TargetName", hasOcclusion: false, hasCollision: false, occlusionModelPath: "/OcclusionModelPath/", requiresExternalPositions: false );

Create Multiple Targets from a Device Database at Runtime

The following code snippet creates an Image Target for each provided target name in a single Device Database. OnTargetStatusChanged() reports which of the Image Targets is currently tracked. Attach this script to the ARCamera and make sure the Device Database and target names are correctly listed, as they are case-sensitive. The target names are available in the dataset XML file.

12345678910111213141516171819202122232425262728
Copy
using UnityEngine; using Vuforia; public class LoadMultipleTargetsFromDatabase : MonoBehaviour { // List of target names static readonly string[] targetNames = new[] { "Astronaut", "Oxygen", "Fissure", "Drone" }; void Start() { VuforiaApplication.Instance.OnVuforiaInitialized += OnVuforiaInitialized; } void OnVuforiaInitialized(VuforiaInitError error) { // Create an Image Target for each target name in the device database foreach (var target in targetNames) { var itBehaviour = VuforiaBehaviour.Instance.ObserverFactory.CreateImageTarget("Vuforia/VuforiaMars_Images.xml", target); Debug.Log("target created: " + target); itBehaviour.OnTargetStatusChanged += OnTargetStatusChanged; } } void OnTargetStatusChanged(ObserverBehaviour behaviour, TargetStatus status) { Debug.Log($"target status: {behaviour.TargetName} {status.Status}"); } }

In this example, loading and creating targets are done on the main thread, but if you plan to create many targets with a single call, we advise using asynchronous calls.

Create Targets Asynchronously

If you have a device database with large targets that may take time to load, you can create them using the Async methods from the ObserverFactory. These methods place the task on a background thread, freeing up the main thread for UI and other updates. The following example loads the database path and target names and assigns the creation process to an await operator, which returns the loaded targets once completed. Replace the CreateImageTargetAsync with any of the other asynchronous functions to create targets from other Vuforia features.

123456789101112131415161718192021222324252627282930313233
Copy
using UnityEngine; using Vuforia; public class AsyncTargetLoading : MonoBehaviour { static readonly string[] targetNames = new[] { "mars_target_images", "mars_target_images_oxygen", "mars_target_images_fissure", "mars_target_images_drone" }; private string databasePath = $"{Application.streamingAssetsPath}/Vuforia/My_Device_Database.xml"; void Start() { VuforiaApplication.Instance.OnVuforiaInitialized += OnVuforiaInitialized; } void OnVuforiaInitialized(VuforiaInitError error) { if(error == VuforiaInitError.NONE) { CreateIT(); } } // Start is called before the first frame update public async void CreateIT() { // Create an Image Target for each target name in the dataset foreach (var target in targetNames) { var itBehaviour = await VuforiaBehaviour.Instance.ObserverFactory.CreateImageTargetAsync(databasePath, target); Debug.Log("target created: " + target); itBehaviour.OnTargetStatusChanged += OnTargetStatusChanged; } } }

Use the same approach to create other targets asynchronously, e.g., CreateAreaTargetAsync()CreateModelTargetAsync()CreateVuMarkBehaviourAsync(), etc.

Activate Targets at Runtime

When a Vuforia Target is created at runtime, it’s enabled by default. Activate and deactivate your targets at runtime to switch between loaded targets.

Attach the script to an ImageTarget GameObject with its Image Target Behaviour component disabled.

1234567891011121314151617
Copy
using UnityEngine; using Vuforia; public class ActivateTargets : MonoBehaviour { // Start is called before the first frame update void Start() { VuforiaApplication.Instance.OnVuforiaStarted += ActivateTarget; } void ActivateTarget() { ImageTargetBehaviour imageTarget = GetComponent<ImageTargetBehaviour>(); imageTarget.enabled = true; } }

To deactivate a Vuforia target, change the imageTarget.enabled to false.

Set the Size of an Image Target at Runtime

Modify targets at runtime and its child objects to adjust the AR experience. In this example, an Image Target is scaled with a button press. Your Unity scene requires an Image Target GameObject with a cube as a child and a button UI for executing SizeMyTarget().

Attach the following script to the Image Target GameObject and assign it to the button’s OnClick()event handler.

The sample code:

123456789101112131415161718192021222324252627282930313233
Copy
using UnityEngine; using Vuforia; public class SizeImageTarget : MonoBehaviour { ImageTargetBehaviour mImageTarget; public float scale = 2; public void SizeMyTarget() { mImageTarget = GetComponent<ImageTargetBehaviour>(); if (!mImageTarget) { Debug.LogError("Cannot set scale, missing target input"); return; } // First deactivate the Image Target mImageTarget.enabled = false; // Query the current Image Target size Vector2 currentSize = mImageTarget.GetSize(); // Set the new size with a scale factor to height or width float width = currentSize.x; float newSize = scale * width; mImageTarget.SetWidth(newSize); // Re-activate the Image Target mImageTarget.enabled = true; } }

Can this page be better?
Share your feedback via our issue tracker