Search code examples
c#unity-game-engineassetsassetbundle

How to Download an AssetBundle and then save it in the device


I'm using the LoadFromCacheOrDownload function, I'm just not sure how can I just download the asset bundle from inside unity and then load the asset bundle for a local in the device. Thank you! Here's the code I'm currently using:

using UnityEngine.UI;
using System;


public class LoadScenes : MonoBehaviour
{
public string sceneAssetBundle;
public string sceneName;
public string sName;
public string bName;
public string BundleURL;
public int version;
public int downloaded = 0;


IEnumerator Start() {
    if (downloaded == 0){
        using (WWW www = WWW.LoadFromCacheOrDownload (BundleURL, version)) {
            yield return www;
            if (www.error != null)
                throw new Exception ("WWW download had an error:" + www.error);
            if (www.error == null) {
                AssetBundle bundle = www.assetBundle;
            }
        }
            if (Caching.ready == true) {
                downloaded = 1;
                yield return InitializeLevelAsync (sceneName, true);

            }
        }
    }


public void getScene(string sName){
    sceneName = sName;

}

public void getBundle(string bName){
    sceneAssetBundle = bName;

}


public IEnumerator InitializeLevelAsync (string levelName, bool isAdditive)
{
    // This is simply to get the elapsed time for this phase of AssetLoading.
    float startTime = Time.realtimeSinceStartup;

    // Load level from assetBundle.
    AssetBundleLoadOperation request = AssetBundleManager.LoadLevelAsync(sceneAssetBundle, levelName, isAdditive);
    if (request == null)
        yield break;
    yield return StartCoroutine(request);

    // Calculate and display the elapsed time.
    float elapsedTime = Time.realtimeSinceStartup - startTime;
    Debug.Log("Finished loading scene " + levelName + " in " + elapsedTime + " seconds" );
}
}

Solution

  • You should use PlayerPrefs to know when Asset is downloaded, Check if it has been downloaded before attempting to download it again. Here is an example

    if (PlayerPrefs.GetInt("AssetLoaded", 0) == 0)
    {
        //Save that we have down loaded Asset 
        PlayerPrefs.SetInt("AssetLoaded", 1);
        Debug.Log("Asset has NOT been downloaded. Downloading....");
    
        //DOWNLOAD ASSET HERE
        //.......
    }
    else
    {
        Debug.Log("Asset already loaded. Can't download it again!");
    }
    

    To incorporate this with the code in your question:

    IEnumerator Start() {
        if (PlayerPrefs.GetInt("AssetLoaded", 0) == 0){
            Debug.Log("Asset has NOT been downloaded. Downloading....");
            using (WWW www = WWW.LoadFromCacheOrDownload (BundleURL, version)) {
                yield return www;
                if (www.error != null)
                    throw new Exception ("WWW download had an error:" + www.error);
                if (www.error == null) {
                    AssetBundle bundle = www.assetBundle;
                }
            }
                if (Caching.ready == true) {
                    downloaded = 1;
                    //Save that we have down loaded Asset 
                    PlayerPrefs.SetInt("AssetLoaded", 1);
                    yield return InitializeLevelAsync (sceneName, true);
    
                }
            }else
              {
                 Debug.Log("Asset already loaded. Can't download it again! Loading it instead");
                 yield return InitializeLevelAsync (sceneName, true);
              }
        }
    

    To Reset it, simply call PlayerPrefs.DeleteKey("AssetLoaded");.