How to Locate Vuforia Datasets in StreamingAssets on ML2?

I'm using Vuforia for ImageTargets tracking and I need to create the ImageTargets at runtime. I followed Create and Load Targets in Unity | Vuforia Library for async creation of targets after initializing, but on ML2 I got the following log message (I'm using $"{Application.streamingAssetsPath}/Vuforia/My_Device_Database.xml" for the path to my xml file):

Error;AR;Failed to load database 'jar:file:///data/app/com.UnityTechnologies.com.unity.template.urpblank-q_RAA3amkxCDElED5Zou6w==/base.apk!/assets/Vuforia/Sudoku.xml'.;

Also here's the screenshot of ML Hub Logs:

Any help would be appreciated!

Hi,

For runtime Image Targets, you can create them from the image file and get the pointer:

var imageTarget = VuforiaBehaviour.Instance.ObserverFactory.CreateImageTarget( textureFile, printedTargetSize, targetName);

The alternative is to have the Image Targets in a database and load them at runtime to "create them", which is outlined in the top section of the article: Create an Image Target from a Device Database at Runtime

Hope that helps

Hi @emichals,

Thanks for your reply. For creating the objects, I'm using the following code:

using UnityEngine;
using Vuforia;

public class AsyncTargetLoading : MonoBehaviour
{
    static readonly string[] targetNames = new[] { "hard_1417", "hard_1418" };
    private string databasePath = $"{Application.streamingAssetsPath}/Vuforia/Sudoku.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 dataset
        foreach (var target in targetNames)
        {
            var itBehaviour = await VuforiaBehaviour.Instance.ObserverFactory.CreateImageTargetAsync(databasePath, target);

            itBehaviour.tag = "KeyTarget";
            Debug.Log("target created: " + target);
            GameObject createdObject = itBehaviour.gameObject;

            createdObject.AddComponent<MyPrefabInstantiator>();

            // itBehaviour.OnTargetStatusChanged += OnTargetStatusChanged;
            AllVariables.Instance.allImageTargets.Add(itBehaviour);

        }
    }

    void OnTargetStatusChanged(ObserverBehaviour behaviour, TargetStatus status)
    {
        Debug.Log($"target status: {behaviour.TargetName} {status.Status} {status.StatusInfo}");
    }
}

I believe this follows your async example? The problem I have is that this .xml file seems to fail to load due to unknown issues only on ML2 (I can do it successfully in play mode). My .xml file is located at StreamingAssets/Vuforia/Sudoku.xml, which looks like:

<?xml version="1.0" encoding="UTF-8"?>
<QCARConfig>
  <Tracking>
    <ImageTarget name="hard_1418" size="0.128000 0.128000" />
    <ImageTarget name="hard_1417" size="0.113000 0.113000" />
  </Tracking>
</QCARConfig>

In the Vuforia Sample for ML2 I found the imageTargets to be created not during runtime and thus cannot find any working example. Have you observed similar problems?

Thanks in advance!

Hi,

A couple things to check... is the xml file actually being copied into the APK? Perhaps there's a configuration somewhere set incorrectly so it's not being copied there. ie, verify the file is indeed where it's expected to be.

You could also check for the file in your script, before calling the CreateImageTargetAsync function, and verify it can at least be accessed by your script. In other words, confirm the file can be accessed at all, and that it's not just the CreateImageTargetAsync function that's having issues.

Also, could you try loading the database from just Vuforia/dataset.xml? Wondering if the jar:file://... is causing some sort of issue?

Hope that helps

Thanks for your reply. May I ask how can I check whether the file is copied into the APK? Also do you mean I should try to not use {Application.streamingAssetsPath} as the prefix?

I think you can unzip the APK and check if the xml file has been copied into the right place. But looking into this further, there appear to be some challenges accessing the streamingAssets folder on Android: Reading file from StreamingAssets, Android - #2 by HenryStrattonFW - Questions & Answers - Unity Discussions

That discussion above should point you in the right direction since others may be having similar issues.

I see what you mean. Seems that the xml file is located at assets\Vuforia\Sudoku.xml. I would try with webrequest. Thanks for pointing these out!

A solution to this: basically

 private string databasePath = "Vuforia/dataset.xml";

would work