Caching WWW Assets - Primarily AssetBundles

Greetings all!

I would like to add a caching mechanism to my AssetBundle usage implementation to save bandwidth and improve user’s experiences.

From a webplayer perspective, things seem very confusing. Aside from the browser’s unrelible built in cache, there is a new WWW.LoadFromCacheOrDownload method that seems to require some kind of “Caching API” key in order to function.

This Unity Feedback topic lists “Some support for [caching] coming in Unity 2.6”, and this forum thread seems to indicate that caching is already fully functional, but requires a special license that is “nowhere near cheap”. I can understand that Unity might need to charge huge amounts of money for an incredibly advanced system of some sort or other, but caching webplayer assets is about as basic as I could imagine anything possibly being. All that needs to happen is for PlayerPrefs to support a new datatype that isn’t limited to 5 megs and that is pruned occasionally, and everything should be great! I would really appreciate it if Unify could clarify the current state of asset caching mechanism(s?) available for webplayer games.

My game is distributed as a native application as well as a webplayer - and since native applications have direct filesystem access, I would like to build my own caching system to function in native versions of my game. If anyone has already built a system like this or has any suggestions to offer, I would be most appreciative! Everything should be trivial to build, but I don’t know how or where application data should be stored on Windows systems, and I would like confirmation that I am storing files on user’s computers in the most optimal fashion.

Whose content gets flushed/pruned “occasionally”? How often is “occasionally”, is it more or less frequent than normal browser cache clearing? What about the one developer that wants to force 5MB in one shot flushing all your stuff if it’s based on “when full flush old stuff”? Does any of that make it less volatile a space than the browser’s cache? I say no it doesn’t as you still have no way of knowing whether your stuff is there or not, right? So from my POV it seems that your “all that’s needed” solution doesn’t actually solve the problem, it just pushes it elsewhere and with a lower space limit (only 5MB) than the typical browser cache offers (more than 5MB). Any real “solution” for this needs to involve non-volatile (meaning only the user can flush it, not other content) storage space and that makes the problem a bit more sticky.

For web player caching today there are two options:

  1. Use the browser’s cache, it’s there, it’s free, but it’s volatile and you won’t know from session to session whether your content is there or not.

  2. License the web player caching feature, but as you know it’s not on the inexpensive side. This is non-volatile, meaning only the user can flush your content unless you force a re-download, your bits are safe from other content.

The reason we don’t open that caching up to everyone is that we don’t want everyone storing lots of content on end user’s hard drives, and it’s pointless to have a shared volatile cache that’s smaller and/or less useful than the browser’s cache is already. I say that because storing lots of files without user awareness/control puts us in serious danger of being labeled a tech that fills drives with unwanted/unexpected material. Yes, there are ways to build in management systems, user controls and whatnot, and we may get there, but not in the 2.x family, we’ll have to see about 3.x and beyond. So for now this is something that’s going to come at a price, then longer term we can see how, if at all, we expose this in some way to general users (some sort of reasonably sized shared space? other?). We’re not there yet so you have to sit tight and wait for it. :slight_smile:

Thanks for your clarifications!

I don’t understand why the concept of caching assets is treated as so nontrivial - It sounds as simple as showing the user a “this Unity application would like to cache files” dialog, then storing that app’s www requests and PlayerPrefs “data” objects in a webplayer specific folder somewhere inside the user’s system application data folder. The www class could check for cached assets as necessary, and cached assets could be automatically deleted by Unity according to the user’s preferences.

Please don’t read the wrong tone into my words - I love Unity, just purchased Pro, could scarcely be more supportive of your technology (especially now that you have released Indy for free!), and don’t mind waiting patiently for new features such as a caching system for webplayer data. It is just that when I hear ideas that sound totally wrong to me - such as “charging devs (in this case, pricing folks like me out of the field) to protect users from cached data”, I want to make sure I can offer my suggestions on how various corporate decisions affect my perception of Unity’s image.

All the best,

-Aubrey

P.S. And now back to the most important aspect of this discussion, can anyone offer suggestions on creating a simple native app asset caching system?

A major focus for us is simplicity in the web player, so as I noted before it’s something we’re approaching with care. This is something that may very well happen as you’ve described, but as a young technology we’re taking our time and don’t want to put it in just yet, not until we’ve had plenty of time to sort it out. What’s there now was done on behalf of large clients, it’s simply going to take a bit more time to trickle down in the right way. :slight_smile:

I don’t know that you’ll be able to do so in the web player without licensing the caching feature we’ve been discussing. I say that because the Unity Web Player cannot access arbitrary files outside the browser cache so you’re kind of stuck in that particular sand box and as you know it’s a volatile storage that you cannot count on for persistence. Perhaps someone else has smarter ideas than me, lord knows I can be dense at times. :slight_smile:

Approaching with care is great! An elegant, Unity worthy system in the future is far more exciting than a hacked, backwards compatibility nightmare today.

Thanks for responding to my concerns. I am once again optimistic and eagerly anticipating Unity announcements :slight_smile:

I didn’t quite make myself clear enough on the P.S. element - by “native”, I meant non-webplayer. I will be content for now to rely on the browser’s volatile asset cache for my webplayer game distribution, but I would like suggestions for a simple custom caching system to be used by “native” builds of my game.

Hello,

HiggyB, have you considered using the System.IO.IsolatedStorage namespace? I’m sure you have, but just thought I’d mention it :-).

This provides the ability to store files locally in a manner which prevents an application from accessing any arbitrary location on the hard disk. It also provides the ability to use quotas on how much disk space the application is able to consume.

I believe this would provide an elegant solution for local file storage within Web Player builds.

Cheers

2 questions:

  1. When calling "new WWW ("http://myserver/myBundle.unity3d");", does it issue the GET request inside the running browser’s process(Firefox, Chrome) or is it always using IE(via .NET Framework or something)?

  2. If I understand correctly, this is like any other file the browser caches, and the browser will cache the .unity3d assetbundle file after the first download?

Thanks.

  1. likely neither but a simple TCP based HTTP request

  2. Right, the browser decides if it caches the file and for how long

In regards to both of your answers: if the Unity WWW class is utilizing System.Net.HttpWebRequest, I believe the cache used is the user’s IE cache. Thus, all cached assetbundle files go to the IE cache.

Unity guys, is this correct?

no it doesn’t it ends in the cache of the browser you use.

it has no browser dependence.

please remember, it exists on osx, windows and the iphone

also, this is mono, not .net, so independent of whatever it will never be ie related

I forgot to mention, the context is in a Unity WebPlayer.

Oops! Yes, it obviously has to be cross-platform because it’s Mono.net! I knew that, just had my head in Windows too much recently! :sweat_smile:

There’s mention of a browser cache in this thread. Where are the assetbundles cached then?

I now think they’re cached in the browser where UnityWebPlayer is running, because:

  1. after I load my webplayer once, and then remove the assetbundle from my webserver and load the html file again in my browser, the asset still gets instantiated.

  2. I just cleared my Firefox cache and reloaded my html and the asset is no longer instantiated.

Thanks for your help!

good good :slight_smile:

When used in the web player all WWW requests are handed off to the browser in which you’re content is being viewed.

Yes, this is a direct result of my answer to #1 above. All queries made via the WWW class are cached by the browser and later repeated calls to the same URL will retrieve the cached copy unless it’s been cleared. If you want to force a fresh download then you need to append some sort of custom and unique URL parameter (just to make sure the URL is different so the browser pulls it fresh).

…And because the broswer’s cache is involved, you should use cache-control headers to your advantage…