I’ve been trying to setup a AssetBundle Loader system for our project, but the documentation about this is confusing and I’m still not sure how or if I can setup the system the way I want to.
I want to store several prefabs in one AssetBundle each. So, AssetBundle X stores Prefab X.
I was able to get this to work in a simple sample script:
public class Loader : MonoBehaviour
{
private AssetBundleCreateRequest bundleRequest;
private UnityWebRequest request;
private bool loaded;
private void Start()
{
request = UnityWebRequest.GetAssetBundle(AppConfig.ASSETBUNDLE_URL + "myBundle/1");
request.SendWebRequest();
}
private void Update()
{
if (!request.isDone || loaded){
return;
}
var bundle = DownloadHandlerAssetBundle.GetContent(request);
var myGameObject = Instantiate(bundle.LoadAsset("MyPrefab")) as GameObject;
loaded = true;
}
}
However it worked only for one bundle and only If I specify the name of the prefab, in that scene. I wanted to load all the assetsBundles in a “loading” scene to then instantiate the prefabs in the next scene.
TLDR:
How do I save assetbundles for later use in the app
Since I posted this I finally understood what I was doing wrong. To make Unity cache asset bundles GetAssetBundle HAS TO have the version otherwise it will not cache it.
However, now I’m having a different issue related to the bundles. I created a coroutine to load one asset bundle and works fine. Then I called this coroutine for each bundlename in a list. When I do this only the first bundle works, when it tries to load the second one it keeps getting the reference to the first one.
private IEnumerator GetAssetBundleFromRemote(string bundleName)
{
var bundleUrl = Path.Combine(RemotePath, bundleName);
var webReq = UnityWebRequest.GetAssetBundle(bundleUrl, 1, 0);
var handler = webReq.downloadHandler as DownloadHandlerAssetBundle;
yield return webReq.Send();
if (webReq.responseCode == 0){
Debug.Log(bundleName + "__>" + "Loading from cache");
}else if (webReq.responseCode == 200){
Debug.Log(bundleName + "__>" + "Loading from server");
}
Debug.Log(bundleName + "__>" + "Analizing response");
var bundle = handler.assetBundle;
if (bundle == null){
Debug.Log(bundleName + "__>" + "No Bundle Found");
yield break;
}
Debug.Log(bundleName + "__>" + "Bundle Found");
Debug.Log(bundleName + "__>" + "Bundle Name: " + bundle.name);
foreach (var assetName in bundle.GetAllAssetNames()){
Debug.Log("Asset: " + assetName);
}
var prefab = bundle.LoadAsset<GameObject>(bundleName);
if (prefab != null){
Debug.Log(bundleName + "__>" + "Prefab Found");
Instantiate(prefab, transform, false);
}
bundle.Unload(false);
yield return new WaitForSeconds(3);
}
When it tries to load the second bundle this code:
foreach (var assetName in bundle.GetAllAssetNames()){
Debug.Log("Asset: " + assetName);
}
Could it be that for subsequent calls it loads the same bundle from cache?
Try using an overload that takes a cached bundle name and make sure that name is unique for each bundle:
i am using WWW for downloading assetbundle from google drive. not unitywebrequest . WWW is working fine for 1 asset bundle with size less then 100mb , but when it exceeds 100mb its giving downloading error. but when i divide 1 into 2 asset bundle to reduce size problem it download both but show error if i try to get 2nd asset bundle.
void Awake()
{
if (Application.isEditor && removeCache)
Caching.ClearCache();
StartCoroutine(GetAssetBundle());
}
IEnumerator GetAssetBundle()
{
www = new WWW[url.Length];
for (indexOfDownloadableFiles=0; indexOfDownloadableFiles < url.Length; indexOfDownloadableFiles++)
{
Debug.Log("Dowloading Started");
www[indexOfDownloadableFiles] = WWW.LoadFromCacheOrDownload(url[indexOfDownloadableFiles], version );
yield return www[indexOfDownloadableFiles];
if (www[indexOfDownloadableFiles].error != null)
{
//if error in downloading asset bundle show error popup
if (errorDownloadDb)
errorDownloadDb.SetActive(true);
yield break;
throw new Exception("WWW download had an error: " + www[indexOfDownloadableFiles].error);
}
AssetBundle assetBundle; assetBundle = www[indexOfDownloadableFiles].assetBundle;
if (!assetBundle && errorDownloadDb)
{
errorDownloadDb.SetActive(true);
yield break;
}
if (canLoadScene)
{
LoadSceneMethod(assetBundle);
}
else
{
if (prefabsName.Length > 0)
{
//instantiating prefabs
foreach (string prefabName in prefabsName)
{
Debug.Log("PrefebName" + prefabName);
AssetBundleRequest assetLoadRequest = assetBundle.LoadAssetAsync<GameObject>(prefabName);
GameObject AssetBundleObj = Instantiate(assetLoadRequest.asset) as GameObject;
AssetBundleObj.SetActive(true);
Debug.Log("AssetBundleObj: " + AssetBundleObj.name);
}
}
Debug.Log("BundleName: "+assetBundle.name);
assetBundle.Unload(false);
www[indexOfDownloadableFiles].Dispose();
Debug.Log( " Spawned");
}
}
if (showContinue && continueButtonSplash)
{
continueButtonSplash.SetActive(true);
}
if (loadingObjGameplay)
loadingObjGameplay.SetActive(false);
}