assetBundle - get the list of the assets in the bundle

is it possible to get list of assets in the bundle, for example, i dont want to load them by name (because i dont want to know their names), i want to loop through the bundle and load the ones i want...

here is the code i use currently to get assetBundles i made for my game (but i get the mainAsset, it would be still ok to loop through main asset to get all children, ideally it would be to somehow get the list of assets and then to load them with LoadAsync, so they start appearing as soon as they are downloaded):

function StartDownload(url:String,download : WWW,instanced : Object){ 

     // INDEXOF METHOD RETURNS THE POSITION IN THE STRING OF THE SEARCH SUBSTRING 
     if (url.IndexOf ("file://") == 0 || url.IndexOf ("http://") == 0) 
        //IF THE FILE:// OR HTTP:// ARE IN THE BEGINNING OF THE URL PROCEED TO DOWNLOAD 
        download = new WWW (url); 
     if (Application.platform == RuntimePlatform.OSXWebPlayer || Application.platform == RuntimePlatform.WindowsWebPlayer) 
        //IF WE ARE EXECUTING IN THE PLAYER 
        download = new WWW (url); 
     else if (Application.platform == RuntimePlatform.OSXEditor || Application.platform == RuntimePlatform.WindowsEditor) 
        //IF WE ARE EXECUTING LOCALLY 
        download = new WWW ("file://" + Application.dataPath + "/Bundles/" + url); 

     //PLACE HERE THE PROGRESS CODE (progress variable has to be global and private 
     if(download.error==null){ 
        //   progressString=parseInt(download.progress*100).ToString();
           //Debug.Log(download.progress); 
     } else { 
           Debug.Log(download.error); 
     } 

     //progressString=parseInt(download.progress*100).ToString(); 

     //WAIT FOR IT TO FINISH 
     yield download;          

     //ASSIGN ASSETBUNDLE FROM DOWNLOAD TO ASSETBUNDLE OBJECT 
     assetBundle = download.assetBundle; 

     //WE CAN NOW RELEASE DOWNLOAD BY 
     download.Dispose(); 
     download=null; 
     //SO THAT WE CAN USE IT LATER ON THE NEXT OBJECT 

     //IF ASSETBUNDLE ISNT NULL 
     if (assetBundle != null) 
     { 

        // Alternatively you can also load an asset by name (assetBundle.Load("my asset name")) 
        var go : Object = assetBundle.mainAsset; 

        //IF  EVERYTHING IS OK 
        if (go != null) 
           //INSTANTIATE THE ASSET BUNDLE 
           instanced = Instantiate(go); 
        else 
           Debug.Log("Couldnt load resource");    
     } 
     else 
     { 
        Debug.Log("Couldnt load resource");    
     } 
  } 

any help or direction is appreciated! thanks!

As far as I know, no you can't list all the assets inside and assetbundle.

However, you can use

Object.FindObjectsOfType (type : Type) : Object[]
Object.FindObjectOfType (type : Type) : Object

After getting your mainasset bundle to load objects by type.

You could also use

AssetBundle.LoadAll(type: Type)

To load all the items by type

Or you can use

AssetBundle.Contains(name : string) : bool

To find if any asset you are looking for by name exists (although, by the nature of your question, you might not want that)

Hope this helps you, Italo F. Capasso B. AKA "Edwood Grant"

There is simple technique used in “CharacterCustomization” example:

in short:

During creation of assetbundle you may create list of objects names, then add it to instance of StringHolder:

public class StringHolder : ScriptableObject
{
public string content;
}

StringHolder holder = ScriptableObject.CreateInstance ();
holder.content = listOfNames.ToArray();
AssetDatabase.CreateAsset(holder, “Assets/objects_names.asset”);

and then add this asset to assetbundle as you did with “real” objects.

At loading time just:
StringHolder names = WWW.assetBundle.Load(“objects_names”, typeof(StringHolder));

so you will know what is inside loaded asset.

You may use simple technique from

During creation of asset write also list of names, like this:

public class StringHolder : ScriptableObject
{
    public string[] content;
}

StringHolder holder = ScriptableObject.CreateInstance<StringHolder>();
holder.content = listOfNames.ToArray();
AssetDatabase.CreateAsset(holder, "Assets/objects_names.asset");

and export this asset with other.


at reading just:

StringHolder objects_names = WWW.assetBundle.LoadAsync("objects_names", typeof(StringHolder));

and that’s all.

Update: Lately I’ve encountered problem with loading StringHolder from WebPlayer. Some “the class defined in script file named ‘StringHolder’ does not match the file name!” garbage. So i’ve come to another solution of creating transitory TextAsset with names of objects in bundle:

// first temporary add txt file to asset database
string assets_names; // contains all names
string path_to_names_in_data = "Resources\\objects_names.txt";
File.WriteAllText( Path.Combine( Application.dataPath, path_to_names_in_data ), assets_names );

// import txt as TextAsset
AssetDatabase.ImportAsset( "Assets/Resources/objects_names.txt", ImportAssetOptions.ForceSynchronousImport );

// get this as TextAsset object
TextAsset text_asset = ( TextAsset )AssetDatabase.LoadAssetAtPath( "Assets/Resources/objects_names.txt", typeof( TextAsset ) );

// add it to export array
Object[] export_selection = new Object[1 + current_selection.Length];
export_selection[ 0 ] = text_asset;

// build bundle:
BuildPipeline.BuildAssetBundle(Selection.activeObject, export_selection, path, BuildAssetBundleOptions.DeterministicAssetBundle | BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets );

// release TextAsset
AssetDatabase.DeleteAsset( AssetDatabase.GetAssetPath( text_asset ) );
UnityEngine.Object.DestroyImmediate( text_asset );

Now I can load this TextAsset at runtime like following:

	TextAsset objects_in_bundle = ( TextAsset )m_asset_bundle.Load( "objects_names", typeof( TextAsset ) );
	string assets_names = objects_in_bundle.text;

Above looks complicated, but has no runtime issues. Hope that may help. :slight_smile:

This old thread still shows up high in google search rankings so it’s worth mentioning that now you definitely can get a list of assets by name.

var names = assetBundle.GetAllAssetNames();

foreach(var name in names) {
  Debug.Log($"name={name}");
}