Because I can’t make them work. I’ve tried every tutorial, read everything, and still, once I build the application, it just doesn’t works, even when using the samples by Unity’s Asset Bundle Manager. I’m currently using a Mac and I don’t really know what else to do, because we need to reduce the application size.
I remember we talked about this here:
You’re saying it doesn’t reduce the size of the application…
When you build the application in the end, what scenes are you including? If you don’t exclude the scenes you wrapped up in an AssetBundle, they will still get compiled into the application.
Or if the the assets that are in the scenes that are included in the scenes that are compiled are also in the assets, they will still get included.
How are you loading the asset bundles?
How did you go about accomplishing this???
This is the entire code I use for loading scenes from asset bundles. The only scene I include is a scene with a few buttons, which works exactly like a menu. The other scripts are from unity’s Asset Bundle Manager. Whenever I build the application, it just doesn’t works, it works perfectly in the editor, but once I build it. It’s kinda frustrating, sorry if I sound rude in any of the posts. :~
using UnityEngine;
using System.Collections;
using AssetBundles;
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 (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) {
PlayerPrefs.SetInt("AssetLoaded", 1);
yield return InitializeLevelAsync (sceneName, true);
}
}else
{
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)
{
Debug.Log (PlayerPrefs.GetInt ("AssetLoaded", 0));
// 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" );
}
}
Use Code Tags:
Sorry, my bad, edited it.
-
Why are those ‘get’ methods called ‘get’ when they obvsly ‘set’…
-
This:
yield return InitializeLevelAsync (sceneName, true);
Does not run InitializeLevelAsync, you need to yield a coroutine to process that…
- Where as here:
yield return StartCoroutine(request);
You called StartCoroutine on a YieldInstruction??? You have these backwards.
Also, where are these getting downloaded from? I see BundleURL, but I don’t know what that is, is that address a valid address in the built version. If it’s a relative address, it may or may not exist.
Well, I’m not actually using Getters and Setters, it’s merely the name of the method, and this part works ok, it’s just the method for me to get the bundle name and the scene name from the buttons I press. The URL is set by the buttons also, but all of them are local files, just for testing purposes. As for the other things, I’ll correct them right now and see how they work. Thank you for your answer!
EDIT: I’ve made those changes, I’ll just post the methods:
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) {
PlayerPrefs.SetInt("AssetLoaded", 1);
yield return StartCoroutine(InitializeLevelAsync (sceneName, true));
}
}else
{
yield return InitializeLevelAsync (sceneName, true);
}
}
and another one:
public IEnumerator InitializeLevelAsync (string levelName, bool isAdditive)
{
Debug.Log (PlayerPrefs.GetInt ("AssetLoaded", 0));
// 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;
StartCoroutine(request);
// Calculate and display the elapsed time.
float elapsedTime = Time.realtimeSinceStartup - startTime;
Debug.Log("Finished loading scene " + levelName + " in " + elapsedTime + " seconds" );
}
}
And it still doesn’t works. I’m sorry, I’m not really an expert at Unity, I’ve been working with only UI and 3D scripting, so it’s been a really big change for me. :~
As for all that, how does it not work?
Did the file size of the main application actually get smaller?
Are the assets just not loading?
Also… what is AssetBundleManager? I don’t know this class, is this 3rd party, or is it new to Unity (I may be a couple versions behind).
I merely pointed that one out because bad naming conventions are often a sign of poor design… or worse a copy and pasting of tutorial code and a lack of understanding of the entire code base in general.
You should name things clearly as to what they’re intended to do. Those functions don’t get anything, they set things.
AssetBundleManager is downloadable from Unity’s website, here in this link. I don’t really think the issue should be their code, since it’s “official”, but who knows?
Well, once I hit build, the buttons show up. Like this:
(Cena1, Cena2, Cena3 all translate to scene1, scene2 and scene3 respectively)
Once I click the buttons, nothing happens. But once I’m inside the editor, the scenes load perfectly.
A couple things jump out immediately
- You’re checking Caching.ready after you’ve potentially already attempted to download something from the cache.
- You don’t need to wrap WWW in using. It’s not a stream per se and will dispose of itself automatically (the Dispose method is really meant to cancel in-progress WWW requests).
The combination of those things, at first blush, could be causing the WWW object to be disposed of without loading anything.
Turn on Development Build and Debug and then check the output log text file in your built client’s directory afterwards to see what error messages are appearing.
Well, the console points out to this error: NullReferenceException: Object reference not set to an instance of an object and then it points out to two different lines of the scripts I currently have:
string[] bundlesWithVariant = m_AssetBundleManifest.GetAllAssetBundlesWithVariant();
This one is the weirdest one, since I don’t even use any variants in my current code. I’m just loading scenes. And it points out to the AssetBundleManager script.
And then, this one, in my LoadScenes script, which is nothing more than a script that comes with the example scene that can be downloaded from Unity’s website.
AssetBundleLoadOperation request = AssetBundleManager.LoadLevelAsync(sceneAssetBundle, levelName, isAdditive);
I’m sorry, I didn’t really understood these. As I said before, I’m pretty much a beginner at Unity, I was used to work with UI and 3D scripting, so for me, these terms are kinda confusing. Could you please explain it a little more? Sorry for my inexperience, also. :~
Um, I’m not sure how else to really explain it. You check Caching.ready after you do WWW.LoadFromCacheOrDownload so there’s the potential that the cache is not ready and you’re trying to get something from it. Secondly, you do something like
using (WWW www = WWW.Load(...))
which you don’t have to do. using is meant as a helper to automatically close and dispose of streams and WWW is not a stream.
Again, best bet is to turn on debug and look in your output log for errors.
Made every change possible, tried new ways, and still, when I build it, it doesn’t loads. My co-worker can’t make them work either, maybe it’s best just to give up on Asset Bundles. I read every tutorial there is on this matter, and still, nothing. We’ve been trying for 3 weeks but we’re not really experienced, so, maybe it’s best to just leave it alone. But thanks for everyone’s replies.
what was the outcome? Issue resolved?
I’m going through a similar issue right now, with a WebGL build… I’ll try to save the assets as public properties within the scripts themselves… … we’ll see how I go, but if you ended up finding a solution, would appreciate if you can share