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 that lets you generate an Image Target from a suitable image source rather than from a database.

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.

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 an Image Target from a Device Database at Runtime

Similar to other instant Image Target creation methods, you specify a storage path when loading from a local directory. For larger apps, the device database may be bundled with the application in StreamingAssets/Vuforia. Also, note that the paths might differ dependent on the platform you are building to. In the following example, we only load the data needed for tracking an Image Target.

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}");
    }
}

To load and track other targets, the above script can be modified by replacing the dataSetPath and targetName with a different dataset, and changing the CreateImageTarget() to CreateModelTarget(), CreateAreaTarget(), etc.. To add content to a target at runtime, see Vuforia Engine in Unity.

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. Loading and creating targets is a blocking operation and you should run on a separate thread or as a coroutine if you plan to create many targets with a single call.

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 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}");
    }
}

 

Activate Targets at Runtime

When a Vuforia Target is created at runtime, it’s enabled by default. You can enable and disable your targets at runtime if you for example wish to switch between loaded targets.

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

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 disable 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 enable users in 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 with the method.

The sample code:

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;
    }
}