- Home /
Which way is better to handle AssetBundle management
Before going to ask the question, I will explain what kind of requirements I need. In my game, there are a lot of textures needed in order to play it. Because of this and the limitation of ipa size (iOS), I think using assetbundle is a must. Because the existing code implementation, I create the assetbundle, 1 asset bundle for 1 image. For example: I have 100 images, then I will create 100 assetbundle(with the mainasset will be the texture), with the same name.
I want my game can be played offline AFTER at first time the user has downloaded all the needed assetbundles. So if the user play for the first time or download the updated version of my game, the game will be forced into special scene where it will download all needed assetbundle, after that, the user can play the game without internet connection.
I thought there are 2 ways regarding of how to download these assetbundle:
The normal way: I put all 100 assetbundles in my server, and put 1 xml file, which consist all assetbundles information and its version. At the special scene, the game will download the xml file, and from that it will download 100 assetbundles via
WWW.LoadFromCacheOrDownload
. The purpose is just to store the needed assetbundles to the cache of game. After successfully downloaded all of them, user can play offline and if the game need the assetbundle to be loaded, then I just callagain theWWW.LoadFromCacheOrDownload
, since it is still in the cache, it can be played offline. Of course, I assume the cache is still there as long as I dont clear the cache explicitly.The hard way: I will zip all 100 assetbundle to 1 zip file. The game will download the xml file, and the zip file. I will decompress the zip, and put all 100 assetbundle in the mobile storage (iOS and Android). So after that, in case the game need to load the asset, I just call the
WWW.LoadFromCacheOrDownload
with the url is usingfile:///
scheme that point to the path of mobile storage.
Summary:
The Normal Way:
Minus: I assume the cache is still there, but if there is something wrong in the cache, the user can't play the game.
Plus: simple implementation, because the assumption that cache will be fine.
The Hard Way:
Minus: well, i don't know it is minus point or not, but this one, I have to implement the unarchived zip file and store them in storage. More implementation needed at server side and the application side. And since I am newbie, I don't know the best practice in this area.
Plus: more robust
So which one is better ? or any better recommendation?
The Hard Way: "A lot of code must be implemented to handle zip file download". It's a bytefile... like any other file... you download it...
The code you need is for extracting the zip file, not downloading it :)
If you can do your own download to local storage then couldn't you just download the image files directly (with a WWW instance, and WWW.texture) and then save the texture data to local storage? This way you wouldn't need to worry about asset bundles at all.
As far as I know, the maximum AssetBundle cache is 50 $$anonymous$$B for the system. And this is for all the Unity web application. So if you open the other app using that - it will then get overwritten. You need a special licence to extend and manage that. But I have noticed that both webplayer and assetbundle files get cached in the standard temporary Internet files folder on my computer.
@yoyo: yes i thought of that too. But in my game, the compression (RGB, PVRTC, et) setting between android and ios is different. So, i guess using assetbundle is more flexible.
@tomekkie: this game is for mobile (ios and android), and the limitation as far as i know is 4GB, which is very big enough to my need (need just 10-20 $$anonymous$$B)
@bangau1, if your compression settings are different per platform then you can download different versions of the images files. (You would need to download different asset bundles on each platform anyway, so not much difference.)
@tomekkie2, looks like the 50$$anonymous$$ limit is just on web player, limits are higher on standalone and mobile -- http://docs.unity3d.com/Documentation/$$anonymous$$anual/DownloadingAssetBundles.html (I didn't know that either).
Answer by whydoidoit · Aug 22, 2013 at 07:54 AM
Well there is another way! Create your asset bundles, download them and store them in local storage... Download the bundle, use www.bytes and System.IO.File.WriteAllBytes to write them to the persistent part of your app's install and then use AssetBundle.CreateFromMemory on the data in the file you wrote using System.IO.File.ReadAllBytes(fileName).
You'd probably be better off making one large AssetBundle with all of the files in it though...
I do not know, if it is true or not, but I guess using that way, there will be an effect in the memory footprint. I just need to load 1 image at one time, but if I load 1 large assetbundle, then it will consume too much memory. C$$anonymous$$IIW
The same would be true of holding a zip file in memory too (which is fundamentally what an asset bundle is).
In that case download and cache in local storage either the image files or the image file asset bundles.
Answer by henryfailbetter · May 06, 2014 at 05:24 PM
Dunno if you solved this, but our solution has a zip file embedded in a dll. I get the zip from the dll and extract the images using SharpZipLib. It works in Mac and Windows, which Ionic didn't)
public static void CopyFilesFromEmbeddedArchiveToFileSystem(string archivePath, string fileSystemPath)
{
var assembly = Assembly.GetCallingAssembly();
var archiveStream = assembly.GetManifestResourceStream(archivePath);
var zipFile = new ICSharpCode.SharpZipLib.Zip.ZipFile(archiveStream);
foreach (ICSharpCode.SharpZipLib.Zip.ZipEntry entry in zipFile)
{
if (entry.IsFile)
{
var stream = zipFile.GetInputStream(entry);
var path = String.Concat(fileSystemPath, entry.Name);
using (var fileStream = new FileStream(path, FileMode.Create))
{
stream.CopyStream(fileStream);
}
}
}
}