La clase Unity AssetDatabase proporciona una API para obtener dependencias de activos, si queremos obtener a qué activos hace referencia un activo, podemos hacerlo a través de las siguientes ideas:
1. Obtener todos los activos del proyecto;
2. Recorra cada activo para obtener una lista de sus dependencias;
3. Si el activo A tiene el activo B en su lista de dependencias, el activo A hace referencia al activo B.
API principal utilizada:
1. Obtener ruta de activos basada en guid
//
// 摘要:
// Gets the corresponding asset path for the supplied GUID, or an empty string if
// the GUID can't be found.
//
// 参数:
// guid:
// The GUID of an asset.
//
// 返回结果:
// Path of the asset relative to the project folder.
public static string GUIDToAssetPath(string guid)
{
return GUIDToAssetPath_Internal(new GUID(guid));
}
2. Obtenga el tipo de activo de acuerdo con la ruta del activo
//
// 摘要:
// Returns the type of the main asset object at assetPath.
//
// 参数:
// assetPath:
// Filesystem path of the asset to load.
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern Type GetMainAssetTypeAtPath(string assetPath);
3. Obtenga las dependencias del activo según la ruta del activo:
//
// 摘要:
// Returns an array of all the assets that are dependencies of the asset at the
// specified pathName. Note: GetDependencies() gets the Assets that are referenced
// by other Assets. For example, a Scene could contain many GameObjects with a Material
// attached to them. In this case, GetDependencies() will return the path to the
// Material Assets, but not the GameObjects as those are not Assets on your disk.
//
// 参数:
// pathName:
// The path to the asset for which dependencies are required.
//
// recursive:
// Controls whether this method recursively checks and returns all dependencies
// including indirect dependencies (when set to true), or whether it only returns
// direct dependencies (when set to false).
//
// 返回结果:
// The paths of all assets that the input depends on.
public static string[] GetDependencies(string pathName)
{
return GetDependencies(pathName, recursive: true);
}
4. Cargue activos según la ruta y el tipo de activos
//
// 摘要:
// Returns the first asset object of type type at given path assetPath.
//
// 参数:
// assetPath:
// Path of the asset to load.
//
// type:
// Data type of the asset.
//
// 返回结果:
// The asset matching the parameters.
[MethodImpl(MethodImplOptions.InternalCall)]
[NativeThrows]
[PreventExecutionInState(AssetDatabasePreventExecution.kGatheringDependenciesFromSourceFile, PreventExecutionSeverity.PreventExecution_ManagedException, "Assets may not be loaded while dependencies are being gathered, as these assets may not have been imported yet.")]
[TypeInferenceRule(TypeInferenceRules.TypeReferencedBySecondArgument)]
public static extern UnityEngine.Object LoadAssetAtPath(string assetPath, Type type);
La herramienta implementada a continuación puede obtener tanto las dependencias del activo como los elementos de referencia del activo:
el código se muestra a continuación:
using System;
using UnityEngine;
using UnityEditor;
using System.Linq;
using System.Collections.Generic;
namespace SK.Framework
{
public class AssetsStatistics : EditorWindow
{
[MenuItem("SKFramework/Assets Statistics")]
private static void Open()
{
GetWindow<AssetsStatistics>("Assets Statistics").Show();
}
private Vector2 selectedListScroll;
//当前选中项索引
private int currentSelectedIndex = -1;
private enum Mode
{
Dependence,
Reference,
}
private Mode mode = Mode.Dependence;
private Vector2 dependenceListScroll;
private Vector2 referenceListScroll;
private string[] dependenciesArray;
private string[] referenceArray;
private void OnGUI()
{
OnListGUI();
OnMenuGUI();
}
private void OnListGUI()
{
if (Selection.assetGUIDs.Length == 0) return;
selectedListScroll = EditorGUILayout.BeginScrollView(selectedListScroll);
for (int i = 0; i < Selection.assetGUIDs.Length; i++)
{
//通过guid获取资产路径
string path = AssetDatabase.GUIDToAssetPath(Selection.assetGUIDs[i]);
GUILayout.BeginHorizontal(currentSelectedIndex == i ? "SelectionRect" : "dragtab first");
//获取资产类型
Type type = AssetDatabase.GetMainAssetTypeAtPath(path);
GUILayout.Label(EditorGUIUtility.IconContent(GetIconName(type.Name)), GUILayout.Width(20f), GUILayout.Height(15f));
GUILayout.Label(path);
//点击选中
if(Event.current.type == EventType.MouseDown && GUILayoutUtility.GetLastRect().Contains(Event.current.mousePosition))
{
currentSelectedIndex = i;
Event.current.Use();
GetDependencies();
}
GUILayout.EndHorizontal();
}
EditorGUILayout.EndScrollView();
}
private void OnMenuGUI()
{
GUILayout.FlexibleSpace();
GUILayout.BeginVertical("Box", GUILayout.Height(position.height * .7f));
{
GUILayout.BeginHorizontal();
{
Color color = GUI.color;
GUI.color = mode == Mode.Dependence ? color : Color.gray;
if (GUILayout.Button("依赖", "ButtonLeft"))
{
mode = Mode.Dependence;
}
GUI.color = mode == Mode.Reference ? color : Color.gray;
if (GUILayout.Button("引用", "ButtonRight"))
{
mode = Mode.Reference;
}
GUI.color = color;
}
GUILayout.EndHorizontal();
switch (mode)
{
case Mode.Dependence: OnDependenceGUI(); break;
case Mode.Reference: OnReferenceGUI(); break;
}
}
GUILayout.EndVertical();
}
private void GetDependencies()
{
string guid = Selection.assetGUIDs[currentSelectedIndex];
string path = AssetDatabase.GUIDToAssetPath(guid);
dependenciesArray = AssetDatabase.GetDependencies(path);
}
private void OnDependenceGUI()
{
EditorGUILayout.HelpBox("该资产的依赖项", MessageType.Info);
if (currentSelectedIndex != -1)
{
dependenceListScroll = EditorGUILayout.BeginScrollView(dependenceListScroll);
for (int i = 0; i < dependenciesArray.Length; i++)
{
string dependency = dependenciesArray[i];
GUILayout.BeginHorizontal("dragtab first");
Type type = AssetDatabase.GetMainAssetTypeAtPath(dependency);
GUILayout.Label(EditorGUIUtility.IconContent(GetIconName(type.Name)), GUILayout.Width(20f), GUILayout.Height(15f));
GUILayout.Label(dependency);
if (Event.current.type == EventType.MouseDown && GUILayoutUtility.GetLastRect().Contains(Event.current.mousePosition))
{
var obj = AssetDatabase.LoadAssetAtPath(dependency, type);
EditorGUIUtility.PingObject(obj);
Event.current.Use();
}
GUILayout.EndHorizontal();
}
EditorGUILayout.EndScrollView();
}
}
private void OnReferenceGUI()
{
EditorGUILayout.HelpBox("该资产的引用项(需点击刷新按钮获取,需要一定时间)", MessageType.Info);
GUI.enabled = currentSelectedIndex != -1;
if (GUILayout.Button("刷新"))
{
if (EditorUtility.DisplayDialog("提醒", "获取工程资产之间的引用关系需要一定时间,是否确定开始", "确定", "取消"))
{
Dictionary<string, string[]> referenceDic = new Dictionary<string, string[]>();
string[] paths = AssetDatabase.GetAllAssetPaths();
for (int i = 0; i < paths.Length; i++)
{
referenceDic.Add(paths[i], AssetDatabase.GetDependencies(paths[i]));
EditorUtility.DisplayProgressBar("进度", "获取工程资产之间的依赖关系", i + 1 / paths.Length);
}
EditorUtility.ClearProgressBar();
string guid = Selection.assetGUIDs[currentSelectedIndex];
string path = AssetDatabase.GUIDToAssetPath(guid);
referenceArray = referenceDic.Where(m => m.Value.Contains(path)).Select(m => m.Key).ToArray();
}
}
GUI.enabled = true;
if(referenceArray != null)
{
referenceListScroll = EditorGUILayout.BeginScrollView(referenceListScroll);
{
for (int i = 0; i < referenceArray.Length; i++)
{
string reference = referenceArray[i];
GUILayout.BeginHorizontal("dragtab first");
Type type = AssetDatabase.GetMainAssetTypeAtPath(reference);
GUILayout.Label(EditorGUIUtility.IconContent(GetIconName(type.Name)), GUILayout.Width(20f), GUILayout.Height(15f));
GUILayout.Label(reference);
if (Event.current.type == EventType.MouseDown && GUILayoutUtility.GetLastRect().Contains(Event.current.mousePosition))
{
var obj = AssetDatabase.LoadAssetAtPath(reference, type);
EditorGUIUtility.PingObject(obj);
Event.current.Use();
}
GUILayout.EndHorizontal();
}
}
EditorGUILayout.EndScrollView();
}
}
private string GetIconName(string typeName)
{
switch (typeName)
{
case "Material": return "d_Material Icon";
case "Mesh": return "d_Mesh Icon";
case "AnimationClip": return "d_AnimationClip Icon";
case "GameObject": return "d_Prefab Icon";
case "Texture2D": return "d_Texture Icon";
case "MonoScript": return "d_cs Script Icon";
case "AnimatorController": return "d_AnimatorController Icon";
case "DefaultAsset": return "d_DefaultAsset Icon";
case "TextAsset": return "d_TextAsset Icon";
case "TimelineAsset": return "d_UnityEditor.Timeline.TimelineWindow";
default: return "d__Help@2x";
}
}
private void OnSelectionChange()
{
currentSelectedIndex = -1;
Repaint();
}
}
}
Bienvenidos a la cuenta pública "Programador Salvaje Contemporáneo"