Asset Bundle loading

hello everybody!

i managed to get asset bundle streaming to work, now i still learning to use them. i need some help though. i was wondering, is there a way to get a part of the asset bundle, not just mainAsset, and what if i dont know the names, can i loop through the objects in asset bundle and get all of these informations…example would be great if it is possible. thanks.

here is the function that i use to load the bundles.

function StartDownload(url:String,download : WWW,instanced : Object){

			// INDEXOF METHOD RETURNS THE POSITION IN THE STRING OF THE SEARCH SUBSTRING
			if (url.IndexOf ("file://") == 0 || url.IndexOf ("http://") == 0)
				//IF THE FILE:// OR HTTP:// ARE IN THE BEGINNING OF THE URL PROCEED TO DOWNLOAD
				download = new WWW (url);
			if (Application.platform == RuntimePlatform.OSXWebPlayer || Application.platform == RuntimePlatform.WindowsWebPlayer)
				//IF WE ARE EXECUTING IN THE PLAYER
				download = new WWW (url);
			else if (Application.platform == RuntimePlatform.OSXEditor || Application.platform == RuntimePlatform.WindowsEditor)
				//IF WE ARE EXECUTING LOCALLY
				download = new WWW ("file://" + Application.dataPath + "/Bundles/" + url);
			
			//PLACE HERE THE PROGRESS CODE (progress variable has to be global and private
			if(download.error==null){
				//	progressString=parseInt(download.progress*100).ToString();
					//Debug.Log(download.progress);
			} else {
					Debug.Log(download.error);
			}
					
			//progressString=parseInt(download.progress*100).ToString();
			
			//WAIT FOR IT TO FINISH
			yield download;			
			
			//ASSIGN ASSETBUNDLE FROM DOWNLOAD TO ASSETBUNDLE OBJECT
			assetBundle = download.assetBundle;
			
			//WE CAN NOW RELEASE DOWNLOAD BY
			download.Dispose();
			download=null;
			//SO THAT WE CAN USE IT LATER ON THE NEXT OBJECT
	
			//IF ASSETBUNDLE ISNT NULL
			if (assetBundle != null)
			{
				
				// Alternatively you can also load an asset by name (assetBundle.Load("my asset name"))
				var go : Object = assetBundle.mainAsset;
				
				//IF  EVERYTHING IS OK
				if (go != null)
					//INSTANTIATE THE ASSET BUNDLE
					instanced = Instantiate(go);
				else
					Debug.Log("Couldnt load resource");	
			}
			else
			{
				Debug.Log("Couldnt load resource");	
			}
			
		
}

nobody? any ideas?

also there i noticed that this isnt streaming though, everything freezes when downloading data…where is a mistake? can somebody help me?

On download it likely does not freeze but the instantiate does when all the mesh and texture data are sent to graphic card. even worse if you have / apply mesh colliders, thats a long time eater.

I don’t know if this will be of any help, but on a recent project for a client, I found loading and using AssetBundles to be so slow that I ended up using WWW instead, which was much, much faster. I was using only textures and audio in this fashion, however, and it wouldn’t work for all assets – but in both cases, the remote assets were in the same Amazon S3 bucket deployed through the same CDN edges and cached locally in the app in the same way (downloaded once and written to the same local data location for subsequent offline access). The AssetBundle file size was slightly but not significantly larger than the individual assets loaded through WWW, and I tried breaking the AssetBundle into separate bundles instead of using one large one as well (which was an improvement but still too sluggish).

This experience may not be common, but seems worth sharing. Dreamora or someone else with more knowledge of Unity’s inner workings than me may be able to suggest why.

Cheers,
psn

one thing is bothering me, if somebody can clear that, is it possible to get one object from asset bundle in such a way that you don’t have to wait the whole bundle to be downloaded, just to peek inside and get what you want…? my game should heavily rely on that so that is a must, i have bundles over 10Mb so i have to start showing objects from the bundle as soon as i can, not to wait whole thing to download…

asset bundles can only be loaded as whole.
Before the download has finished its not even an asset bundle.

if you want to access stuff more selectively, you must bundle it accordingly (and can, thats why you decide what goes into it)

that is sad…because i have around 500 objects in a bundle, i first wanted to make 500 separated bundles, and t o try to load them one by one, and show them as soon as they are downloaded but i get problem with size. for example a prefab has 8Kb (a small object) and when i make asset bundle from just that prefab (no textures) i get 3.3Mb in size!? so 3.3 x 500 objects = a lot… complete asset bundle made from prefab that has all 500 objects is around 7Mb…so what is going on…?

i know that 7Mb is not that much, but still, i am surprised that there is no method to get fairly small 3d objects (from 10-100Kb) into play. i what streaming is then? and how to use it…

a prefab is hardly never 8kb
don’t forget, a prefab hosts relations to assets which are not stored in the prefab itself.

so ontop of your 8kb you forgot to calculate in textures and models which easily host mbs as those 3.3mb you got

as such it will differ from prefab to prefab dependent on what you used.

So if I had 3 prefabs that shared the same texture file and made 3 asset bundles.

The image file for each prefab would be stored in each asset bundle.

Probably a good idea to bundle things together that share images.

Thats exactly the behavior you would see, right.
Assuming you create bundles with dependencies.
If you know that the original bundle will definitely be loaded you can omit that and just rely on the one there if loaded.

Optimally you normally bundle stuff that will appear together anyway, as you know that you will require all of them, so loading them one by one will only cost you time and reduce the bandwidth potentially (the only reason to do it is to benefit from browser caching if they would get too large when bundled)

here is the update…i think i will have to kiss goodbye the idea that i will have loading and displaying of objects one by one…

i fixed the code to see how LoadAsync works
at first i noticed that it seems better, no glitches but when i added colliders to all the objects and tried again, there was a big halt…that is the problem.

can i add colliders to the objects in the bundle in runtime? is it going to be faster and without halt?

here is the code (i used this link as reference):
http://forum.unity3d.com/viewtopic.php?t=45295&postdays=0&postorder=asc&start=0

function LoadResource(BundleLocation : String,AssetName : String,UpdateCounter : boolean)
{
	
			var www : WWW;
	
			if (BundleLocation.IndexOf ("file://") == 0 || BundleLocation.IndexOf ("http://") == 0)
				 www = new WWW(BundleLocation);
			if (Application.platform == RuntimePlatform.OSXWebPlayer || Application.platform == RuntimePlatform.WindowsWebPlayer)
				 www = new WWW(BundleLocation);
			else if (Application.platform == RuntimePlatform.OSXEditor || Application.platform == RuntimePlatform.WindowsEditor)
				 www = new WWW("file://" + Application.dataPath + "/Bundles/" + BundleLocation);


	Debug.Log("file://" + Application.dataPath + "/Bundles/" + BundleLocation);
	//WWW www=new WWW(BundleLocation);
	
	var LastProgress : int=0;
	
	while(![url]www.isDone[/url])
	{
		if(UpdateCounter)
		{
			CurrentLoadingSize-=LastProgress;
			LastProgress=www.size*[url]www.progress;[/url]
			CurrentLoadingSize+=LastProgress;
			Debug.Log(CurrentLoadingSize);
		}
		
			yield www;
			
			if(LoadAsync)
				StartCoroutine(LoadFromBundleAsync([url]www.assetBundle,AssetName[/url]));
			
	}

		
		www.Dispose();

}

function LoadFromBundleAsync(Bundle : AssetBundle,AssetName : String)
{

	var ABR : AssetBundleRequest=Bundle.LoadAsync(AssetName,Object);
	
	while(!ABR.isDone)
	{
			yield ABR;
			
			Instantiate(ABR.asset);
			Bundle.Unload(false);
	}
	
}