Log in or register to post comments

Dynamically Load .unity Trackable File from Web

September 17, 2012 - 9:35am #1

Hi All -

Is it possibly to dynamically load the .unity file (containing trackables created in qdevnet) from a web service at runtime on mobile devices? Need to replace existing trackables associated with target images in unity scene without having to do it manually and then recompile the app.

If so... what is the best way?

Many thanks.

Dynamically Load .unity Trackable File from Web

April 21, 2015 - 7:27am #16

I want to make a system that I can use to download various targets dynamically from my website without using "Cloud" system. I also want to save the dataset to .xml and .dat formats which I want to activate from my saving device.

There are a lot of methods and pages to doing that with vuforia and unity, but unfortunately when I test it I receive an error for all of them. It seems that i have made a mistake in my code or a vuforia class was changed.

For instance please look this link: https://developer.vuforia.com/library/articles/Solution/Unity-Load-DataSet-from-SD-Card I got Error: Using Vuforia;

I placed the .xml and .dat files in "Application.persistentDataPath + "/" + "Building1.xml" i used this Script "DataSetLoadBehavior" that attached "AR Camera and placed my code in it. I got an Error:

NullReferenceException: Object reference not set to an instance of an object DataSetLoadBehaviour.OnInitialized () (at Assets/Qualcomm Augmented Reality/Scripts/DataSetLoadBehaviour.cs:49) DataSetLoadBehaviour.Start () (at Assets/Qualcomm Augmented Reality/Scripts/DataSetLoadBehaviour.cs:80)

My code is this:

unity 4.2 pro and vuforia 2.8.9 or 3.0.9

/*==============================================================================
Copyright (c) 2010-2014 Qualcomm Connected Experiences, Inc.
All Rights Reserved.
Confidential and Proprietary - Qualcomm Connected Experiences, Inc.
==============================================================================*/

using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// This behaviour allows to automatically load and activate one or more DataSet on startup
/// </summary>
public class DataSetLoadBehaviour : DataSetLoadAbstractBehaviour
{
       [HideInInspector, SerializeField]
       public List<string> mDataSetsToActivate2 = new List<string>();
      [SerializeField, HideInInspector]
    public List<string> mDataSetsToLoad2 = new List<string>();

    protected DataSetLoadBehaviour()
    {
    }
    private void OnDestroy()
    {
        QCARAbstractBehaviour behaviour = (QCARAbstractBehaviour) UnityEngine.Object.FindObjectOfType(typeof(QCARAbstractBehaviour));
        if (behaviour != null)
        {

        }
    }

    public void OnInitialized()
    {

        if (QCARRuntimeUtilities.IsQCAREnabled())
        {
            foreach (string str in this.mDataSetsToLoad2)
            {

                if (!DataSet.Exists(str, QCARUnity.StorageType.STORAGE_ABSOLUTE))

                {
                    Debug.LogError("Data set " + str + " does not exist.");
                }
                else
                {

                    ImageTracker tracker = TrackerManager.Instance.GetTracker<ImageTracker>();
                    DataSet dataSet = tracker.CreateDataSet();
                    if (!dataSet.Load(str))
                    {
                        Debug.LogError("Failed to load data set " + str + ".");
                    }
                    else if (this.mDataSetsToActivate2.Contains(str))
                    {
                        tracker.ActivateDataSet(dataSet);
                    }
                }
            }
        }
    }

    public void OnTrackablesUpdated()
    {
    }

    private void Start()
    {

        QCARAbstractBehaviour behaviour = (QCARAbstractBehaviour) UnityEngine.Object.FindObjectOfType(typeof(QCARAbstractBehaviour));
        if (behaviour != null)
        {


            mDataSetsToLoad2.Add(Application.persistentDataPath + "/" + "Building1.xml");




            OnInitialized();
        }
    }
    public override void AddOSSpecificExternalDatasetSearchDirs()
    {
#if UNITY_ANDROID
        if (Application.platform == RuntimePlatform.Android)
        {
            // Get the external storage directory
            AndroidJavaClass jclassEnvironment = new AndroidJavaClass("android.os.Environment");
            AndroidJavaObject jobjFile = jclassEnvironment.CallStatic<AndroidJavaObject>("getExternalStorageDirectory");
            string externalStorageDirectory = jobjFile.Call<string>("getAbsolutePath");

            // Get the package name
            AndroidJavaObject jobjActivity = new AndroidJavaClass("com.unity3d.player.UnityPlayer").GetStatic<AndroidJavaObject>("currentActivity");
            string packageName = jobjActivity.Call<string>("getPackageName");

            // Add some best practice search directories
            //
            // Assumes just Vufroria datasets extracted to the files directory
            AddExternalDatasetSearchDir(externalStorageDirectory + "/Android/data/" + packageName + "/files/");
            // Assume entire StreamingAssets dir is extracted here and our datasets are in the "QCAR" directory
            AddExternalDatasetSearchDir(externalStorageDirectory + "/Android/data/" + packageName + "/files/QCAR/");
        }
#endif //UNITY_ANDROID
    }

    void Update()
    {

    }

}

 

Dynamically Load .unity Trackable File from Web

November 7, 2012 - 9:31pm #15

On further debugging, it seems "dataSet.GetNumTrackables()" always returning zero even though i have 12 trackables in the dataset...What will be the problem here ??

Because GetNumTrackables method is available as dll only and couldnt trace further...Please suggest :-(

Dynamically Load .unity Trackable File from Web

November 7, 2012 - 9:13pm #14

In the LoadAndActivate method, it comes to,

Debug.Log("Data set Exist");

ImageTracker imageTracker = (ImageTracker)TrackerManager.Instance.GetTracker(Tracker.Type.IMAGE_TRACKER);

DataSet dataSet = imageTracker.CreateDataSet();

Debug.Log("Is Dataset null - " +dataSet);

And here after executing " imageTracker.CreateDataSet();" it prints the details of Trackables and then prints null reference....I tried to trace it but failed...

Very hard to debug as we can test only in device....

Can you trace where could be the problem ?? The output also is pasted in the last post..

 

Dynamically Load .unity Trackable File from Web

November 7, 2012 - 3:37am #13

So atlast loaded dataset in the app directly by downloading from server...Thanks a lot for your continuous support...

But still i have one thing to do, when i capture a target image it is not getting recognized and printed in console lik "Image found" "Image lost",

How can i add that behaviour to the object and also am pasting the log from device here for your reference...

I/Unity   (13929): Creating Image Target with values:

I/Unity   (13929):  ID:           3

I/Unity   (13929):  Name:         Airtel_1

I/Unity   (13929):  Path:         /data/data/com.BeHappy.LoadAndActivate/files/H

ighRes_Logos.xml

I/Unity   (13929):  Storage Type: STORAGE_ABSOLUTE

I/Unity   (13929):  Size:         420x336

I/Unity   (13929):

I/Unity   (13929): (Filename: ./Runtime/ExportGenerated/AndroidManaged/UnityEngi

neDebug.cpp Line: 43)

I/Unity   (13929):

I/Unity   (13929): Creating Image Target with values:

I/Unity   (13929):  ID:           4

I/Unity   (13929):  Name:         Airtel_2

I/Unity   (13929):  Path:         /data/data/com.BeHappy.LoadAndActivate/files/H

ighRes_Logos.xml

I/Unity   (13929):  Storage Type: STORAGE_ABSOLUTE

I/Unity   (13929):  Size:         420x185.7393

I/Unity   (13929):

I/Unity   (13929): (Filename: ./Runtime/ExportGenerated/AndroidManaged/UnityEngi

neDebug.cpp Line: 43)

I/Unity   (13929):

I/Unity   (13929): Creating Image Target with values:

I/Unity   (13929):  ID:           5

I/Unity   (13929):  Name:         Airtel_3

I/Unity   (13929):  Path:         /data/data/com.BeHappy.LoadAndActivate/files/H

ighRes_Logos.xml

I/Unity   (13929):  Storage Type: STORAGE_ABSOLUTE

I/Unity   (13929):  Size:         500x400

I/Unity   (13929):

I/Unity   (13929): (Filename: ./Runtime/ExportGenerated/AndroidManaged/UnityEngi

neDebug.cpp Line: 43)

I/Unity   (13929):

I/Unity   (13929): Creating Image Target with values:

I/Unity   (13929):  ID:           6

I/Unity   (13929):  Name:         Hyundai_1

I/Unity   (13929):  Path:         /data/data/com.BeHappy.LoadAndActivate/files/H

ighRes_Logos.xml

I/Unity   (13929):  Storage Type: STORAGE_ABSOLUTE

I/Unity   (13929):  Size:         420x262.132

I/Unity   (13929):

I/Unity   (13929): (Filename: ./Runtime/ExportGenerated/AndroidManaged/UnityEngi

neDebug.cpp Line: 43)

I/Unity   (13929):

I/Unity   (13929): Creating Image Target with values:

I/Unity   (13929):  ID:           7

I/Unity   (13929):  Name:         Hyundai_2

I/Unity   (13929):  Path:         /data/data/com.BeHappy.LoadAndActivate/files/H

ighRes_Logos.xml

I/Unity   (13929):  Storage Type: STORAGE_ABSOLUTE

I/Unity   (13929):  Size:         400x224

I/Unity   (13929):

I/Unity   (13929): (Filename: ./Runtime/ExportGenerated/AndroidManaged/UnityEngi

neDebug.cpp Line: 43)

I/Unity   (13929):

I/Unity   (13929): Creating Image Target with values:

I/Unity   (13929):  ID:           8

I/Unity   (13929):  Name:         Hyundai_3

I/Unity   (13929):  Path:         /data/data/com.BeHappy.LoadAndActivate/files/H

ighRes_Logos.xml

I/Unity   (13929):  Storage Type: STORAGE_ABSOLUTE

I/Unity   (13929):  Size:         247x150.9016

I/Unity   (13929):

I/Unity   (13929): (Filename: ./Runtime/ExportGenerated/AndroidManaged/UnityEngi

neDebug.cpp Line: 43)

I/Unity   (13929):

I/Unity   (13929): Creating Image Target with values:

I/Unity   (13929):  ID:           9

I/Unity   (13929):  Name:         Honda_1

I/Unity   (13929):  Path:         /data/data/com.BeHappy.LoadAndActivate/files/H

ighRes_Logos.xml

I/Unity   (13929):  Storage Type: STORAGE_ABSOLUTE

I/Unity   (13929):  Size:         400x270

I/Unity   (13929): Creating Image Target with values:

I/Unity   (13929):  ID:           12

I/Unity   (13929):  Name:         Vodafone_small_1

I/Unity   (13929):  Path:         /data/data/com.BeHappy.LoadAndActivate/files/H

ighRes_Logos.xml

I/Unity   (13929):  Storage Type: STORAGE_ABSOLUTE

I/Unity   (13929):  Size:         40x19.27115

I/Unity   (13929):

I/Unity   (13929): (Filename: ./Runtime/ExportGenerated/AndroidManaged/UnityEngi

neDebug.cpp Line: 43)

I/Unity   (13929):

I/Unity   (13929): NullReferenceException: Object reference not set to an instan

ce of an object

I/Unity   (13929):   at LoadAndActivate.LoadAndActivateDataSet (System.String da

taSetPath) [0x00000] in <filename unknown>:0

I/Unity   (13929):   at LoadAndActivate.OnGUI () [0x00000] in <filename unknown>

 

Am not sure where this error comes from as am debugging it via adb logcat....Fetching the name while capturing the image will end my app successfully....

Kindly help...

Dynamically Load .unity Trackable File from Web

November 6, 2012 - 8:55pm #12

I placed the xml and dat files in "C:/Users/BeHappy/AppData/LocalLow/ATB/LoadAndActivate Dataset". 

When i try to load them using the code slice, it says "Dataset does not exist" Frown   Do i need to download or place any other files rather than xml or dat files for Vuforia to recognize it as a dataset ??

Am calling the LoadAndActivateDataset Function given by you...I call them using"LoadAndActivateDataSet(" C:/Users/BeHappy/AppData/LocalLow/ATB/LoadAndActivate Dataset /HighRes_Logos.xml");

What may be the problem here ??

Dynamically Load .unity Trackable File from Web

November 6, 2012 - 4:00am #11

The SDK documentation shows how to do this:

https://ar.qualcomm.at/sdk/android

Getting Started - Unity Extension

    >Step 3 Mastering Advanced Topics

          >Swappable Datasets

and it shows the code below to load and activate a dataset.

 

N

 

 

// Load and activate a data set at the given path.

private bool LoadDataSet(string dataSetPath, DataSet.StorageType storageType)
{
    // Check if the data set exists at the given path.
    
    if (!DataSet.Exists(dataSetPath, storageType))
    {
        Debug.LogError("Data set " + dataSetPath + " does not exist.");
        return false;
    }

    // Request an ImageTracker instance from the TrackerManager.
    
    ImageTracker imageTracker =
        (ImageTracker)TrackerManager.Instance.GetTracker(
                                        Tracker.Type.IMAGE_TRACKER);

    // Create a new empty data set.
    
    DataSet dataSet = imageTracker.CreateDataSet();

    // Load the data set from the given path.
    
    if (!dataSet.Load(dataSetPath, storageType))
    {
        Debug.LogError("Failed to load data set " + dataSetPath + ".");
        return false;
    }

    // (Optional) Activate the data set.
    
    imageTracker.ActivateDataSet(dataSet);

    return true;
}

Dynamically Load .unity Trackable File from Web

November 6, 2012 - 1:34am #10

DavidBeard wrote:

If you're simply attempting to load a dataset, then you don't need to package this in an AssetBundle and can use the WWW class directly.

Here is an example - http://forum.unity3d.com/threads/122110-Can-anyone-tell-me-HOW

Basically you download the file using WWW and then write it to the local file system using System.IO's File.WriteAllBytes

 

As you suggested, i extracted the .xml and .dat from unitypackage and uploaded to the server. I could now able to download them to my device and tried to load it using STORAGE_ABSOLUTE....But nothing seems working...

My .xml and .dat files are now located in "/mnt/sdcard/Android/data/com.BeHappy.SwapDataset/files". I dont want any default dataset to be loaded through inspector, i want to download this two files once when user opens the application....

So can you please help me out on bringing this dataset to work and track all the images associated with it.

 

Thanks a lot.

Dynamically Load .unity Trackable File from Web

November 5, 2012 - 3:54am #9

I think you need to use asset bundles which are a pro-only feature.

If you hunt around the Unity forums you may be able to find a "basic" workaround.

As for the size, probably the best thing is to work these out before hand within Unity and then create prefabs that are correct in size in relation to the Image Target.

 

N

Dynamically Load .unity Trackable File from Web

November 5, 2012 - 12:32am #8

Thanks Nalin, I have a similar question. I want to load 3d object as dynamic like in image target i want to load "teapot.fbx" dynamic suppose load from Shared directory in iphone this loading should be on runtime. But i think one issue is more how adjust size of 3d object which is being loading on runtime according to target.

 

Dynamically Load .unity Trackable File from Web

October 22, 2012 - 11:42pm #7

First of all Thanks a ton, NalinS and Davidbeard....You are helping all the way...Without you people i wouldnt have progressed much...

My ultimate aim of the app is,

* I have one set of trackable(around 20 images) while publishing, but twice a week i will get new images that need to be recognized along with the 20 images available with the app.

* And also i dont want to show any game objects(cube) while identifying image target, i just need the name of the marker traced. so that i can send the name to the web service and get the result.

* As of now, am done with web service and initial dataset and it is working perfect.

* Am struggling to find the right path to download and recognize new images :-(  I have unity pro right now, but not sure of how to make use of the new dataset ? 

* And do i need to add more image target to track the newly added image or using one image target itself i can find all the trackables associated with the dataset ??

with you people's suggestion i will look more into asset bundle.

Once again, Thanks a lot and lot for your continuous support. :-)

Dynamically Load .unity Trackable File from Web

October 22, 2012 - 8:18pm #6

If you're simply attempting to load a dataset, then you don't need to package this in an AssetBundle and can use the WWW class directly.

Here is an example - http://forum.unity3d.com/threads/122110-Can-anyone-tell-me-HOW

Basically you download the file using WWW and then write it to the local file system using System.IO's File.WriteAllBytes

 

 

Dynamically Load .unity Trackable File from Web

October 22, 2012 - 7:45am #5

Hi,

Please see my answer to your other question regarding AssetBundles here:

https://ar.qualcomm.at/content/please-provide-sample-swapping-dataset-unity3d

I think it might make sense for you to hunt around for information on AssetBundles, which does seem a bit sparse:

http://unity3d.com/support/documentation/ScriptReference/BuildPipeline.BuildAssetBundle.html

http://unity3d.com/support/resources/example-projects/assetbundles

It might also help to understand the structure of an imagetarget  .unitypackage so you can check that everything you expect can be accessed as you intend.

HTH

N

 

Dynamically Load .unity Trackable File from Web

October 21, 2012 - 8:39pm #4

Please Help...

Dynamically Load .unity Trackable File from Web

October 19, 2012 - 2:13am #3

Hi DavidBeard,

Can you please let me know, what are the things i should put into the Asset Bundle ?

I would like to activate a new dataset(should be downloaded from Web) for the application once after pushing to production.

Please suggest.

 

Thanks,

Muthukumar

Dynamically Load .unity Trackable File from Web

September 17, 2012 - 11:39am #2

Unity provides a WWW class to retrieve resources from URL's

http://docs.unity3d.com/Documentation/ScriptReference/WWW.html

And AssetBundles can be used to package assets and instantiate them at runtime

http://docs.unity3d.com/Documentation/ScriptReference/AssetBundle.html

* AssetBundles are a pro-only feature.

Here are some examples of how to handle datasets programmatically - https://ar.qualcomm.at/sdk/android/swappable%20datasets%20-%20android

Log in or register to post comments