Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

Danger: AssetBundle.LoadAllAssets<T>() loads everything.

Discussion in 'Asset Bundles' started by LightStriker, Sep 9, 2019.

  1. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,598
    I should have seen it coming, as Resources has the same issue.

    To be able to figure out the type of an Asset, Unity loads it. It's dumb. That's what headers are for (or manifests), but clearly not in this case.

    So if you have an AssetBundle comprising many assets of many types, trying to retrieve only a specific type will make Unity load everything. The solution is to have AssetBundle "per-type" instead.
     
  2. Ryanc_unity

    Ryanc_unity

    Unity Technologies

    Joined:
    Jul 22, 2015
    Posts:
    284
    Actual behavior depends on the type of T passed in. If it's a scripting type such as a MonoBehavior or ScriptableObject, it requires loading of that object to know it's specific scripting type. If it's a native type such as Texture2D, it can determine the type without loading the object and thus will not load it if it is not that type or does not derive from that type.
     
    Last edited: Sep 10, 2019
  3. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,598
    Honestly, that should be a bold red warning in the documentation. Having a 250Mb+ AssetBundle and finding out it just loads everything is not a pleasant surprise ;)

    Honestly, I keep saying it, but there should be more data in the headers, such as typing.
     
  4. Ryanc_unity

    Ryanc_unity

    Unity Technologies

    Joined:
    Jul 22, 2015
    Posts:
    284
    Type information is already contained in the headers. The exception is scripting types due to how script instance data is stored. The only case where everything is loaded by LoadAllAssets<T> is if every asset in that bundle is a ScriptableObject. Looking at the source, I think we can add a few more checks to reduce this further, such as if T is not a scripting type. I've added a note to also improve the documentation for the Load* asset bundle pages.
     
  5. nsmith1024

    nsmith1024

    Joined:
    Mar 18, 2014
    Posts:
    822
    Hello Ryanc_unity,

    At run-time i download an asset bundle, I want to extract everything so they all appear as if they are in the resource folder of the running unity app, for example if the asset bundle contained a prefab called "monster" normally i would have to do this

    var prefab=bundle.LoadAsset("monster");
    Instantiate(prefab);

    Instead of doing that, i want to load everything in the downloaded asset bundle so that everything in there acts as if its in the resource folder, so that i can do this directly and not have to the bundle.LoadAsset("monster") step, like this

    Instantate("monster")

    Is this possible?

    Thanks
     
  6. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,598
    I don't understand the limitation here.
    Scripting types are referenced by GUIDs. They could also be referenced by an Assembly qualified name, if someone wanted more flexibility, with say third-party libraries.
    There's literally zero reason to have to fully load an object to know what type it is or what it contains if the headers have the proper information.
     
unityunity