In the editor I want to load all the assets in a given folder into an array. Once I have the asset’s name I can use AssetDatabase.LoadAssetAtPath . But how do I find out what assets are in the folder?
You have an asset build script that puts in a text file into the root that lists all files in as it has written them when adding to the bundle
then you can get those information from that text file.
I have looked at my orginal question and see I misunderstood how loadall works. so the answer to my orignal question (untest) be to var textures : Object[] = Resources.LoadAll("Prefabs", GameObjects); and loop over Object[ ] getting the names out.
The approach that uses .NET’s System.IO is not guaranteed to work on devices. The ‘Resources’ folder e.g. can become one big wad and filesystem calls will fail at that point.
The Resources.LoadAll approach is not great either because of the large memory load it can cause.
It’s kind of disappointing that Unity does not support a simple operation like listing your assets without side effects. This can be especially useful when you are trying to get something done quick and dirty.
Lacking this, the best approach seems to be @Dreamora’s approach of caching a list at build time.
Maybe I’m missing something, but why don’t you use Resources.LoadAll(string path) ? Which does exactly what you want… You just have to put the assets you want to import in the Resources folder.
Because that “loads the asset” imagine having 5000 models in there and you want to iterate over them (loading only 1 or a screenful at a time)… Resources.LoadAll() is no good here.
For my usecase, I have implimented this as a static method, that returns a List.
Also, I dislike for loops, so I used Select for clarity, which applies a function to a whole set.
public static List<T> GetAssetList<T>(string path) where T : class
{
string[] fileEntries = Directory.GetFiles(Application.dataPath + "/" + path);
return fileEntries.Select(fileName =>
{
string temp = fileName.Replace("\\", "/");
int index = temp.LastIndexOf("/");
string localPath = "Assets/" + path;
if (index > 0)
localPath += temp.Substring(index);
return AssetDatabase.LoadAssetAtPath(localPath, typeof(T));
})
//Filtering null values, the Where statement does not work for all types T
.OfType<T>() //.Where(asset => asset != null)
.ToList();
}
var assets = AssetDatabase.FindAssets("t:AnimationClip", new[] {"Assets/Animations"});
foreach (var guid in assets) {
var clip = AssetDatabase.LoadAssetAtPath<AnimationClip>(AssetDatabase.GUIDToAssetPath(guid));
Debug.Log(clip);
}
This is safer than working with Directory and IndexOf(“Assets”) because those can break randomly (for example when your project ends up in a subdir that has Assets in its name).
Worth noting: AssetDatabase.FindAssets can be very slow if you have lots of assets in the project. In my project, using the Directory.GetFiles + AssetDatabase.AssetPathToGUID was about 50x faster. (~40 ms down to 0.8ms)
Might be a stupid question but how do I call that?
private T[ ] GetAtPath(string path) - what does the call look like and what do I have at that point? I am looking for a way to get every mesh under assets and turn off the mesh setting of read|write in order to save some memory durring gameplay.