Search code examples
unity-game-enginevuforia

Can't load data-set from obb in Vuforia 7.04 v


I am working in unity 2017.03 with Vuforia 7.04 V.

My problem is my apk size 120mb+ so I had to try to split the binary and upload it to the google play store.

Before splitting the application was working perfectly, but after splitting it's not working except the AR scenes are all working fine.

On testing consol in mobile I get this error :

fail to load dataset /storage/emulated0/Android/data/com.xyz.game/files/QCAR/dbname.xml

after google search I got this code

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

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

        var www = new WWW(uri);
        yield return www;

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

    // When done extracting the datasets, Start Vuforia AR scene
    SceneManager.LoadScene("Home"); 

}

private void Save(WWW www, string outputPath) {
    File.WriteAllBytes(outputPath,www.bytes);

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

But no luck, still get the same error same.

Someone help me, please!

I am using this as reference


Solution

  • After a long search and much debugging, I have found a way to resolve this. Here is code and steps to solve this problem:

    public class ARFix : MonoBehaviour {
    private string nextScene = "QRScaner";
    
    private bool obbisok = false;
    private bool loading = false;
    private bool replacefiles = false; //true if you wish to over copy each time
    
    private string[] paths ={
        "Vuforia/FriendsJungle_DB.dat",
        "Vuforia/FriendsJungle_DB.xml",
    };
    
    void Update()
    {
        if (Application.platform == RuntimePlatform.Android)
        {
            if (Application.dataPath.Contains(".obb") && !obbisok)
            {
                StartCoroutine(CheckSetUp());
                obbisok = true;
            }
        }
        else
        {
            if (!loading)
            {
                StartApp();
            }
        }
    }
    
    
    public void StartApp()
    {
        loading = true;
        SceneManager.LoadScene(nextScene);
    }
    
    public IEnumerator CheckSetUp()
    {
        //Check and install!
        for (int i = 0; i < paths.Length; ++i)
        {
            yield return StartCoroutine(PullStreamingAssetFromObb(paths[i]));
        }
        yield return new WaitForSeconds(3f);
        StartApp();
    }
    
    //Alternatively with movie files these could be extracted on demand and destroyed or written over
    //saving device storage space, but creating a small wait time.
    public IEnumerator PullStreamingAssetFromObb(string sapath)
    {
        if (!File.Exists(Application.persistentDataPath + sapath) || replacefiles)
        {
            WWW unpackerWWW = new WWW(Application.streamingAssetsPath + "/" + sapath);
            while (!unpackerWWW.isDone)
            {
                yield return null;
            }
            if (!string.IsNullOrEmpty(unpackerWWW.error))
            {
                Debug.Log("Error unpacking:" + unpackerWWW.error + " path: " + unpackerWWW.url);
    
                yield break; //skip it
            }
            else
            {
                Debug.Log("Extracting " + sapath + " to Persistant Data");
    
                if (!Directory.Exists(Path.GetDirectoryName(Application.persistentDataPath + "/" + sapath)))
                {
                    Directory.CreateDirectory(Path.GetDirectoryName(Application.persistentDataPath + "/" + sapath));
                }
                File.WriteAllBytes(Application.persistentDataPath + "/" + sapath, unpackerWWW.bytes);
                //could add to some kind of uninstall list?
            }
        }
        yield return 0;
    }}
    

    Steps:

    1. Create one empty scene and add this script in empty object.
    2. Save that scene and load before all scene.
    3. Don't forget to change next scene name and database name.