Last active
March 31, 2024 18:33
-
-
Save HilariousCow/7f301b04c28fdf61e71f to your computer and use it in GitHub Desktop.
Load All Prefabs In Directory
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using UnityEngine; | |
using UnityEditor; | |
using System.IO; | |
public static class PrefabLoader | |
{ | |
//So, there's no "load all assets in directory" function in unity. | |
//I guess this is to avoid people using Prefabs as "data blobs". | |
//They'd rather you use ScriptableObjects... which is fine in some cases, | |
//but sometimes the thing you're blobbing is just a bunch of child transforms anyway, | |
//so it's huge buckets of sweat to reproduce the scene tools unity already has. | |
//The "AssetsDatabase.LoadAllAssetsAtPath" refers to /compound/ raw assets, | |
//like maya files. But it doesn't care about humble prefabs, | |
//which are more like compounds of assets, rather than raw assets. | |
//This function collates all the the behaviours you want in the directory you point it at. The path is relative to your Assets. | |
//i.e. "Assets/MyDirectory/" | |
//It returns the Prefab References, remember! Not instantiated scene objects! | |
//So it's only used for *editor-side* tools. Not run time. | |
//Quite useful in conjunction with "PrefabUtility". | |
public static List<T> LoadAllPrefabsOfType<T>(string path) where T : MonoBehaviour | |
{ | |
if (path != "") | |
{ | |
if (path.EndsWith("/")) | |
{ | |
path = path.TrimEnd('/'); | |
} | |
} | |
DirectoryInfo dirInfo = new DirectoryInfo(path); | |
FileInfo[] fileInf = dirInfo.GetFiles("*.prefab"); | |
//loop through directory loading the game object and checking if it has the component you want | |
List<T> prefabComponents = new List<T>(); | |
foreach (FileInfo fileInfo in fileInf) | |
{ | |
string fullPath = fileInfo.FullName.Replace(@"\","/"); | |
string assetPath = "Assets" + fullPath.Replace(Application.dataPath, ""); | |
GameObject prefab = AssetDatabase.LoadAssetAtPath(assetPath, typeof(GameObject)) as GameObject; | |
if(prefab!= null) | |
{ | |
T hasT = prefab.GetComponent<T>(); | |
if (hasT !=null) | |
{ | |
prefabComponents.Add(hasT); | |
} | |
} | |
} | |
return prefabComponents; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Personally I think static methods are just evil. I could see maybe see a justification if this were an extension method. Static methods/properties makes completely untestable code. I have all my game objects in a dll with DryIoc, so I can fully mock make game objects before using them in Unity. Makes for much faster development.
So, I re-modified this so you can apply an Func parameter. For instance, I want all prefabs to be loaded and I have a MonoBehavior that specifies it's scene name it can be loaded in.
using this code I can add custom validation code within the method.
` public List LoadPrefabsByScene(string sceneName)
{
return LoadAllPrefabsOfType("Assets/Resources/Prefabs", (x) => x.Scenes.Contains(sceneName))..Select(x => x.gameObject).ToList();
}
Hope this helps someone, Cheers!