Unity 编辑器开发实战【AssetDatabase】- 获取资产的依赖项、引用项

简介: Unity 编辑器开发实战【AssetDatabase】- 获取资产的依赖项、引用项

image.gif

Unity AssetDatabase类中提供了获取资产依赖项的API,如果我们想要获取某一资产被哪些资产引用,可以通过如下思路去实现:

1.获取工程中的所有资产;

2.遍历每一项资产,获取其依赖项列表;

3.如果资产A的依赖项列表中包含资产B,则资产B被资产A引用。

用到的核心API:

1.根据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.publicstaticstringGUIDToAssetPath(stringguid)
{
returnGUIDToAssetPath_Internal(newGUID(guid));
}

image.gif

2.根据资产路径获取资产的类型

//// 摘要://     Returns the type of the main asset object at assetPath.//// 参数://   assetPath://     Filesystem path of the asset to load.[MethodImpl(MethodImplOptions.InternalCall)]
publicstaticexternTypeGetMainAssetTypeAtPath(stringassetPath);

image.gif

3.根据资产路径获取该资产的依赖项:

//// 摘要://     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.publicstaticstring[] GetDependencies(stringpathName)
{
returnGetDependencies(pathName, recursive: true);
}

image.gif

4.根据资产路径及类型加载资产

//// 摘要://     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)]
publicstaticexternUnityEngine.ObjectLoadAssetAtPath(stringassetPath, Typetype);

image.gif

下面实现的工具,既可以获取资产的依赖项,也可以获取资产的引用项:

image.gif

代码如下:

usingSystem;
usingUnityEngine;
usingUnityEditor;
usingSystem.Linq;
usingSystem.Collections.Generic;
namespaceSK.Framework{
publicclassAssetsStatistics : EditorWindow    {
        [MenuItem("SKFramework/Assets Statistics")]
privatestaticvoidOpen()
        {
GetWindow<AssetsStatistics>("Assets Statistics").Show();
        }
privateVector2selectedListScroll;
//当前选中项索引privateintcurrentSelectedIndex=-1;
privateenumMode        {
Dependence,
Reference,
        }
privateModemode=Mode.Dependence;
privateVector2dependenceListScroll;
privateVector2referenceListScroll;
privatestring[] dependenciesArray;
privatestring[] referenceArray;
privatevoidOnGUI()
        {
OnListGUI();
OnMenuGUI();
        }
privatevoidOnListGUI()
        {
if (Selection.assetGUIDs.Length==0) return;
selectedListScroll=EditorGUILayout.BeginScrollView(selectedListScroll);
for (inti=0; i<Selection.assetGUIDs.Length; i++)
            {
//通过guid获取资产路径stringpath=AssetDatabase.GUIDToAssetPath(Selection.assetGUIDs[i]);
GUILayout.BeginHorizontal(currentSelectedIndex==i?"SelectionRect" : "dragtab first");
//获取资产类型Typetype=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();
        }
privatevoidOnMenuGUI()
        {
GUILayout.FlexibleSpace();
GUILayout.BeginVertical("Box", GUILayout.Height(position.height* .7f));
            {
GUILayout.BeginHorizontal();
                {
Colorcolor=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)
                {
caseMode.Dependence: OnDependenceGUI(); break;
caseMode.Reference: OnReferenceGUI(); break;
                }
            }
GUILayout.EndVertical();
        }
privatevoidGetDependencies()
        {
stringguid=Selection.assetGUIDs[currentSelectedIndex];
stringpath=AssetDatabase.GUIDToAssetPath(guid);
dependenciesArray=AssetDatabase.GetDependencies(path);
        }
privatevoidOnDependenceGUI()
        {
EditorGUILayout.HelpBox("该资产的依赖项", MessageType.Info);
if (currentSelectedIndex!=-1)
            {
dependenceListScroll=EditorGUILayout.BeginScrollView(dependenceListScroll);
for (inti=0; i<dependenciesArray.Length; i++)
                {
stringdependency=dependenciesArray[i];
GUILayout.BeginHorizontal("dragtab first");
Typetype=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))
                    {
varobj=AssetDatabase.LoadAssetAtPath(dependency, type);
EditorGUIUtility.PingObject(obj);
Event.current.Use();
                    }
GUILayout.EndHorizontal();
                }
EditorGUILayout.EndScrollView();
            }
        }
privatevoidOnReferenceGUI()
        {
EditorGUILayout.HelpBox("该资产的引用项(需点击刷新按钮获取,需要一定时间)", MessageType.Info);
GUI.enabled=currentSelectedIndex!=-1;
if (GUILayout.Button("刷新")) 
            {
if (EditorUtility.DisplayDialog("提醒", "获取工程资产之间的引用关系需要一定时间,是否确定开始", "确定", "取消"))
                {
Dictionary<string, string[]>referenceDic=newDictionary<string, string[]>();
string[] paths=AssetDatabase.GetAllAssetPaths();
for (inti=0; i<paths.Length; i++)
                    {
referenceDic.Add(paths[i], AssetDatabase.GetDependencies(paths[i]));
EditorUtility.DisplayProgressBar("进度", "获取工程资产之间的依赖关系", i+1/paths.Length);
                    }
EditorUtility.ClearProgressBar();
stringguid=Selection.assetGUIDs[currentSelectedIndex];
stringpath=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 (inti=0; i<referenceArray.Length; i++)
                    {
stringreference=referenceArray[i];
GUILayout.BeginHorizontal("dragtab first");
Typetype=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))
                        {
varobj=AssetDatabase.LoadAssetAtPath(reference, type);
EditorGUIUtility.PingObject(obj);
Event.current.Use();
                        }
GUILayout.EndHorizontal();
                    }
                }
EditorGUILayout.EndScrollView();
            }
        }
privatestringGetIconName(stringtypeName)
        {
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";
            }
        }
privatevoidOnSelectionChange()
        {
currentSelectedIndex=-1;
Repaint();
        }
    }
}

image.gif

目录
相关文章
|
1月前
|
缓存 API 开发工具
有关Unity使用Rider编辑器无法弹出代码提示的有效解决方法
【11月更文挑战第13天】在 Unity 中使用 Rider 编辑器时,若遇到代码提示无法弹出的问题,可以通过检查 Rider 设置(如自动补全选项、Unity 插件安装、索引设置)、Unity 项目设置(如解决方案正确关联、脚本导入设置)以及环境和依赖关系(如 .NET SDK 版本兼容性、Unity 和 Rider 版本兼容性)等方面进行排查和解决。
|
4月前
|
图形学 开发者 存储
超越基础教程:深度拆解Unity地形编辑器的每一个隐藏角落,让你的游戏世界既浩瀚无垠又细节满满——从新手到高手的全面技巧升级秘籍
【8月更文挑战第31天】Unity地形编辑器是游戏开发中的重要工具,可快速创建复杂多变的游戏环境。本文通过比较不同地形编辑技术,详细介绍如何利用其功能构建广阔且精细的游戏世界,并提供具体示例代码,展示从基础地形绘制到植被与纹理添加的全过程。通过学习这些技巧,开发者能显著提升游戏画面质量和玩家体验。
193 3
|
4月前
|
开发者 图形学 开发工具
Unity编辑器神级扩展攻略:从批量操作到定制Inspector界面,手把手教你编写高效开发工具,解锁编辑器隐藏潜能
【8月更文挑战第31天】Unity是一款强大的游戏开发引擎,支持多平台发布与高度可定制的编辑器环境。通过自定义编辑器工具,开发者能显著提升工作效率。本文介绍如何使用C#脚本扩展Unity编辑器功能,包括批量调整游戏对象位置、创建自定义Inspector界面及项目统计窗口等实用工具,并提供具体示例代码。理解并应用这些技巧,可大幅优化开发流程,提高生产力。
440 1
|
4月前
|
开发者 图形学 Java
揭秘Unity物理引擎核心技术:从刚体动力学到关节连接,全方位教你如何在虚拟世界中重现真实物理现象——含实战代码示例与详细解析
【8月更文挑战第31天】Unity物理引擎对于游戏开发至关重要,它能够模拟真实的物理效果,如刚体运动、碰撞检测及关节连接等。通过Rigidbody和Collider组件,开发者可以轻松实现物体间的互动与碰撞。本文通过具体代码示例介绍了如何使用Unity物理引擎实现物体运动、施加力、使用关节连接以及模拟弹簧效果等功能,帮助开发者提升游戏的真实感与沉浸感。
121 1
|
4月前
|
算法 vr&ar C#
使用Unity进行虚拟现实开发:深入探索与实践
【8月更文挑战第24天】使用Unity进行虚拟现实开发是一个充满挑战和机遇的过程。通过掌握Unity的VR开发技术,你可以创造出令人惊叹的VR体验,为用户带来前所未有的沉浸感和乐趣。随着技术的不断进步和应用场景的不断拓展,VR开发的未来充满了无限可能。希望本文能为你提供有用的指导和启发!
|
3月前
|
图形学 C++ C#
Unity插件开发全攻略:从零起步教你用C++扩展游戏功能,解锁Unity新玩法的详细步骤与实战技巧大公开
【8月更文挑战第31天】Unity 是一款功能强大的游戏开发引擎,支持多平台发布并拥有丰富的插件生态系统。本文介绍 Unity 插件开发基础,帮助读者从零开始编写自定义插件以扩展其功能。插件通常用 C++ 编写,通过 Mono C# 运行时调用,需在不同平台上编译。文中详细讲解了开发环境搭建、简单插件编写及在 Unity 中调用的方法,包括创建 C# 封装脚本和处理跨平台问题,助力开发者提升游戏开发效率。
300 0
|
3月前
|
图形学 iOS开发 Android开发
从Unity开发到移动平台制胜攻略:全面解析iOS与Android应用发布流程,助你轻松掌握跨平台发布技巧,打造爆款手游不是梦——性能优化、广告集成与内购设置全包含
【8月更文挑战第31天】本书详细介绍了如何在Unity中设置项目以适应移动设备,涵盖性能优化、集成广告及内购功能等关键步骤。通过具体示例和代码片段,指导读者完成iOS和Android应用的打包与发布,确保应用顺利上线并获得成功。无论是性能调整还是平台特定的操作,本书均提供了全面的解决方案。
160 0
|
3月前
|
图形学 开发者 搜索推荐
Unity Asset Store资源大解密:自制与现成素材的优劣对比分析,教你如何巧用海量资产加速游戏开发进度
【8月更文挑战第31天】游戏开发充满挑战,尤其对独立开发者或小团队而言。Unity Asset Store 提供了丰富的资源库,涵盖美术、模板、音频和脚本等,能显著加快开发进度。自制资源虽具个性化,但耗时长且需专业技能;而 Asset Store 的资源经官方审核,质量可靠,可大幅缩短开发周期,使开发者更专注于核心玩法。然而,使用第三方资源需注意版权问题,且可能需调整以适应特定需求。总体而言,合理利用 Asset Store 能显著提升开发效率和项目质量。
89 0
|
4月前
|
开发者 图形学 API
从零起步,深度揭秘:运用Unity引擎及网络编程技术,一步步搭建属于你的实时多人在线对战游戏平台——详尽指南与实战代码解析,带你轻松掌握网络化游戏开发的核心要领与最佳实践路径
【8月更文挑战第31天】构建实时多人对战平台是技术与创意的结合。本文使用成熟的Unity游戏开发引擎,从零开始指导读者搭建简单的实时对战平台。内容涵盖网络架构设计、Unity网络API应用及客户端与服务器通信。首先,创建新项目并选择适合多人游戏的模板,使用推荐的网络传输层。接着,定义基本玩法,如2D多人射击游戏,创建角色预制件并添加Rigidbody2D组件。然后,引入网络身份组件以同步对象状态。通过示例代码展示玩家控制逻辑,包括移动和发射子弹功能。最后,设置服务器端逻辑,处理客户端连接和断开。本文帮助读者掌握构建Unity多人对战平台的核心知识,为进一步开发打下基础。
156 0
|
4月前
|
开发者 图形学 C#
揭秘游戏沉浸感的秘密武器:深度解析Unity中的音频设计技巧,从背景音乐到动态音效,全面提升你的游戏氛围艺术——附实战代码示例与应用场景指导
【8月更文挑战第31天】音频设计在游戏开发中至关重要,不仅能增强沉浸感,还能传递信息,构建氛围。Unity作为跨平台游戏引擎,提供了丰富的音频处理功能,助力开发者轻松实现复杂音效。本文将探讨如何利用Unity的音频设计提升游戏氛围,并通过具体示例代码展示实现过程。例如,在恐怖游戏中,阴森的背景音乐和突然的脚步声能增加紧张感;在休闲游戏中,轻快的旋律则让玩家感到愉悦。
125 0