Search Unity

  1. We are migrating the Unity Forums to Unity Discussions. On July 12, the Unity Forums will become read-only. On July 15, Unity Discussions will become read-only until July 18, when the new design and the migrated forum contents will go live. Read our full announcement for more information and let us know if you have any questions.

Question How to make Vuforia with aab and split binary work?

Discussion in 'Android' started by MotionBrain, Apr 22, 2024.

  1. MotionBrain

    MotionBrain

    Joined:
    Dec 5, 2015
    Posts:
    36
    I'm experiencing a persistent issue where the Vuforia database is not recognized when I build my app as an Android App Bundle (AAB) with split binary options. However, when I build the project as an APK, everything functions correctly.

    Here's what I've explored so far:

    I understand that there are specific considerations with the StreamingAssets folder in AAB, such as potential delays in downloading contents. I attempted to package the Vuforia database using AssetBundles. Unfortunately, it seems that the .dat file cannot be included in an AssetBundle. For reference, the app does upload and I can open it. It is just Vuforia which doesnt work!

    I have a loading scene in Unity and my main Scene which gets loaded after

    Setup Details:

    Code (CSharp):
    1. Unity 2022.3.25f1
    2. Vuforia 10.22.5
    3. Build App Bundle (Google Play) [Check]
    4. Split Application Binary [Check]
    5.  
    6. Base Scene Size: ~50MB
    7. Main Scene Size: ~1.5GB
    8.  
    I've spent numerous hours over several nights trying to resolve this without success. Does anyone have suggestions on how to ensure the Vuforia database is properly recognized and loaded in an AAB format? Any insights or fixes would be greatly appreciated.

    Thank you, MotionBrain

    I tried this to delay the streaming asset folder.

    Code (CSharp):
    1.   IEnumerator Start()
    2.     {
    3.  
    4. #if UNITY_EDITOR
    5.         yield return null;
    6. #else
    7.             string[] assetPackNames = AndroidAssetPacks.GetCoreUnityAssetPackNames();
    8.             if (!AndroidAssetPacks.coreUnityAssetPacksDownloaded)
    9.             {
    10.                 yield return StartCoroutine(WaitForAssetPacksDownload(assetPackNames));
    11.             }
    12.             else{
    13.                 yield return StartCoroutine(CheckAssetPacksDownloaded(assetPackNames));
    14.             }
    15. #endif
    16.  
    17.     }
    18.  
    19.     IEnumerator WaitForAssetPacksDownload(string[] assetPackNames)
    20.     {
    21.         bool allDownloaded = false;
    22.         // App cannot load without UnityStreamingAssetsPack being downloaded first
    23.         while (!allDownloaded)
    24.         {
    25.             var operation = AndroidAssetPacks.GetAssetPackStateAsync(assetPackNames);
    26.             yield return operation; // Wait for the state check to complete
    27.             if (operation.isDone)
    28.             {
    29.                 allDownloaded = true;
    30.             }
    31.             if (!allDownloaded)
    32.             {
    33.                 // Wait before checking again to avoid spamming checks
    34.                 yield return new WaitForSeconds(3);
    35.             }
    36.         }
    37.         errorTtext.SetText("All asset packs downloaded.");
    38.  
    39.         AsyncOperation asyncOperation = SceneManager.LoadSceneAsync(1);
    40.         asyncOperation.allowSceneActivation = false;
    41.  
    42.         while (!asyncOperation.isDone)
    43.         {
    44.             float progress = asyncOperation.progress * 100;
    45.             loadingPercent.text = (int)progress + "%";
    46.  
    47.             if (asyncOperation.progress >= 0.90f)
    48.             {
    49.                 yield return new WaitForSeconds(5);
    50.                 asyncOperation.allowSceneActivation = true;
    51.             }
    52.  
    53.             yield return null;
    54.         }
    55.      
    56.     }
    Thank you,

    MotionBrain
     
    Last edited: Apr 22, 2024
  2. MotionBrain

    MotionBrain

    Joined:
    Dec 5, 2015
    Posts:
    36
  3. MotionBrain

    MotionBrain

    Joined:
    Dec 5, 2015
    Posts:
    36
    Found a Solution:

    Reverted to Vuforia 9.8.5.
    And used this code while loading my MainScene (the big scene)




    Code (CSharp):
    1.  
    2.  
    3.     private string datUrl = "url.dat";
    4.     private string xmlUrl = "url.xml";
    5.     private string datasetName = "datasetName";  
    6.     IEnumerator DownloadAndLoadDatasets()
    7.         {
    8.             // Download DAT file
    9.             UnityWebRequest datRequest = UnityWebRequest.Get(datUrl);
    10.             yield return datRequest.SendWebRequest();
    11.             if (datRequest.isNetworkError || datRequest.isHttpError)
    12.             {
    13.                 statusText.text += "Failed to download DAT file: " + datRequest.error;
    14.                 yield break;
    15.             }
    16.    
    17.             // Download XML file
    18.             UnityWebRequest xmlRequest = UnityWebRequest.Get(xmlUrl);
    19.             yield return xmlRequest.SendWebRequest();
    20.             if (xmlRequest.isNetworkError || xmlRequest.isHttpError)
    21.             {
    22.                 statusText.text += "Failed to download XML file: " + xmlRequest.error;
    23.                 yield break;
    24.             }
    25.    
    26.             // Save downloaded files
    27.             string datPath = Path.Combine(Application.persistentDataPath, datasetName + ".dat");
    28.             string xmlPath = Path.Combine(Application.persistentDataPath, datasetName + ".xml");
    29.             File.WriteAllBytes(datPath, datRequest.downloadHandler.data);
    30.             File.WriteAllBytes(xmlPath, xmlRequest.downloadHandler.data);
    31.    
    32.             // Load and activate dataset
    33.             LoadAndActivateDataset(datPath, xmlPath);
    34.         }
    35.    
    36.         void LoadAndActivateDataset(string datPath, string xmlPath)
    37.         {
    38.             ObjectTracker objectTracker = TrackerManager.Instance.GetTracker<ObjectTracker>();
    39.             DataSet dataSet = objectTracker?.CreateDataSet();
    40.          
    41.             if (dataSet != null /*&& dataSet.Load(xmlPath, VuforiaUnity.StorageType.STORAGE_ABSOLUTE)*/)
    42.             {
    43.                 objectTracker.Stop();
    44.                 objectTracker.ActivateDataSet(dataSet);
    45.                 objectTracker.Start();
    46.             }
    47.             else
    48.             {
    49.                 statusText.text += "Failed to load dataset.";
    50.             }
    51.         }
     
    AlanUnity likes this.
  4. AlanUnity

    AlanUnity

    Joined:
    Feb 18, 2018
    Posts:
    13
    Congrats on finding a solution, I am nearing the "closed testing" stage of my build, my app is not as big as yours, about 550Mb in total, the base scene is around 40MB and the rest makes up two scenes with Vuforia Image Targets. Are we required to add this code if we check "split application binary" and build an AAB? I'd hate to send my app to the testers, and it doesn't work right away :/