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

目录
打赏
0
0
1
1
8
分享
相关文章
Unity开发中使用UnityWebRequest从HTTP服务器下载资源。
总之,UnityWebRequest就是游戏开发者手中的万能钓鱼竿,既可以获取文本数据,也能钓上图片资源,甚至是那声音的涟漪。使用UnityWebRequest的时候,你需要精心准备,比如确定URL、配置请求类型和头信息;发起请求;巧妙处理钓获的数据;还需要机智面对网络波澜,处理各种可能出现的错误。按照这样的过程,数据的钓取将会是一次既轻松愉快也效率高效的编程钓鱼之旅。
58 18
Unity编辑器脚本(添加/删除)碰撞盒
这段代码提供了两个Unity编辑器工具,用于批量处理模型的碰撞盒。一是“一键添加所有碰撞盒”,通过选择模型的父物体,自动为其子物体添加`MeshCollider`。二是“一键清理所有Collider碰撞盒”,同样选择父物体后,递归删除子物体上的`BoxCollider`组件。两者均通过Unity的菜单项实现便捷操作,方便开发者快速调整场景中的物理属性。
|
8月前
|
业余时间开发了个海报编辑器
为了满足撰写博客或录制教程视频时对高质量海报的需求,我利用业余时间开发了一款海报编辑器。第一版功能简单,支持固定尺寸、黑底白字的标题。后来经过优化,增加了背景图、模糊效果、文字样式调整等功能,使海报更具吸引力。目前该编辑器已上线,欢迎大家试用并反馈。[访问海报编辑器](https://tool.share888.top/#/poster)
141 6
业余时间开发了个海报编辑器
有关Unity使用Rider编辑器无法弹出代码提示的有效解决方法
【11月更文挑战第13天】在 Unity 中使用 Rider 编辑器时,若遇到代码提示无法弹出的问题,可以通过检查 Rider 设置(如自动补全选项、Unity 插件安装、索引设置)、Unity 项目设置(如解决方案正确关联、脚本导入设置)以及环境和依赖关系(如 .NET SDK 版本兼容性、Unity 和 Rider 版本兼容性)等方面进行排查和解决。
1241 5
|
9月前
|
【运维基础知识】掌握VI编辑器:提升你的Java开发效率
本文详细介绍了VI编辑器的常用命令,包括模式切换、文本编辑、搜索替换及退出操作,帮助Java开发者提高在Linux环境下的编码效率。掌握这些命令,将使你在开发过程中更加得心应手。
106 2
超越基础教程:深度拆解Unity地形编辑器的每一个隐藏角落,让你的游戏世界既浩瀚无垠又细节满满——从新手到高手的全面技巧升级秘籍
【8月更文挑战第31天】Unity地形编辑器是游戏开发中的重要工具,可快速创建复杂多变的游戏环境。本文通过比较不同地形编辑技术,详细介绍如何利用其功能构建广阔且精细的游戏世界,并提供具体示例代码,展示从基础地形绘制到植被与纹理添加的全过程。通过学习这些技巧,开发者能显著提升游戏画面质量和玩家体验。
614 3
|
10月前
|
Unity插件开发全攻略:从零起步教你用C++扩展游戏功能,解锁Unity新玩法的详细步骤与实战技巧大公开
【8月更文挑战第31天】Unity 是一款功能强大的游戏开发引擎,支持多平台发布并拥有丰富的插件生态系统。本文介绍 Unity 插件开发基础,帮助读者从零开始编写自定义插件以扩展其功能。插件通常用 C++ 编写,通过 Mono C# 运行时调用,需在不同平台上编译。文中详细讲解了开发环境搭建、简单插件编写及在 Unity 中调用的方法,包括创建 C# 封装脚本和处理跨平台问题,助力开发者提升游戏开发效率。
941 0
从Unity开发到移动平台制胜攻略:全面解析iOS与Android应用发布流程,助你轻松掌握跨平台发布技巧,打造爆款手游不是梦——性能优化、广告集成与内购设置全包含
【8月更文挑战第31天】本书详细介绍了如何在Unity中设置项目以适应移动设备,涵盖性能优化、集成广告及内购功能等关键步骤。通过具体示例和代码片段,指导读者完成iOS和Android应用的打包与发布,确保应用顺利上线并获得成功。无论是性能调整还是平台特定的操作,本书均提供了全面的解决方案。
354 0
从零起步,深度揭秘:运用Unity引擎及网络编程技术,一步步搭建属于你的实时多人在线对战游戏平台——详尽指南与实战代码解析,带你轻松掌握网络化游戏开发的核心要领与最佳实践路径
【8月更文挑战第31天】构建实时多人对战平台是技术与创意的结合。本文使用成熟的Unity游戏开发引擎,从零开始指导读者搭建简单的实时对战平台。内容涵盖网络架构设计、Unity网络API应用及客户端与服务器通信。首先,创建新项目并选择适合多人游戏的模板,使用推荐的网络传输层。接着,定义基本玩法,如2D多人射击游戏,创建角色预制件并添加Rigidbody2D组件。然后,引入网络身份组件以同步对象状态。通过示例代码展示玩家控制逻辑,包括移动和发射子弹功能。最后,设置服务器端逻辑,处理客户端连接和断开。本文帮助读者掌握构建Unity多人对战平台的核心知识,为进一步开发打下基础。
440 0
揭秘游戏沉浸感的秘密武器:深度解析Unity中的音频设计技巧,从背景音乐到动态音效,全面提升你的游戏氛围艺术——附实战代码示例与应用场景指导
【8月更文挑战第31天】音频设计在游戏开发中至关重要,不仅能增强沉浸感,还能传递信息,构建氛围。Unity作为跨平台游戏引擎,提供了丰富的音频处理功能,助力开发者轻松实现复杂音效。本文将探讨如何利用Unity的音频设计提升游戏氛围,并通过具体示例代码展示实现过程。例如,在恐怖游戏中,阴森的背景音乐和突然的脚步声能增加紧张感;在休闲游戏中,轻快的旋律则让玩家感到愉悦。
442 0
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问