Combate de desarrollo del editor de Unity [AssetDatabase]: obtenga referencias y dependencias de activos

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"

Supongo que te gusta

Origin blog.csdn.net/qq_42139931/article/details/123796260
Recomendado
Clasificación