- Home /
Lag when Instantiating a loaded AssetBundle
Hi!
I have a 3D model I've made into an AssetBundle. I load the AssetBundle using yield etc. on my iPhone and it works great, no lag. It does it in the background.
But when I Instantiate the actual model after loading it, it lags for 1+ sec when adding it to the scene. I call the Instantiate in a StartCoroutine() function, so it should be doing it in its own thread.
Is there any way to make it instantiate it without any lag?
The 3D model has 150 animations, but I can't have all of those loaded at once because of memory issues, so what I've done is packaged each FBX animation into its own AssetBundle, so I'm trying to load an animation when needed at runtime and play it, without any noticeable lag.
Thanks!
StartCoroutine is not a different thread.
It enables you to tell computer to hold the execution of whatever comes after a yield for a while/until the yield function returns/for 1 frame/. While this holds the main thread continues as if the coroutine was over.
On the other hand, the Asset Bundle loading is done in a different thread, and that's why you don't have lag.
It could be that the instantiation takes a while.
Could you post the code snippet?
Thanks for the reply! Here's the code I currently use, loading assetBundle:
StartCoroutine(WwwLoad());
IEnumerator WwwLoad()
{
download = new WWW(thePath);
download.threadPriority = ThreadPriority.Low;
yield return download;
}
In Update(), when WWW.isDone is true I do:
GameObject.Instantiate(theWww.assetBundle.mainAsset);
I'm also trying Dreamora's suggestion of ins$$anonymous$$d of using mainAsset using LoadAsync:
assetBundleRequest = theWww.assetBundle.LoadAsync("TheName", typeof(GameObject));
Then in Update(), when assetBundleRequest.isDone is true, assetBundleRequest.asset contains the GameObject correctly, but it is not added to the scene (the hierarchy), so I have to do this to see it (which introduces the lag again):
GameObject.Instantiate(assetBundleRequest.asset);
Answer by Arnleif · Oct 09, 2013 at 07:53 AM
Using the bundle.mainAsset the first time is like doing a bundle.Load(..) and it is not async. In my case we use WWW.LoadFromCacheOrDownload and then the first call to bundle.mainAsset takes 0.076 sec and allocates ~8MB of memory. This is the whole bundle, unpacked. What I then have is the prefab as it was packed in my bundle. I can now Instantiate it to get it into the scene. If you use bundle.LoadAsync(..) you can remove the fps drop of the loading (Just don't use the mainasset.name to find the name! ).
When it come to the Instantiate, it might be more complicated depending on how complicated your prefab is, I assume. How much code it runs in awake etc. It might also help to think about what other things happens the same frame. Maybe add a yield return null; before and after doing the Instantiate. If you do a lot of Instantiate then try spreading them over several frames as well.
Answer by Dreamora · Jul 13, 2011 at 08:14 PM
A short lag will always be there, thats caused by the texture upload when the object first shows in front of the camera. Using smaller textures, compressed textures and alike helps seriously on that end.
also, you can load data asyncronously from asset bundles if you use the corresponding load function instead of Instantiate with the mainAsset
Thanks for the reply! I tried to use "assetBundle.LoadAsync()" now ins$$anonymous$$d of "Instantiate(assetBundle.mainAsset)" and it looks like it works a lot better (not as much lag), but when LoadAsync's returned assetBundleRequest.isDone is true, the assetBundleRequest.asset is correctly loaded as a GameObject, but it has not been added to the scene (the Hierarchy), so I can't see it.
It seems like I still have to use "Instantiate(assetBundleRequest.asset)" on that to get it added to the scene, which introduces the lag again... Do you know if "LoadAsync" should add it to the scene as well, or do I need to do something else with it to get it added? Thanks!
@T$$anonymous$$$$anonymous$$, did you resolve this one? I'm wondering why Instantiate is needed after LoadAsync. In this case what does LoadAsync do? Is instantiating after the async load much faster than simply instantiating from the start?
@andym, unfortunately I didn't find any solution to it... It seems like you have to use Instantiate no matter what kind of Load function you use.
I don't know why though, most likely the Load functions just load it into Unity as a resource, then Instantiate adds it into the scene.
Your answer
Follow this Question
Related Questions
Unloading asset bundles doesn't clear memory on iOS 1 Answer
Removing instantiated objects?? 1 Answer
Checking if object intersects? 1 Answer
Missing Material in AssetBundle Prefab 3 Answers
Memory Locking While Loading Issue 0 Answers