当前位置:   article > 正文

【Unity Editor】使用AssetDatabase.GetDependencies查看/搜索所有资源引用详情(升级版)

assetdatabase.getdependencies

实现功能:

1. 查找引用方

查看某个文件引用的所有资源

 2. 查找被引用方

查看某个资源的被引用关系

 

3. 引用关系列表

查看所有资源的引用关系,可以按名字搜索,查看引用详情

4. 被引用关系列表

查看所有资源的被引用关系,按文件后缀名分类,可以按名字搜索,查看被引用详情

 5. 直接/递归引用

可以选择只查看直接引用(直接依赖关系),也可以查看递归引用(间接依赖关系)

功能代码:

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEditor;
  5. using System.IO;
  6. using System.Linq;
  7. public class AssetDependenciesTool : EditorWindow
  8. {
  9. //--- 固定数据 ---
  10. private readonly Color listItemColor = new Color(0.9f,0.9f,0.9f,1);
  11. private readonly string[] displayBarArray = new string[] { "查找引用方","查找被引用方","引用关系","被引用关系" };
  12. //--- 初始数据 ---
  13. //Prefab/Scene的引用资源
  14. private Dictionary<string,string[]> prefabDependDic = new Dictionary<string,string[]>();
  15. //被Prefab/Scene引用的资源
  16. private Dictionary<string,string[]> assetRelatedDic = new Dictionary<string,string[]>();
  17. //Prefab/Scene的名字
  18. private string[] prefabNameArray;
  19. //资源类型、名字
  20. private string[] assetExtentArray;
  21. private Dictionary<string,string[]> assetExtentNameDic;
  22. //--- 变化数据 ---
  23. //====================
  24. private static bool recursiveFind = false;
  25. [MenuItem("MyTools/资源引用关系/查看直接引用",priority = EditorCommon.assetDependPriority)]
  26. public static void FindAssetsDependencies1()
  27. {
  28. recursiveFind = false;
  29. GetWindow<AssetDependenciesTool>(true,"查找资源引用关系-直接引用");
  30. }
  31. [MenuItem("MyTools/资源引用关系/查看递归引用",priority = EditorCommon.assetDependPriority)]
  32. public static void FindAssetsDependencies2()
  33. {
  34. recursiveFind = true;
  35. GetWindow<AssetDependenciesTool>(true,"查找资源引用关系-递归引用");
  36. }
  37. private void OnEnable()
  38. {
  39. FindAllPrefabDependencies(ref prefabDependDic,ref assetRelatedDic,out prefabNameArray,out assetExtentArray,out assetExtentNameDic);
  40. }
  41. private int displayIndex = 0;
  42. private void OnGUI()
  43. {
  44. EditorGUILayout.BeginVertical("box");
  45. EditorGUILayout.LabelField("资源引用方数量 : " + prefabDependDic.Count);
  46. EditorGUILayout.LabelField("资源被引用方数量 : " + assetRelatedDic.Count);
  47. EditorGUILayout.LabelField("所统计的资源引用关系,不包含代码动态加载");
  48. EditorGUILayout.EndVertical();
  49. displayIndex = GUILayout.Toolbar(displayIndex,displayBarArray);
  50. switch(displayIndex)
  51. {
  52. case 0:
  53. OnGUI_FindPrefab();
  54. break;
  55. case 1:
  56. OnGUI_FindAssets();
  57. break;
  58. case 2:
  59. OnGUI_AllPrefab();
  60. break;
  61. case 3:
  62. OnGUI_AllAssets();
  63. break;
  64. default:
  65. break;
  66. }
  67. }
  68. //查找某个Prefab/Scene引用的所有资源
  69. Object selectPrefabObject;
  70. PrefabDependItem selectPrefabDependItem;
  71. private void OnGUI_FindPrefab()
  72. {
  73. EditorGUILayout.BeginHorizontal();
  74. selectPrefabObject = EditorGUILayout.ObjectField("引用资源:",selectPrefabObject,typeof(Object),true,GUILayout.Width(600));
  75. if(GUILayout.Button("分析引用详情",GUILayout.Width(100)))
  76. {
  77. if(selectPrefabObject != null)
  78. {
  79. string prefabPath = AssetDatabase.GetAssetPath(selectPrefabObject);
  80. prefabDependDic.TryGetValue(prefabPath,out var depPathArray);
  81. selectPrefabDependItem = new PrefabDependItem(prefabPath,depPathArray);
  82. }
  83. }
  84. EditorGUILayout.EndHorizontal();
  85. OnGUI_PrefabDetial(ref selectPrefabDependItem);
  86. }
  87. //查找某个资源被哪些Prefab/Scene引用
  88. Object selectAssetObject;
  89. AssetRelatedItem selectAssetRelatedItem;
  90. private void OnGUI_FindAssets()
  91. {
  92. EditorGUILayout.BeginHorizontal();
  93. selectAssetObject = EditorGUILayout.ObjectField("被引用资源:",selectAssetObject,typeof(Object),true,GUILayout.Width(600));
  94. if(GUILayout.Button("分析被引用详情",GUILayout.Width(100)))
  95. {
  96. if(selectAssetObject != null)
  97. {
  98. string assetPath = AssetDatabase.GetAssetPath(selectAssetObject);
  99. assetRelatedDic.TryGetValue(assetPath,out var depPathArray);
  100. selectAssetRelatedItem = new AssetRelatedItem(assetPath,depPathArray);
  101. }
  102. }
  103. EditorGUILayout.EndHorizontal();
  104. OnGUI_AssetDetial(ref selectAssetRelatedItem);
  105. }
  106. int showPageIndex1 = 0;
  107. string searchPrefabNameSign;
  108. bool isSearchPrefabName;
  109. Vector2 scrollViewPos03;
  110. Vector2 scrollViewPos031;
  111. PrefabDependItem previewPrefabDependItem;
  112. private void OnGUI_AllPrefab()
  113. {
  114. EditorGUILayout.BeginHorizontal("box");
  115. EditorGUILayout.LabelField("搜索关键字(仅搜索当前页!!!):",GUILayout.Width(200));
  116. searchPrefabNameSign = EditorGUILayout.TextField(searchPrefabNameSign,GUILayout.Width(200));
  117. isSearchPrefabName = !string.IsNullOrEmpty(searchPrefabNameSign);
  118. EditorGUILayout.EndHorizontal();
  119. scrollViewPos03 = EditorGUILayout.BeginScrollView(scrollViewPos03);
  120. for(int i = showPageIndex1; i < showPageIndex1 + 100; i++)
  121. {
  122. if(i >= prefabNameArray.Length)
  123. break;
  124. string prefabPath = prefabNameArray[i];
  125. if(isSearchPrefabName && !prefabPath.Contains(searchPrefabNameSign))
  126. continue;
  127. EditorGUILayout.BeginHorizontal("box");
  128. EditorGUILayout.LabelField($"{i}. 资源文件名: {prefabPath}");
  129. EditorGUILayout.LabelField($"引用数量: { prefabDependDic[prefabPath].Length}",GUILayout.Width(200));
  130. if(GUILayout.Button("查看引用详情",GUILayout.Width(100)))
  131. {
  132. prefabDependDic.TryGetValue(prefabPath,out var depPathArray);
  133. previewPrefabDependItem = new PrefabDependItem(prefabPath,depPathArray);
  134. }
  135. EditorGUILayout.EndHorizontal();
  136. }
  137. EditorGUILayout.EndScrollView();
  138. OnGUI_PrefabDetial(ref previewPrefabDependItem);
  139. EditorGUILayout.BeginHorizontal();
  140. if(GUILayout.Button("首页",GUILayout.Width(100)))
  141. {
  142. showPageIndex1 = 0;
  143. }
  144. if(GUILayout.Button("上一页",GUILayout.Width(100)))
  145. {
  146. showPageIndex1 -= 100;
  147. if(showPageIndex1 < 0)
  148. showPageIndex1 = 0;
  149. }
  150. EditorGUILayout.LabelField($"{showPageIndex1}/{prefabNameArray.Length}",GUILayout.Width(100));
  151. if(GUILayout.Button("下一页",GUILayout.Width(100)))
  152. {
  153. if((showPageIndex1 + 100) < prefabNameArray.Length)
  154. showPageIndex1 += 100;
  155. }
  156. if(GUILayout.Button("尾页",GUILayout.Width(100)))
  157. {
  158. showPageIndex1 = prefabNameArray.Length / 100 * 100;
  159. }
  160. EditorGUILayout.EndHorizontal();
  161. }
  162. int showPageIndex2 = 0;
  163. int selectExtentIndex = -1;
  164. string searchAssetNameSign;
  165. bool isSearchAssetName;
  166. Vector2 scrollViewPos04;
  167. Vector2 scrollViewPos041;
  168. AssetRelatedItem previewAssetRelatedItem;
  169. private void OnGUI_AllAssets()
  170. {
  171. selectExtentIndex = EditorGUILayout.Popup("查找资源类型 : ",selectExtentIndex,assetExtentArray,GUILayout.MaxWidth(300));
  172. if(selectExtentIndex < 0 || selectExtentIndex >= assetExtentArray.Length)
  173. return;
  174. EditorGUILayout.BeginHorizontal("box");
  175. EditorGUILayout.LabelField("搜索关键字(仅搜索当前页!!!):",GUILayout.Width(200));
  176. searchAssetNameSign = EditorGUILayout.TextField(searchAssetNameSign,GUILayout.Width(200));
  177. isSearchAssetName = !string.IsNullOrEmpty(searchAssetNameSign);
  178. EditorGUILayout.EndHorizontal();
  179. scrollViewPos04 = EditorGUILayout.BeginScrollView(scrollViewPos04);
  180. var nameArray = assetExtentNameDic[assetExtentArray[selectExtentIndex]];
  181. for(int i = showPageIndex2; i < showPageIndex2 + 100; i++)
  182. {
  183. if(i >= nameArray.Length)
  184. break;
  185. string assetPath = nameArray[i];
  186. if(isSearchAssetName && !assetPath.Contains(searchAssetNameSign))
  187. continue;
  188. EditorGUILayout.BeginHorizontal("box");
  189. EditorGUILayout.LabelField($"{i}. 资源文件名: {assetPath}");
  190. EditorGUILayout.LabelField($"被引用次数: { assetRelatedDic[assetPath].Length}",GUILayout.Width(200));
  191. if(GUILayout.Button("查看引用详情",GUILayout.Width(100)))
  192. {
  193. assetRelatedDic.TryGetValue(assetPath,out var depPathArray);
  194. previewAssetRelatedItem = new AssetRelatedItem(assetPath,depPathArray);
  195. }
  196. EditorGUILayout.EndHorizontal();
  197. }
  198. EditorGUILayout.EndScrollView();
  199. OnGUI_AssetDetial(ref previewAssetRelatedItem);
  200. EditorGUILayout.BeginHorizontal();
  201. if(GUILayout.Button("首页",GUILayout.Width(100)))
  202. {
  203. showPageIndex2 = 0;
  204. }
  205. if(GUILayout.Button("上一页",GUILayout.Width(100)))
  206. {
  207. showPageIndex2 -= 100;
  208. if(showPageIndex2 < 0)
  209. showPageIndex2 = 0;
  210. }
  211. EditorGUILayout.LabelField($"{showPageIndex2}/{nameArray.Length}",GUILayout.Width(100));
  212. if(GUILayout.Button("下一页",GUILayout.Width(100)))
  213. {
  214. if((showPageIndex2 + 100) < nameArray.Length)
  215. showPageIndex2 += 100;
  216. }
  217. if(GUILayout.Button("尾页",GUILayout.Width(100)))
  218. {
  219. showPageIndex2 = nameArray.Length / 100 * 100;
  220. }
  221. EditorGUILayout.EndHorizontal();
  222. }
  223. private void OnGUI_PrefabDetial(ref PrefabDependItem prefabDependItem)
  224. {
  225. EditorGUILayout.Space(5);
  226. if(prefabDependItem != null)
  227. {
  228. EditorGUILayout.BeginVertical("box");
  229. if(GUILayout.Button("关闭引用详情",GUILayout.Width(100)))
  230. {
  231. prefabDependItem = null;
  232. }
  233. EditorGUILayout.Space(2);
  234. scrollViewPos031 = EditorGUILayout.BeginScrollView(scrollViewPos031,GUILayout.Height(500));
  235. EditorGUILayout.ObjectField("引用方:",prefabDependItem.prefabObject,typeof(Object),true,GUILayout.Width(400));
  236. EditorGUILayout.Space(5);
  237. EditorGUILayout.LabelField("被引用方列表:");
  238. for(int i = 0; i < prefabDependItem.dependObjectArray.Length; i++)
  239. {
  240. EditorGUILayout.Space(2);
  241. EditorGUILayout.ObjectField($"({i}) 被引用方:",prefabDependItem.dependObjectArray[i],typeof(Object),true,GUILayout.Width(400));
  242. }
  243. EditorGUILayout.EndScrollView();
  244. EditorGUILayout.EndVertical();
  245. }
  246. EditorGUILayout.Space(5);
  247. }
  248. private void OnGUI_AssetDetial(ref AssetRelatedItem assetRelatedItem)
  249. {
  250. EditorGUILayout.Space(5);
  251. if(assetRelatedItem != null)
  252. {
  253. EditorGUILayout.BeginVertical("box");
  254. if(GUILayout.Button("关闭引用详情",GUILayout.Width(100)))
  255. {
  256. assetRelatedItem = null;
  257. }
  258. EditorGUILayout.Space(2);
  259. scrollViewPos041 = EditorGUILayout.BeginScrollView(scrollViewPos041,GUILayout.Height(500));
  260. EditorGUILayout.ObjectField("被引用方:",assetRelatedItem.assetObject,typeof(Object),true,GUILayout.Width(400));
  261. EditorGUILayout.Space(5);
  262. EditorGUILayout.LabelField("引用方列表:");
  263. for(int i = 0; i < assetRelatedItem.relatedObjectArray.Length; i++)
  264. {
  265. EditorGUILayout.Space(2);
  266. EditorGUILayout.ObjectField($"({i}) 引用方:",assetRelatedItem.relatedObjectArray[i],typeof(Object),true,GUILayout.Width(400));
  267. }
  268. EditorGUILayout.EndScrollView();
  269. EditorGUILayout.EndVertical();
  270. }
  271. EditorGUILayout.Space(5);
  272. }
  273. //==========
  274. //准备初始数据
  275. private void FindAllPrefabDependencies(ref Dictionary<string,string[]> _prefabDependDic,ref Dictionary<string,string[]> _assetRelatedDic,out string[] _prefabNameArray,out string[] _assetExtentArray,out Dictionary<string,string[]> _assetExtentNameDic)
  276. {
  277. EditorUtility.DisplayProgressBar("读取项目所有资源","读取所有资源",0);
  278. //string[] allFilePathArray = Directory.GetFiles(Application.dataPath,"*.*",SearchOption.AllDirectories);
  279. string[] allFilePathArray = AssetDatabase.GetAllAssetPaths();
  280. EditorUtility.ClearProgressBar();
  281. //----------
  282. _prefabDependDic.Clear();
  283. EditorUtility.DisplayProgressBar("获取资源引用关系","遍历所有资源",0);
  284. for(int i = 0; i < allFilePathArray.Length; i++)
  285. {
  286. if(i % 100 == 0)
  287. {
  288. //间隔刷新UI提示框
  289. if(EditorUtility.DisplayCancelableProgressBar("获取资源引用关系",$"遍历所有文件 : {i}/{allFilePathArray.Length}",(float)i / allFilePathArray.Length))
  290. break;
  291. }
  292. _prefabDependDic[allFilePathArray[i]] = AssetDatabase.GetDependencies(allFilePathArray[i],recursiveFind);
  293. }
  294. EditorUtility.DisplayProgressBar("读取项目所有资源","资源引用排序",0);
  295. _prefabDependDic = _prefabDependDic.OrderBy(item => item.Value.Length).ToDictionary(item => item.Key,item => item.Value);
  296. EditorUtility.ClearProgressBar();
  297. //----------
  298. EditorUtility.DisplayProgressBar("反向解析引用关系","遍历所有资源",0);
  299. Dictionary<string,List<string>> tempAssetDic = new Dictionary<string,List<string>>();
  300. for(int i = 0; i < allFilePathArray.Length; i++)
  301. {
  302. if(i % 200 == 0)
  303. {
  304. //间隔刷新UI提示框
  305. if(EditorUtility.DisplayCancelableProgressBar("反向解析引用关系",$"遍历所有文件 : {i}/{allFilePathArray.Length}",(float)i / allFilePathArray.Length))
  306. break;
  307. }
  308. if(!tempAssetDic.TryGetValue(allFilePathArray[i],out var relList))
  309. {
  310. relList = tempAssetDic[allFilePathArray[i]] = new List<string>();
  311. }
  312. foreach(var item in _prefabDependDic)
  313. {
  314. if(item.Value.Contains(allFilePathArray[i]))
  315. {
  316. relList.Add(item.Key);
  317. }
  318. }
  319. }
  320. EditorUtility.DisplayProgressBar("反向解析引用关系","资源引用排序",0);
  321. _assetRelatedDic.Clear();
  322. foreach(var item in tempAssetDic)
  323. {
  324. _assetRelatedDic[item.Key] = item.Value.ToArray();
  325. }
  326. _assetRelatedDic = _assetRelatedDic.OrderBy(item => item.Value.Length).ToDictionary(item => item.Key,item => item.Value);
  327. EditorUtility.ClearProgressBar();
  328. //----------
  329. EditorUtility.DisplayProgressBar("读取引用资源类型","获取所有引用文件类型",0);
  330. var tempExtentDic = new Dictionary<string,List<string>>();
  331. foreach(var assetName in _assetRelatedDic.Keys)
  332. {
  333. string assetExtent = Path.GetExtension(assetName);
  334. if(!tempExtentDic.TryGetValue(assetExtent,out var nameList))
  335. {
  336. nameList = tempExtentDic[assetExtent] = new List<string>();
  337. }
  338. nameList.Add(assetName);
  339. }
  340. _assetExtentNameDic = new Dictionary<string,string[]>(tempExtentDic.Count);
  341. foreach(var item in tempExtentDic)
  342. {
  343. _assetExtentNameDic[item.Key] = item.Value.ToArray();
  344. }
  345. _assetExtentArray = tempExtentDic.Keys.ToArray();
  346. _prefabNameArray = _prefabDependDic.Keys.ToArray();
  347. EditorUtility.ClearProgressBar();
  348. }
  349. //==========
  350. //查找某个Prefab/Scene引用的所有资源
  351. public class PrefabDependItem
  352. {
  353. private string prefabPath;
  354. private string[] dependPathArray;
  355. public Object prefabObject;
  356. public Object[] dependObjectArray;
  357. public PrefabDependItem(string _prefabPath,string[] _dependPathArray)
  358. {
  359. prefabPath = _prefabPath;
  360. dependPathArray = _dependPathArray;
  361. LoadDependObjects();
  362. }
  363. private void LoadDependObjects()
  364. {
  365. prefabObject = AssetDatabase.LoadAssetAtPath<Object>(prefabPath);
  366. if(dependPathArray == null || dependPathArray.Length == 0)
  367. {
  368. dependObjectArray = new Object[0];
  369. return;
  370. }
  371. dependObjectArray = new Object[dependPathArray.Length];
  372. for(int i = 0; i < dependPathArray.Length; i++)
  373. {
  374. if(EditorUtility.DisplayCancelableProgressBar("加载引用该资源的Prefab|Scene",$"加载进度 : {i}/{dependPathArray.Length}",(float)i / dependPathArray.Length))
  375. {
  376. EditorUtility.ClearProgressBar();
  377. return;
  378. }
  379. Object tempObj = AssetDatabase.LoadAssetAtPath<Object>(dependPathArray[i]);
  380. dependObjectArray[i] = tempObj;
  381. }
  382. EditorUtility.ClearProgressBar();
  383. }
  384. }
  385. //查找某个资源被哪些Prefab/Scene引用
  386. public class AssetRelatedItem
  387. {
  388. private string assetPath;
  389. private string[] relatedPathArray;
  390. public Object assetObject;
  391. public Object[] relatedObjectArray;
  392. public AssetRelatedItem(string _assetPath,string[] _relatedPathArray)
  393. {
  394. assetPath = _assetPath;
  395. relatedPathArray = _relatedPathArray;
  396. LoadRelatedObjects();
  397. }
  398. private void LoadRelatedObjects()
  399. {
  400. assetObject = AssetDatabase.LoadAssetAtPath<Object>(assetPath);
  401. if(relatedPathArray == null || relatedPathArray.Length == 0)
  402. {
  403. relatedObjectArray = new Object[0];
  404. return;
  405. }
  406. relatedObjectArray = new Object[relatedPathArray.Length];
  407. for(int i = 0; i < relatedPathArray.Length; i++)
  408. {
  409. if(EditorUtility.DisplayCancelableProgressBar("加载引用该资源的Prefab|Scene",$"加载进度 : {i}/{relatedPathArray.Length}",(float)i / relatedPathArray.Length))
  410. {
  411. EditorUtility.ClearProgressBar();
  412. return;
  413. }
  414. Object tempObj = AssetDatabase.LoadAssetAtPath<Object>(relatedPathArray[i]);
  415. relatedObjectArray[i] = tempObj;
  416. }
  417. EditorUtility.ClearProgressBar();
  418. }
  419. }
  420. }

旧版实现: 

【UnityEditor】使用AssetDatabase.GetDependencies分析资源引用关系

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/661802
推荐阅读
相关标签
  

闽ICP备14008679号