-
-
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; | |
} | |
} |
Please tell me if i was wrong( cause i m also nêw bie and trying to learn too) if you want to change it into object just load object .... why did you load their component
@MuhammadFaizanKhan @lovancon
I also needed this functionality so I made some changes to it in this fork:
https://gist.github.com/ytjchan/b32e54233895122ab9d51156dccf6ee4
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!
Thanks I am able to use this through
Can i change it to gameobject type?