Building Large Vuforia Engine Apps in Unity

If you are building an application with Vuforia in Unity for Android, and your application size (the APK compressed file) exceeds 100MB, you should consider some measures to reduce its size. We present in this article various suggestions and how to use the OBB expansion file in Unity.

We highly recommend consulting the platform’s official documentation on supported file size submissions to the Google Play Store as it may change. The file size limit is currently set to 100MB.

For Android: http://developer.android.com/google/play/expansion-files.html

General Tips and Suggestions

Hosting assets on a server and downloading at runtime 

If the size of your app is due to the use of large files, such as videos, 3D models and textures, or other Unity assets, you may want to consider hosting them externally, such as on a server. This way, the assets are downloaded via the network and used at runtime which dramatically reduces your app size since they are not packaged with the app.

Asset Bundles

Note that Unity also provides a convenient feature and API to achieve this, called Asset Bundles. Please refer to the official Unity Asset Bundle documentation for more details about this feature:

Unity3D Documentation – AssetBundles Intro

Or refer to this Vuforia Library section on using the AssetBundles to package augmentations.

Using OBB expansion files

Another possibility is to use the OBB expansion files, which allow your app to be larger than 100MB. By enabling the Split Application Binary option in the Player Settings, Unity splits your build into an APK and an expansion file (.obb). In the section below, we describe the practice of using expansion files and loading dataset files from there.

More general information can be found in the Unity online documentation:

Unity3D Documentation – OBB Support

OBB Expansion and Vuforia Engine

While you are allowed to use the OBB split option with Vuforia, you should be aware that certain Vuforia functionalities may need to be handled in an alternate manner.

In particular, the database loading feature is affected as the dataset files (.dat and .xml) that were placed in the Assets/StreamingAssets/Vuforia folder of your Unity project will now be part of the .obb expansion file. As a consequence, the DataSet load methods of the Vuforia API will fail to locate and load those files.

Therefore, we advise to create a custom script that retrieves and copies the dataset files of your Vuforia Targets in a separate scene before your AR scene.

High level script behavior

The custom script should read your dataset .xml and .dat files from these locations:

  1. Application.streamingAssetsPath + "/Vuforia/" + dataset_xml_filename / dataset_dat_filename
  2. Application.applicationDataPath + ''/Android/obb/" + obb_filename (check the Android developer guide for more information on the actual OBB path and filename: Google Play Store – Expansion files).

Read the .dat and .xml files using the UnityWebRequest class with a uri pointing to one of the locations above (see also https://docs.unity3d.com/ScriptReference/Networking.UnityWebRequest.html).

Get the file contents from the UnityWebRequest class, using its DownloadHandler property.

This will save the content into a new pair of .dat and .xml files at a writable location on your device storage (e.g. your SD card, or otherwise to a device’s internal storage), or, store them onto a subdirectory of Application.persistentDataPath

  • Application.persistentDataPath + "/MyDatasets/MyDataset.xml
  • and Application.persistentDataPath + "/MyDatasets/MyDataset.dat")

Use the Vuforia API to load the databases from the new location, using the STORAGE_ABSOLUTE option.

dataSet.Load(outputFilePath, VuforiaUnity.StorageType.STORAGE_ABSOLUTE);

 

For more information on dataset loading from an SD card, please refer to the ObjectTracker API Overview and Working with Vuforia Engine and Unity.

How to retrieve dataset files from the OBB expansion file

  1. Ensure that the desired databases are enabled in the Databases expandable menu under Vuforia Configuration.

NOTE: Databases are automatically added to the Databases list and will be loaded and activated as long as their TrackingBehaviour components are enabled.  

  1. Navigate Build Settings and ensure that the build platform is set to Android.
    • Continue to Player Settings -> Android Settings -> Other Settings.
    • Set Write Permissions to External (SDCard).
    • Under Publishing Settings, Check the Split Application Binary box.
  2. Create a new scene (in this example, it is named Vuforia-0-Splash) or make use of one of your scenes that is started before your Vuforia enabled scene. 
    • Add/position the scene in the Build Settings so that it is before your augmented reality scene(s).
  3. Create a GameObject in the scene and attach a new script to it with the name; ObbExtractor.cs.
    • Copy the following code example and adjust it according to your databases and file paths.

This code snippet pulls the Astronaut .dat and .xml dataset files (assuming the default Image Target database was imported) from the .obb and outputs them in the application’s persistentDataPath, allowing them to be automatically loaded once Vuforia is initialized. 

using System.IO;
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.Networking;

public class ObbExtractor : MonoBehaviour
{

    void Start()
    {
        StartCoroutine(ExtractObbDatasets());
    }

    private IEnumerator ExtractObbDatasets()
    {
        string[] filesInOBB = { "Astronaut.dat", "Astronaut.xml" };
        foreach (var filename in filesInOBB)
        {
            string uri = Application.streamingAssetsPath + "/Vuforia/" + filename;

            string outputFilePath = Application.persistentDataPath + "/Vuforia/" + filename;
            if (!Directory.Exists(Path.GetDirectoryName(outputFilePath)))
                Directory.CreateDirectory(Path.GetDirectoryName(outputFilePath));

            UnityWebRequest datasetFiles = UnityWebRequest.Get(uri);
            yield return datasetFiles.SendWebRequest();

            Save(datasetFiles, outputFilePath);
            yield return new WaitForEndOfFrame();
        }

        // When done extracting the datasets, Start Vuforia AR scene
        SceneManager.LoadScene("Vuforia-0-Splash");
    }

    private void Save(UnityWebRequest datasetFiles, string outputPath)
    {
        File.WriteAllBytes(outputPath, datasetFiles.downloadHandler.data);

        // Verify that the File has been actually stored
        if (File.Exists(outputPath))
        {
            Debug.Log("File successfully saved at: " + outputPath);
        }
        else
        {
            Debug.Log("Failure!! - File does not exist at: " + outputPath);
        }
    }
}