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

目录
相关文章
|
小程序 PHP 图形学
热门小游戏源码(Python+PHP)下载-微信小程序游戏源码Unity发实战指南​
本文详解如何结合Python、PHP与Unity开发并部署小游戏至微信小程序。涵盖技术选型、Pygame实战、PHP后端对接、Unity转换适配及性能优化,提供从原型到发布的完整指南,助力开发者快速上手并发布游戏。
|
开发工具 Android开发 开发者
用Flet打造跨平台文本编辑器:从零到一的Python实战指南
本文介绍如何使用Flet框架开发一个跨平台、自动保存的文本编辑器,代码不足200行,兼具现代化UI与高效开发体验。
1501 0
|
前端开发
业余时间开发了个海报编辑器
为了满足撰写博客或录制教程视频时对高质量海报的需求,我利用业余时间开发了一款海报编辑器。第一版功能简单,支持固定尺寸、黑底白字的标题。后来经过优化,增加了背景图、模糊效果、文字样式调整等功能,使海报更具吸引力。目前该编辑器已上线,欢迎大家试用并反馈。[访问海报编辑器](https://tool.share888.top/#/poster)
429 6
业余时间开发了个海报编辑器
|
图形学 开发者
Unity编辑器脚本(添加/删除)碰撞盒
这段代码提供了两个Unity编辑器工具,用于批量处理模型的碰撞盒。一是“一键添加所有碰撞盒”,通过选择模型的父物体,自动为其子物体添加`MeshCollider`。二是“一键清理所有Collider碰撞盒”,同样选择父物体后,递归删除子物体上的`BoxCollider`组件。两者均通过Unity的菜单项实现便捷操作,方便开发者快速调整场景中的物理属性。
|
缓存 API 开发工具
有关Unity使用Rider编辑器无法弹出代码提示的有效解决方法
【11月更文挑战第13天】在 Unity 中使用 Rider 编辑器时,若遇到代码提示无法弹出的问题,可以通过检查 Rider 设置(如自动补全选项、Unity 插件安装、索引设置)、Unity 项目设置(如解决方案正确关联、脚本导入设置)以及环境和依赖关系(如 .NET SDK 版本兼容性、Unity 和 Rider 版本兼容性)等方面进行排查和解决。
2795 5
|
运维 Java Linux
【运维基础知识】掌握VI编辑器:提升你的Java开发效率
本文详细介绍了VI编辑器的常用命令,包括模式切换、文本编辑、搜索替换及退出操作,帮助Java开发者提高在Linux环境下的编码效率。掌握这些命令,将使你在开发过程中更加得心应手。
315 2
|
图形学 开发者 存储
超越基础教程:深度拆解Unity地形编辑器的每一个隐藏角落,让你的游戏世界既浩瀚无垠又细节满满——从新手到高手的全面技巧升级秘籍
【8月更文挑战第31天】Unity地形编辑器是游戏开发中的重要工具,可快速创建复杂多变的游戏环境。本文通过比较不同地形编辑技术,详细介绍如何利用其功能构建广阔且精细的游戏世界,并提供具体示例代码,展示从基础地形绘制到植被与纹理添加的全过程。通过学习这些技巧,开发者能显著提升游戏画面质量和玩家体验。
1681 3
|
图形学 开发者 搜索推荐
Unity Asset Store资源大解密:自制与现成素材的优劣对比分析,教你如何巧用海量资产加速游戏开发进度
【8月更文挑战第31天】游戏开发充满挑战,尤其对独立开发者或小团队而言。Unity Asset Store 提供了丰富的资源库,涵盖美术、模板、音频和脚本等,能显著加快开发进度。自制资源虽具个性化,但耗时长且需专业技能;而 Asset Store 的资源经官方审核,质量可靠,可大幅缩短开发周期,使开发者更专注于核心玩法。然而,使用第三方资源需注意版权问题,且可能需调整以适应特定需求。总体而言,合理利用 Asset Store 能显著提升开发效率和项目质量。
774 1
|
开发者 图形学 API
从零起步,深度揭秘:运用Unity引擎及网络编程技术,一步步搭建属于你的实时多人在线对战游戏平台——详尽指南与实战代码解析,带你轻松掌握网络化游戏开发的核心要领与最佳实践路径
【8月更文挑战第31天】构建实时多人对战平台是技术与创意的结合。本文使用成熟的Unity游戏开发引擎,从零开始指导读者搭建简单的实时对战平台。内容涵盖网络架构设计、Unity网络API应用及客户端与服务器通信。首先,创建新项目并选择适合多人游戏的模板,使用推荐的网络传输层。接着,定义基本玩法,如2D多人射击游戏,创建角色预制件并添加Rigidbody2D组件。然后,引入网络身份组件以同步对象状态。通过示例代码展示玩家控制逻辑,包括移动和发射子弹功能。最后,设置服务器端逻辑,处理客户端连接和断开。本文帮助读者掌握构建Unity多人对战平台的核心知识,为进一步开发打下基础。
1325 0
|
开发者 图形学 开发工具
Unity编辑器神级扩展攻略:从批量操作到定制Inspector界面,手把手教你编写高效开发工具,解锁编辑器隐藏潜能
【8月更文挑战第31天】Unity是一款强大的游戏开发引擎,支持多平台发布与高度可定制的编辑器环境。通过自定义编辑器工具,开发者能显著提升工作效率。本文介绍如何使用C#脚本扩展Unity编辑器功能,包括批量调整游戏对象位置、创建自定义Inspector界面及项目统计窗口等实用工具,并提供具体示例代码。理解并应用这些技巧,可大幅优化开发流程,提高生产力。
1705 1

热门文章

最新文章