Hello, I’m to make the app I’m making download an asset bundle if it’s the first time, but save said bundle to disk,so it can check if it has already been downloaded and load it next time.
I’ve been looking forever, the only thing i could find was to save the downloadHandler.data to disk, like this,
byte[] bytes = req.downloadHandler.data;
File.WriteAllBytes(pathToSaveTo, bytes);
But Unity gives an error that you can’t access an asset bundler’s data directly?? I even tried generating a new byte array and copying the bytes over to no avail lol.
I’ve saved data from regular downloadHandlers just fine, I even have images saving to .png in the same game, but for some reason it doesn’t let you access the asset bundles download handler… I also looked up caching but i can’t really figure it out, nor do i really know if putting some 300mb of asset bundles in cache is really the best solution, as this will be on Amazon Firestick.
Here’s my script,
using System.IO;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using TMPro;
public class BookDownloader : MonoBehaviour
{
string assetName, uRL, pathToSaveTo;
UnityWebRequest r;
void Start()
{
pathToSaveTo = Application.persistentDataPath + "/Books/";
BookConfig config = GlobalValues.currentSelectedBookConfig;
GetBookFromBundle(config.assetBundleUrl, config.bookName);
}
public void GetBookFromBundle(string uRL, string assetName)
{
this.uRL = uRL;
this.assetName = assetName;
string fileName = pathToSaveTo + assetName;
if (!File.Exists(pathToSaveTo + assetName))
{
StartCoroutine(DownloadBookFromURL());
}
else
{
LoadManager.lm.SetLoadBarGoal(1);
AssetBundleCreateRequest bundle = AssetBundle.LoadFromFileAsync(pathToSaveTo + assetName);
GameObject book = bundle.assetBundle.LoadAsset<GameObject>(assetName);
GlobalValues.currentBook = book;
GlobalValues.currentBook.GetComponent<Book>().bookConfig.pagesText = GlobalValues.currentSelectedBookConfig.pagesText;
StartCoroutine(DelayToStart());
}
}
IEnumerator DownloadBookFromURL()
{
r = UnityWebRequest.Get(uRL);
StartCoroutine(GetDownloadProgress());
yield return r.SendWebRequest();
if (r.result == UnityWebRequest.Result.ConnectionError || r.result == UnityWebRequest.Result.DataProcessingError || r.result == UnityWebRequest.Result.ProtocolError)
{
StartCoroutine(DownloadBookFromURL());
yield break;
}
if (!Directory.Exists(pathToSaveTo))
{
Directory.CreateDirectory(pathToSaveTo);
}
byte[] bytes = r.downloadHandler.data;
File.WriteAllBytes(pathToSaveTo + assetName, bytes);
AssetBundle bundle = AssetBundle.LoadFromFile(pathToSaveTo + assetName);
Instantiate(bundle.LoadAsset<GameObject>(assetName));
GameObject book = bundle.LoadAsset<GameObject>(assetName);
GlobalValues.currentBook = book;
GlobalValues.currentBook.GetComponent<Book>().bookConfig.pagesText = GlobalValues.currentSelectedBookConfig.pagesText;
bundle.Unload(false);
LoadManager.lm.downloadsFinished = true;
}
IEnumerator DelayToStart()
{
yield return new WaitForSeconds(3);
LoadManager.lm.downloadsFinished = true;
}
IEnumerator GetDownloadProgress()
{
while (!r.isDone)
{
LoadManager.lm.SetLoadBarGoal(r.downloadProgress);
yield return null;
}
}
}
Thanks
Edit: I’ve figured a work around, it seems kinda a band-aid fix but it works lol, but I’m using a regular UnityWebRequest, saving it to disk, then loading it from the disk.I’ve updated my script if anyone needs it. So weird that Unity doesn’t make it easy to access an asset bundle download handlers data, it doesn’t even allow reading the data!?