Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

LoadAllAssetsAtPath not working or I'm using it wrong?

Discussion in 'Editor & General Support' started by Leslie-Young, Nov 1, 2011.

  1. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,148
    I'm trying to get a list of prefabs so I can place them in the scene via code.
    The code below keeps saying "found: 0" and I have about 20 prefabs in that folder.
    Code (csharp):
    1.  
    2. [MenuItem("Tools/Create Decor")]
    3. public static void KBM_Create_Decor()
    4. {
    5.     // find all the decor related prefabs
    6.     Object[] assets = AssetDatabase.LoadAllAssetsAtPath("Assets/art/tile_decor/");
    7.     Debug.Log("found: " + assets.Length);
    8.     foreach (Object asset in assets)
    9.     {
    10.         Debug.Log(": " + asset.name);
    11.     }
    12. }
    13.  
     
  2. ChiefHawks

    ChiefHawks

    Joined:
    Nov 30, 2011
    Posts:
    1
    Is the script that uses the AssetDatabase in the Assets/Editor folder?

    http://unity3d.com/support/documentation/ScriptReference/AssetDatabase.html
     
  3. jnakai

    jnakai

    Joined:
    Aug 28, 2009
    Posts:
    38
    I'm seeing the same issue, even running AssetDatabase.LoadAllAssetsAtPath("Assets") is returning 0 assets
     
  4. jnakai

    jnakai

    Joined:
    Aug 28, 2009
    Posts:
    38
    Looking at this further, seems LoadAllAssetsAtPath() only works when I directly reference a single asset. Trying to use this to load and return all the assets in a directory doesn't work and returns a 0 length array...annoying
     
  5. probbins

    probbins

    Joined:
    Oct 19, 2010
    Posts:
    216
    I am having the same issue, after reading the documentation again I believe there is no method in AssetBundles to get all assets from a folder.

    LoadAllAssetsAtPath returns a object including all objects inside the object. E.G A Assest may include children such as a mesh, therefor it returns both.

    I believe the documentation could be a little bit clearer!

    As a work around I guess ill just need to use the C# library to return the all file paths at a path. EG http://www.csharp-examples.net/get-files-from-directory/
     
    Last edited: Dec 13, 2011
  6. duke

    duke

    Joined:
    Jan 10, 2007
    Posts:
    763
    Yeah this is quite confusing. It would make more sense if it were re-labeled LoadAllSubAssetsAtPath.
     
    errenestoty, TBooker, Laiken and 3 others like this.
  7. B_Nut

    B_Nut

    Joined:
    Apr 14, 2013
    Posts:
    1
    !!!JAVASCRIPT!!!
    Okay I spend a whole day looking for that. In my case I wanted to load a bunch of textures to integrate simple 2D-Animations without changing the script for every new Image (These aren't developed yet). On another (not good tagged) forum.

    The right Command is:
    Code (csharp):
    1. Resources.LoadAll (path : String, systemTypeInstance : Type)
    You should know that you don't have to give the whole path. Just Create a folder at "Assets/Resources/*customfolder*/"
    In my case this works fine:

    Code (csharp):
    1. *global*  var ChangeWalkInterval : float = 0.1;
    2. function ChangeImage(key){
    3.  
    4.         var MarioWalk : Object[];
    5.         if (key == "d")
    6.         MarioWalk = Resources.LoadAll("MarioWalkRight", Texture);
    7.         if (key == "a")
    8.         MarioWalk = Resources.LoadAll("MarioWalkLeft", Texture);
    9.  
    10.         var index : int = Time.time / ChangeWalkInterval;
    11.         index = index % MarioWalk.length;
    12.         renderer.material.mainTexture = MarioWalk[index];
    13. }
    Read the Helpfile for Resources.LoadAll:

    The last lines are copied from here.
     
  8. tomtominc

    tomtominc

    Joined:
    Nov 7, 2013
    Posts:
    22
    I know this is an old topic but this is what I do to get all assets. Is there a better way?

    Code (CSharp):
    1.   /// <summary>
    2.         /// Tries the get an asset.
    3.         /// </summary>
    4.         /// <returns>The asset.</returns>
    5.         /// <param name="optionalName">Optional name: if no name provided returns the first asset.</param>
    6.         /// <typeparam name="T">The 1st type parameter.</typeparam>
    7.         public static T TryGetAsset<T>(string optionalName = "") where T : UnityEngine.Object
    8.         {  
    9.             // Gets all files with the Directory System.IO class
    10.             string[] files = Directory.GetFiles(Application.dataPath, "*.*",SearchOption.AllDirectories);
    11.             T asset = null;
    12.  
    13.             // move through all files
    14.             foreach (var file in files)
    15.             {
    16.                 // use the GetRightPartOfPath utility method to cut the path so it looks like this: Assets/folderblah
    17.                 string path = GetRightPartOfPath(file,"Assets");
    18.  
    19.                 // Then I try and load the asset at the current path.
    20.                 asset = AssetDatabase.LoadAssetAtPath<T>(path);
    21.  
    22.                 // check the asset to see if it's not null
    23.                 if (asset)
    24.                 {
    25.                     // if the optional name is nothing then we skip this step
    26.                     if (optionalName != "")
    27.                     {
    28.                         if (asset.name == optionalName)
    29.                         {
    30.  
    31.                             Debug.Log("Found the database at path: " + path + "with name: " + asset.name);
    32.                             break;
    33.                         }
    34.                     }
    35.                     else
    36.                     {
    37.                         Debug.Log("Found the database at path: " + path);
    38.                         break;
    39.                     }
    40.                 }
    41.  
    42.             }
    43.  
    44.             return asset;
    45.         }
    46.  
    47.         private static string GetRightPartOfPath(string path, string after)
    48.         {
    49.             var parts = path.Split(Path.DirectorySeparatorChar);
    50.             int afterIndex = Array.IndexOf(parts, after);
    51.  
    52.             if (afterIndex == -1)
    53.             {
    54.                 return null;
    55.             }
    56.  
    57.             return string.Join(Path.DirectorySeparatorChar.ToString(),
    58.             parts, afterIndex, parts.Length - afterIndex);
    59.         }
     
  9. the_lemur

    the_lemur

    Joined:
    Apr 3, 2013
    Posts:
    104
    Honestly after all these years Unity documentation continues to be really confusing.

    The documentation just tends to reiterate the function name itself.

    "Loads assets at the given path."

    Well I have a ton of json files there and not one shows up. And yet using the System.IO File/Directory functions everything becomes EXTREMELY SIMPLE.

    I wrote the whole thing in 5minutes. With AssetDatabase, an hour later.. Nothing. But oh Don't use System.IO they warn you... Usability is just ridiculous.
     
    Last edited: Aug 23, 2022
  10. FlightOfOne

    FlightOfOne

    Joined:
    Aug 1, 2014
    Posts:
    668
    It is indeed an old thread yet we are still confused by LoadAllAssetsAtPath() method. See the manual for more info on what it really does.

    Here's what I did to get all the assets (UNITY OBJECTS) from a given folder -figured it would save someone some time and headaches. I mainly use this to add Scriptable objects. Note that this only works in the editor.

    Code (CSharp):
    1. #if UNITY_EDITOR
    2.  
    3.         /// <summary>
    4.         /// Adds newly (if not already in the list) found assets.
    5.         /// Returns how many found (not how many added)
    6.         /// </summary>
    7.         /// <typeparam name="T"></typeparam>
    8.         /// <param name="path"></param>
    9.         /// <param name="assetsFound">Adds to this list if it is not already there</param>
    10.         /// <returns></returns>
    11.         public static int TryGetUnityObjectsOfTypeFromPath<T>(string path, List<T> assetsFound) where T : UnityEngine.Object
    12.         {
    13.             string[] filePaths = System.IO.Directory.GetFiles(path);
    14.  
    15.             int countFound = 0;
    16.  
    17.             Debug.Log(filePaths.Length);
    18.  
    19.             if (filePaths != null && filePaths.Length > 0)
    20.             {
    21.                 for (int i = 0; i < filePaths.Length; i++)
    22.                 {
    23.                     UnityEngine.Object obj = UnityEditor.AssetDatabase.LoadAssetAtPath(filePaths[i], typeof(T));
    24.                     if (obj is T asset)
    25.                     {
    26.                         countFound++;
    27.                         if (!assetsFound.Contains(asset))
    28.                         {
    29.                             assetsFound.Add(asset);
    30.                         }
    31.                     }
    32.                 }
    33.             }
    34.  
    35.             return countFound;
    36.         }
    37.  
    38. #endif
     
    id0, Rodolfo-Rubens, sama-van and 4 others like this.
  11. SoulGameStudio

    SoulGameStudio

    Joined:
    Jan 18, 2016
    Posts:
    46
    FlightOfOne likes this.
  12. illinar

    illinar

    Joined:
    Apr 6, 2011
    Posts:
    863
    Just stumbled into it. Very unfortunate method naming.
     
  13. zachstronaut

    zachstronaut

    Joined:
    Jan 30, 2016
    Posts:
    6
    Unity maybe can't/won't do anything about the method naming at this point, but they sure could update the documentation page for this method to explain that if you want to get all assets of a type from a folder you can't use this method. They could even provide an example of how you could do it. Like this thread provides.
     
  14. echoAndecho

    echoAndecho

    Joined:
    Aug 27, 2019
    Posts:
    1
    I knew it! Bad documentation for this one. Same here, just stumbled onto this thread.

    Another reminder for Unity to work harder on the Doc.
    Will use .Net's System.IO instead.
     
  15. DanjelRicci

    DanjelRicci

    Joined:
    Mar 8, 2010
    Posts:
    308
    Just stumbled on this thread as I got the same "issue". Came up with a simple substitute for that, use at will:

    Code (CSharp):
    1. List<Object> LoadAllAssetsAtPath (string path) {
    2.  
    3.     List<Object> objects = new List<Object>();
    4.     if (Directory.Exists(path)) {
    5.         string[] assets = Directory.GetFiles(path);
    6.         foreach (string assetPath in assets) {
    7.             if (assetPath.Contains(".asset") && !assetPath.Contains(".meta")) {
    8.                 objects.Add(AssetDatabase.LoadMainAssetAtPath(assetPath));
    9.                 Debug.Log("Loaded " + assetPath);
    10.             }
    11.         }
    12.     }
    13.     return objects;
    14. }
     
    owlrazum and tokar_dev like this.
  16. ShadowAngel

    ShadowAngel

    Joined:
    Aug 7, 2012
    Posts:
    12
    Hey guys had to spend some time on this, since I did not want to use System.IO
    So here is a bit safer version(just change out GameLevel to a type you are looking for):
    Code (CSharp):
    1.    
    2.  
    3. public string DataLocation = string.Empty;
    4.  
    5. private List<GameLevel> Load()
    6.     {
    7.         string[] assetGUIDs = UnityEditor.AssetDatabase.FindAssets("t:"+ nameof(GameLevel),new []{DataLocation});
    8.         List<GameLevel> levels = new List<GameLevel>();
    9.         foreach (string guid in assetGUIDs)
    10.         {
    11.             string assetPath = UnityEditor.AssetDatabase.GUIDToAssetPath(guid);
    12.             GameLevel level = UnityEditor.AssetDatabase.LoadAssetAtPath<GameLevel>(assetPath);
    13.             levels.Add(level);
    14.         }
    15.         return levels;
    16.     }
     
    Josiah_Kunz likes this.
  17. m4a44

    m4a44

    Joined:
    Mar 13, 2013
    Posts:
    45
    Updated this so it works with any type.

    Only limitation with this approach is that the search must work in the Project Search (won't find components on objects).
    Code (CSharp):
    1.     public static List<T> FindAssets<T>(params string[] paths) where T : Object
    2.     {
    3.         string[] assetGUIDs = AssetDatabase.FindAssets("t:" + typeof(T), paths);
    4.         List<T> assets = new List<T>();
    5.         foreach (string guid in assetGUIDs)
    6.         {
    7.             string assetPath = AssetDatabase.GUIDToAssetPath(guid);
    8.             T asset = AssetDatabase.LoadAssetAtPath<T>(assetPath);
    9.             assets.Add(asset);
    10.         }
    11.         return assets;
    12.     }
     
    owlrazum likes this.
  18. EnesNder

    EnesNder

    Joined:
    Feb 1, 2021
    Posts:
    1
    Code (CSharp):
    1.        /*using System;
    2.         using System.IO;
    3.         using System.Collections;
    4.         using System.Collections.Generic;
    5.         using UnityEngine;
    6.         using UnityEditor;*/
    7.         List<T> LoadAllAssetsAtPathWithIO<T>(string path, string Pattern) where T : UnityEngine.Object { // Important: Dont add "Assets" to path and Pattern should write with point. For example: .asset
    8.             List<T> _out = new();
    9.  
    10.             string root_path = Application.dataPath + "/" + path;
    11.             Debug.Log(root_path);
    12.  
    13.             if(!Directory.Exists(root_path)) {
    14.                 Debug.LogWarning("Path doesn't exist");
    15.                 return _out;
    16.             }
    17.  
    18.             string[] fileEntries = Directory.GetFiles(root_path, $"*{Pattern}");
    19.  
    20.             foreach(string FileName in fileEntries) {
    21.                 string[] filepath = FileName.Split(Application.dataPath);
    22.                 Debug.Log("Assets" + filepath[1]);
    23.                 _out.Add(AssetDatabase.LoadAssetAtPath<T>("Assets" + filepath[1]));
    24.             }
    25.  
    26.             return _out;
    27.         }
    I think this code will work for you :)