- Home /
Getting all assets of the specified type
I'm searching for something like:
Object[] objs = AssetDatabase.Find (typeof (ScriptableObject));
Does this exists? If not, how does ProjectWindow (or a SearchableEditorWindow) get those? How does the search manage to filter by type? (`t:Material`)
Anyone knows how to use HierarchyProperty
s? They seem to be very unstable, but ProjectWindow relies on them it seems.
I have converted my comment into an answer. Glad that you solved!
Answer by BiG · Jul 05, 2013 at 08:48 AM
Does Resources.FindObjectsOfTypeAll accomplish what you wanna do?
This will only find assets that are loaded (into memory in the Editor), not all assets in your Project hierarchy.
Answer by glitchers · Jul 15, 2016 at 09:56 AM
Unity has made Object. FindObjectsOfTypeIncludingAssets
obsolete and recommends you use Resources. FindObjectsOfTypeAll
but this will not find all assets.
I have written a small piece of code that you can use in Editor only that takes a generic type and will return all objects in your project regardless of if they have been loaded yet.
public static List<T> FindAssetsByType<T>() where T : UnityEngine.Object
{
List<T> assets = new List<T>();
string[] guids = AssetDatabase.FindAssets(string.Format("t:{0}", typeof(T)));
for( int i = 0; i < guids.Length; i++ )
{
string assetPath = AssetDatabase.GUIDToAssetPath( guids[i] );
T asset = AssetDatabase.LoadAssetAtPath<T>( assetPath );
if( asset != null )
{
assets.Add(asset);
}
}
return assets;
}
Thanks! The only thing is that at line 5 typeof(T) should be typeof (T).ToString().Replace("UnityEngine.", "");
For example if we're looking for a material we should say FindAssets("t:$$anonymous$$aterial");
however typeof(T)
returns UnityEngine.$$anonymous$$aterial
, therefore we have to remove the UnityEngine part first.
This wont work with scenes due to a boxing conversion error :/ 5.6.0f3
Answer by icepick912 · Nov 27, 2013 at 06:37 PM
Here is a c# one for getting all assets in project of type with a certain file extension
/// <summary>
/// Used to get assets of a certain type and file extension from entire project
/// </summary>
/// <param name="type">The type to retrieve. eg typeof(GameObject).</param>
/// <param name="fileExtension">The file extention the type uses eg ".prefab".</param>
/// <returns>An Object array of assets.</returns>
public static Object[] GetAssetsOfType(System.Type type, string fileExtension)
{
List<Object> tempObjects = new List<Object>();
DirectoryInfo directory = new DirectoryInfo(Application.dataPath);
FileInfo[] goFileInfo = directory.GetFiles("*" + fileExtension, SearchOption.AllDirectories);
int i = 0; int goFileInfoLength = goFileInfo.Length;
FileInfo tempGoFileInfo; string tempFilePath;
Object tempGO;
for (; i < goFileInfoLength; i++)
{
tempGoFileInfo = goFileInfo[i];
if (tempGoFileInfo == null)
continue;
tempFilePath = tempGoFileInfo.FullName;
tempFilePath = tempFilePath.Replace(@"\", "/").Replace(Application.dataPath, "Assets");
Debug.Log(tempFilePath + "\n" + Application.dataPath);
tempGO = AssetDatabase.LoadAssetAtPath(tempFilePath, typeof(Object)) as Object;
if (tempGO == null)
{
Debug.LogWarning("Skipping Null");
continue;
}
else if (tempGO.GetType() != type)
{
Debug.LogWarning("Skipping " + tempGO.GetType().ToString());
continue;
}
tempObjects.Add(tempGO);
}
return tempObjects.ToArray();
}
I have changed your code a little to support declarations like that: $$anonymous$$yScript[] script = GetAssetsOfType(".prefab");
/// <summary>
/// Used to get assets of a certain type and file extension from entire project
/// </summary>
/// <param name="type">The type to retrieve. eg typeof(GameObject).</param>
/// <param name="fileExtension">The file extention the type uses eg ".prefab".</param>
/// <returns>An Object array of assets.</returns>
public static T[] GetAssetsOfType<T>(string fileExtension) where T : UnityEngine.Object
{
List<T> tempObjects = new List<T>();
DirectoryInfo directory = new DirectoryInfo(Application.dataPath);
FileInfo[] goFileInfo = directory.GetFiles("*" + fileExtension, SearchOption.AllDirectories);
int i = 0; int goFileInfoLength = goFileInfo.Length;
FileInfo tempGoFileInfo; string tempFilePath;
T tempGO;
for (; i < goFileInfoLength; i++)
{
tempGoFileInfo = goFileInfo[i];
if (tempGoFileInfo == null)
continue;
tempFilePath = tempGoFileInfo.FullName;
tempFilePath = tempFilePath.Replace(@"\", "/").Replace(Application.dataPath, "Assets");
tempGO = AssetDatabase.LoadAssetAtPath(tempFilePath, typeof(T)) as T;
if (tempGO == null)
{
continue;
}
else if (!(tempGO is T))
{
continue;
}
tempObjects.Add(tempGO);
}
return tempObjects.ToArray();
}
I prefer clean code, so here is my version. ;) Supports checking for both extension or extension plus type:
public static T[] FindAssetsWithExtension<T>(string fileExtension) where T : UnityEngine.Object
{
var paths = FindAssetPathsWithExtension(fileExtension);
if (paths == null || paths.Length == 0)
return null;
List<T> assetsOfType = new List<T>();
for (int i = 0; i < paths.Length; i++)
{
var asset = AssetDatabase.LoadAssetAtPath(paths[i], typeof(T)) as T;
if (asset == null || (asset is T) == false)
continue;
assetsOfType.Add(asset);
}
return assetsOfType.ToArray();
}
public static string[] FindAssetPathsWithExtension(string fileExtension)
{
if (string.IsNullOrEmpty(fileExtension))
return null;
if (fileExtension[0] == '.')
fileExtension = fileExtension.Substring(1);
DirectoryInfo directoryInfo = new DirectoryInfo(Application.dataPath);
FileInfo[] fileInfos = directoryInfo.GetFiles("*." + fileExtension, SearchOption.AllDirectories);
List<string> assetPaths = new List<string>();
foreach (var file in fileInfos)
{
var assetPath = file.FullName.Replace(@"\", "/").Replace(Application.dataPath, "Assets");
assetPaths.Add(assetPath);
}
return assetPaths.ToArray();
}
Answer by FriedrichWessel_Inno · Oct 18, 2018 at 07:49 AM
AssetDatabase.Find("t: ScriptableObject")
You can test the filters in your searchbar before Documentation: https://docs.unity3d.com/ScriptReference/AssetDatabase.FindAssets.html
Answer by zauberzaubar · Apr 09, 2021 at 02:32 PM
glitchers answer is correct but here's an iterator version of it:
public static IEnumerable<T> FindAssetsByType<T>() where T : Object {
var guids = AssetDatabase.FindAssets($"t:{typeof(T)}");
foreach (var t in guids) {
var assetPath = AssetDatabase.GUIDToAssetPath(t);
var asset = AssetDatabase.LoadAssetAtPath<T>(assetPath);
if (asset != null) {
yield return asset;
}
}
}
Your answer
Follow this Question
Related Questions
How to highlight or select an asset in project window from editor script? 2 Answers
Multiple object Selection in project view: Unity shows wrong type 0 Answers
Was the feature of using the Asterisk ('*') as a wildcard Removed? 1 Answer
Getting assets / sub folders inside a folder 1 Answer
Custom Project Editor Window 1 Answer