-
-
Save HilariousCow/7f301b04c28fdf61e71f to your computer and use it in GitHub Desktop.
| 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; | |
| } | |
| } |
Awesome! Thanks for sharing. For anyone else looking, if you need the subdirectories too, just add a SearchOption to the GetFiles Method like so
FileInfo[] fileInf = dirInfo.GetFiles("*.prefab",SearchOption.AllDirectories);
root folder should be directory of folders for this script to work that is a pre-condition
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();
}
public List<T> LoadAllPrefabsOfType<T>(string path, Func<T, bool> evaluate) where T : MonoBehaviour
{
if (path != "")
{
if (path.EndsWith("/"))
{
path = path.TrimEnd('/');
}
}
DirectoryInfo dirInfo = new DirectoryInfo(path);
FileInfo[] fileInf = dirInfo.GetFiles("*.prefab", SearchOption.AllDirectories);
//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)
{
// validate the expression
if (evaluate.Invoke(hasT))
{
prefabComponents.Add(hasT);
}
}
}
}
return prefabComponents;
}`
Hope this helps someone, Cheers!
@MuhammadFaizanKhan @lovancon
I also needed this functionality so I made some changes to it in this fork:
https://gist.github.com/ytjchan/b32e54233895122ab9d51156dccf6ee4