- Home /
Using as AssetBundle to replace first scene
Hello Unity Community!
Once again I am here for help.
After many failed attempts and research I come to you for an answer. Unfortunately, I have a legacy app developed in Unity3. (My clients dont want to upgrade to unity4 b/c it would take up too much of their resources) My game is over 50mb so I have to split the apk which I can successfully do. I'm not exactly sure what my problem is. But after I download the obb file my game runs fine. My problem occurs when I close the app and re-open it. I should note that I have a downloader scene which downloads all the other scenes as one assetbundle. So when I open the game for a second time, I try to skip the downloader scene. (Look at my Awake() method). But nothing happens, the game just sits still. So, I downloaded a logger app and I found out that I get this message: "sceneName (-1) has not been added to the build settings".
Can I edit the build settings during runtime, so I can make the first scene the menu scene and skip the downloader scene completely? And not in the editor in the actual app/apk/ipa? If so how can I achieve this?
Or
Am I not saving my assetbundle correctly? Thus causing a error b/c there is no menu scene b/c I didn't save it correclty.
I'm not exactly sure where I am going wrong here so any help would be appreciated!
Thank you!
using UnityEngine;
using System.Collections;
using System.IO;
using System;
public class DownloadObbExample : MonoBehaviour {
public string menuScene = "PrimaryMenu"; //TODO I MUST BE CHANGED BEFORE THE BUILD!!!!!!!
public int versionNumber = 0;
public GameObject ElementaryShell;
public GameObject PrimaryShell;
public GameObject ElementaryDownloadBtn;
public GameObject PrimaryDownloadBtn;
public SpriteText progressText;
private string expPath;
private string logtxt;
private bool alreadyLogged = false;
private bool downloadStarted;
private float progress;
void Awake() {
#if UNITY_ANDROID
Debug.Log("AWAKE I AM AWAKE DESTORYING SOME SHIT BEBFORE THE START ! <3 - ETB");
if(menuScene == "PrimaryMenu") DestroyImmediate(ElementaryShell);
else if (menuScene == "ElementaryMenu") DestroyImmediate(PrimaryShell);
if(PlayerPrefs.GetInt("wasDownloaded", 0) == 0) {
//download the obb file
StartDownload();
//and re-write 0 with 1 - do that at application.loadlevel - if we got that far for sure we downloaded the obb
} else {
Application.LoadLevel(menuScene);
}
#elif UNITY_IPHONE || UNITY_EDITOR
//we should never get here b/c this scene is only built when making a split apk - but just incase lets handle it
Application.LoadLevel(menuScene);
#endif
}
public void StartDownload() {
#if UNITY_ANDROID
if (!GooglePlayDownloader.RunningOnAndroid()) {
Debug.LogError("Use GooglePlayDownloader only on Android device!");
return;
}
expPath = GooglePlayDownloader.GetExpansionFilePath();
if (expPath == null) Debug.LogError("External storage is not available! ");
else {
string mainPath = GooglePlayDownloader.GetMainOBBPath(expPath);
string patchPath = GooglePlayDownloader.GetPatchOBBPath(expPath);
if(alreadyLogged == false) {
alreadyLogged = true;
if (mainPath != null) { Debug.Log("Attempted load level from !alreadyLogged statement"); StartCoroutine(loadLevel()); }
}
if (mainPath == null) {
//error obtaining path
allowForceDownload();
}
}
#endif
}
private void allowForceDownload() {
if(menuScene == "PrimaryMenu") PrimaryDownloadBtn.SetActiveRecursively(true);
else if (menuScene == "ElementaryMenu") ElementaryDownloadBtn.SetActiveRecursively(true);
}
private void forceDownlad() {
StartCoroutine(loadLevel());
}
protected IEnumerator loadLevel() {
#if UNITY_ANDROID
while(!Caching.ready) {
Debug.Log("caching not ready... waitting");
yield return null;
}
string mainPath;
do {
Debug.Log("fetching main path... waitting");
yield return new WaitForSeconds(0.5f);
mainPath = GooglePlayDownloader.GetMainOBBPath(expPath);
} while(mainPath == null);
string uri = "file://" + mainPath;
using(WWW www = WWW.LoadFromCacheOrDownload(uri, versionNumber)) {
while(!www.isDone ) {
progressText.Text = "0% Complete";
progress = (www.progress*100);
progress = Mathf.RoundToInt(progress);
progressText.Text = progress + "% Complete";
yield return null;
}
yield return www;
if (www.error != null) throw new Exception("WWW download had an error:" + www.error);
AssetBundle bundle = www.assetBundle;
bundle.LoadAll();
PlayerPrefs.SetInt("wasDownloaded", 1);
Debug.Log("About to load the main menu");
Application.LoadLevel(menuScene);
}
// OLD METHOD OF DOWNLOADING
// if(downloadStarted == false) {
// downloadStarted = true;
// WWW www = WWW.LoadFromCacheOrDownload(uri , 0);
// while(!www.isDone ) {
// progressText.Text = "0% Complete";
// progress = (www.progress*100);
// progress = Mathf.RoundToInt(progress);
// progressText.Text = progress + "% Complete";
// yield return null;
// }
//
// if (www.error != null) { Debug.LogError("Error dowloading: " + www.error); allowForceDownload(); }
// else {
// AssetBundle bundle = www.assetBundle;
// if(bundle == null) Debug.LogError(" Asset Bundle is null ");
// else {
// bundle.LoadAll();
// PlayerPrefs.SetInt("wasDownloaded", 1);
// Application.LoadLevel(menuScene);
// }
// }
// }
#endif
yield return 0;
}
}
So after further research I found this unity answer page: http://answers.unity3d.com/questions/382154/problem-in-loading-scene-from-asset-bundle.html
So if I understand this correctly, every time I have to either download the obb and load the assetbundle(if first open) or re-load the asset bundle from the cache(if second+ open)?
So I cannot install the asset bundle and have it become part of the apk? As opposed to re-loading the asset bundle every start up?
Answer by dorpeleg · Aug 25, 2013 at 07:13 AM
(I did not read your code, sorry)
Asset bundles have to be loaded.
The first time you try to load them, they will be downloaded (internet required).
Once they are downloaded, they are saved to cache (local file).
But in order to load them, you still have to use LoadFromCacheOrDownload, because that's the only way (that I know of) to load from the cache.
So if you are skipping the loading scene, your project is trying to open a scene that is not loaded.
That is why you are getting the "add to build settings" message.
There is no way to add a scene to the build settings at run-time.
that's what I thought, it looks like floky's ABT is my only solution... I will now explore the following:
http://forum.unity3d.com/threads/129042-Android-Builder-Tool?p=871925#post871925
Answer by ChenMo2 · Dec 26, 2013 at 01:48 AM
You can load your scene asset bundles at run time, then you can load your new scene as if it has been added into building settings.