Search code examples
unity-game-enginefile-extensionassetbundle

Unity: Loading an asset from an Asset Bundle without a file extention


I'm using asset bundles to load localised VO. These VO files could be .wavs or .oggs and it's not viable to specify which before loading the file. This is fine when loading the default files from Resources since Unity doesn't require the file extension. However when loading the localised files from an Asset Bundle, if the file extension isn't included in the load call the file can't be found. The manifest file does include the extension.

Is there a way to load a file from an Asset Bundle without providing the extension? From what I hear, this was doable in Unity 4 but I'm having the problem using Unity 5 (5.1.2p3).

Just as an example of what I'm trying to do:

This works:

AudioClip soundClip = localisedAssetBundle.LoadAsset<AudioClip>( "sound.wav" );

This also works:

AudioClip soundClip = Resources.Load<AudioClip>( "sound" );

But this doesn't:

AudioClip soundClip = localisedAssetBundle.LoadAsset<AudioClip>( "sound" );

POST-ANSWER EDIT:

My examples weren't quite correct, as I was paraphrasing them. The third example actually would have worked as it is written above. However, what I had actually tried to do in my code was this:

AudioClip soundClip = localisedAssetBundle.LoadAsset<AudioClip>( "Assets/sound" );

Since I was neither specifying a valid path, nor a valid filename, this didn't work. See accepted answer for full explanation.


Solution

  • You can load an asset from an asset bundle either by its path, or by its name.

    From docs:

    AssetBundle.LoadAsset will load an object using its name identifier as a parameter. The name is the one visible in the Project view. You can optionally pass an object type as an argument to the Load method to make sure the object loaded is of a specific type.

    For example:

    AudioClip sound = _assetBundle.LoadAsset<AudioClip>( "assets/sound.wav" ); // Get an asset by path
    
    AudioClip sound2 = _assetBundle.LoadAsset<AudioClip>( "sound" ); // Get an asset by name
    AudioClip sound = _assetBundle.LoadAsset<AudioClip>( "sound.wav" ); //Get an asset by file name
    
    AudioClip sound = _assetBundle.LoadAsset<AudioClip>( "Assets/sound" ); // This will not work as it's neither a path, nor an asset name
    

    In case you have 2 assets with identical name, you can specify which asset type you need. Let's say you have an AudioClip asset called "test" and a material asset, called "test".

    bundle.LoadAsset<Material>("test"); //returns you material
    bundle.LoadAsset("test", typeof(Material)); //as well, as this one
    bundle.LoadAsset<AudioClip>("test"); //returns an audio clip