描述
项目开发时候总是要改资源替换资源什么的,有的资源可能会残留,看到了想删掉又怕在哪里被引用导致误删,手动检查又太麻烦。
花了点时间解决了问题,主要是通过接口AssetDatabase.GetDependencies 获取相关资源列表。
功能一
右键菜单选择资源,找到依赖资源
图例
功能二
批量检查某一图集的未被引用资源用于筛选,还能标记为是否被代码使用
图例
代码
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;
using System.Linq;
public class ShowAllNotUseResourceCheck : EditorWindow
{
enum UIType
{
NotUseRes = 1,
FindReferences = 2,
}
[MenuItem("Tools/删除资源工具", false, 1000)]
static public void OpenPrefabTool()
{
uitype = UIType.NotUseRes;
ShowAllNotUseResourceCheck checkWin = (ShowAllNotUseResourceCheck)EditorWindow.GetWindow<ShowAllNotUseResourceCheck>(false, "checkWin", true);
checkWin.autoRepaintOnSceneChange = true;
LoadConfig();
checkWin.Show();
}
[MenuItem("Assets/Find References", false)]
static public void FindResReferences()
{
uitype = UIType.FindReferences;
StarFind();
}
static UIType uitype = UIType.NotUseRes;
static Dictionary<string, bool> mapReourceUsedOther = new Dictionary<string, bool>(); //资源是否被代码引用
static private List<string> checkType = new List<string>(); //检测的类型
static private List<string> allResource = new List<string>(); //所有使用资源
static private List<string> notUseReource = new List<string>(); //没有使用过的资源
static private string searchModule = "bag"; //需要搜索的模块
Vector2 scrollPos = Vector2.zero;
static private List<string> findPrefabs = new List<string>(); //被引用的预制体
private void StartCheck()
{
List<string> withoutExtensions = new List<string>() { ".prefab" };
string[] files = Directory.GetFiles(Application.dataPath + "/LuaFramework/AssetBundleRes/ui/", "*.*", SearchOption.AllDirectories)
.Where(s => withoutExtensions.Contains(Path.GetExtension(s).ToLower())).ToArray();
List<string> withoutExtensions2 = new List<string>() { ".png", ".jpg" };
//所有project 里面的资源
string[] UIReource = Directory.GetFiles(Application.dataPath + "/LuaFramework/AssetBundleRes/ui/" + searchModule, "*.*", SearchOption.AllDirectories)
.Where(s => withoutExtensions2.Contains(Path.GetExtension(s).ToLower())).ToArray();
for (int i = 0; i < UIReource.Length; i++)
{
UIReource[i] = UIReource[i].Replace("\\", "/");
int index = UIReource[i].IndexOf("Assets");
UIReource[i] = UIReource[i].Substring(index);
}
float count = 0;
foreach (string file in files)
{
count++;
EditorUtility.DisplayProgressBar("Processing...", "检索中....", count / files.Length);
string strFile = file.Substring(file.IndexOf("Asset")).Replace('\\', '/');
string[] dependenciesFiles = AssetDatabase.GetDependencies(strFile, false);
foreach (string depFile in dependenciesFiles)
{
bool isNeedShow = false;
foreach (string type in checkType)
{
//存在设置类型 需要显示
if (depFile.IndexOf(type) > -1)
{
isNeedShow = true;
break;
}
}
if (isNeedShow == false)
{
continue;
}
allResource.Add(depFile);
}
}
EditorUtility.ClearProgressBar();
for (int i = 0; i < UIReource.Length; i++)
{
bool isUse = false;
foreach (string usePath in allResource)
{
if (UIReource[i] == usePath)
{
isUse = true;
break;
}
}
if (isUse == false)
{
notUseReource.Add(UIReource[i]);
}
}
}
static void StarFind()
{
findPrefabs.Clear();
if (Selection.activeObject == null)
{
EditorUtility.DisplayDialog("提示", "没有选中物体", "确定");
return;
}
string path = AssetDatabase.GetAssetPath(Selection.activeObject);
if (string.IsNullOrEmpty(path))
{
EditorUtility.DisplayDialog("提示", "没有选中物体", "确定");
return;
}
List<string> withoutExtensions = new List<string>() { ".prefab" };
string[] files = Directory.GetFiles(Application.dataPath + "/LuaFramework/AssetBundleRes/ui/", "*.*", SearchOption.AllDirectories)
.Where(s => withoutExtensions.Contains(Path.GetExtension(s).ToLower())).ToArray();
float count = 0;
foreach (string file in files)
{
count++;
EditorUtility.DisplayProgressBar("Processing...", "检索中....", count / files.Length);
string strFile = file.Substring(file.IndexOf("Asset")).Replace('\\', '/');
string[] dependenciesFiles = AssetDatabase.GetDependencies(strFile, false);
foreach (string depFile in dependenciesFiles)
{
if (path == depFile)
{
findPrefabs.Add(strFile);
}
}
}
EditorUtility.ClearProgressBar();
if (findPrefabs.Count == 0)
{
EditorUtility.DisplayDialog("搜索结果", "没有找到任何预制体引用", "确定");
}
else
{
EditorUtility.DisplayDialog("搜索结果", "有" + findPrefabs.Count + "个预制体引用了该素材", "确定");
ShowAllNotUseResourceCheck checkWin = (ShowAllNotUseResourceCheck)EditorWindow.GetWindow<ShowAllNotUseResourceCheck>(false, "checkWin", true);
checkWin.autoRepaintOnSceneChange = true;
checkWin.Show();
}
}
void OnGUI()
{
if (uitype == UIType.NotUseRes)
{
OnNotUseResGUI();
}
else
{
OnFindReferencesGUI();
}
}
void OnNotUseResGUI()
{
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("列出所有未使用过的图片", GUILayout.Width(200)))
{
allResource = new List<string>();
notUseReource = new List<string>();
checkType.Clear();
checkType.Add(".jpg");
checkType.Add(".png");
StartCheck();
}
EditorGUILayout.LabelField("搜索模块:", GUILayout.MaxWidth(45));
searchModule = EditorGUILayout.TextField(searchModule, GUILayout.MaxWidth(200));
EditorGUILayout.EndHorizontal();
scrollPos = EditorGUILayout.BeginScrollView(scrollPos);
foreach (var path in notUseReource)
{
EditorGUILayout.BeginHorizontal();
Texture2D t = (Texture2D)AssetDatabase.LoadAssetAtPath(path, typeof(Texture2D));
EditorGUILayout.ObjectField(t, typeof(Texture2D), false);
string module = "", name = "";
GetModuleAndName(path, out module, out name);
EditorGUILayout.TextField(module, GUILayout.MaxWidth(100));
EditorGUILayout.TextField(name, GUILayout.MaxWidth(200));
GUI.backgroundColor = Color.red;
if (GUILayout.Button("删除图片", GUILayout.Width(100)))
{
if (mapReourceUsedOther.ContainsKey(path))
{
mapReourceUsedOther.Remove(path);
SaveConfig();
}
File.Delete(path);
AssetDatabase.Refresh();
}
GUI.backgroundColor = Color.white;
if (mapReourceUsedOther.ContainsKey(path) && mapReourceUsedOther[path] == true)
{
if (GUILayout.Button("取消", GUILayout.Width(200)))
{
mapReourceUsedOther[path] = false;
SaveConfig();
AssetDatabase.Refresh();
}
}
else
{
if (GUILayout.Button("设置为代码使用", GUILayout.Width(200)))
{
if (mapReourceUsedOther.ContainsKey(path))
mapReourceUsedOther[path] = true;
else
mapReourceUsedOther.Add(path, true);
SaveConfig();
AssetDatabase.Refresh();
}
}
EditorGUILayout.EndHorizontal();
}
EditorGUILayout.EndScrollView();
}
void OnFindReferencesGUI()
{
scrollPos = EditorGUILayout.BeginScrollView(scrollPos);
foreach (var path in findPrefabs)
{
EditorGUILayout.BeginHorizontal();
GameObject t = (GameObject)AssetDatabase.LoadAssetAtPath(path, typeof(GameObject));
EditorGUILayout.ObjectField(t, typeof(GameObject), false);
GUI.backgroundColor = Color.white;
EditorGUILayout.EndHorizontal();
}
EditorGUILayout.EndScrollView();
}
void GetModuleAndName(string str, out string module, out string name)
{
string temp = "";
module = "";
name = "";
int index = str.IndexOf("ui");
temp = str.Substring(index);
temp = temp.Replace(".png", "");
string[] strs = temp.Split('/');
if (strs.Length >= 4)
{
module = strs[1];
name = strs[3];
}
}
static void SaveConfig()
{
string path = Application.dataPath + @"/Editor/NotUseResourceCheck/NotUseResConfig.txt";
StreamWriter sw;
FileInfo fi = new FileInfo(path);
sw = fi.CreateText();
foreach (var item in mapReourceUsedOther)
{
if (item.Value)
sw.WriteLine(item.Key);
}
sw.Close();
sw.Dispose();
}
static void LoadConfig()
{
mapReourceUsedOther.Clear();
string path = Application.dataPath + @"/Editor/NotUseResourceCheck/NotUseResConfig.txt";
StreamReader sr = null;
sr = File.OpenText(path);
if (sr != null)
{
string t_Line;
while ((t_Line = sr.ReadLine()) != null)
{
mapReourceUsedOther.Add(t_Line, true);
}
sr.Close();
sr.Dispose();
}
}
}
用法
文件命名ShowAllNotUseResourceCheck.cs,在Editor创建文件夹NotUseResourceCheck,放进去。
同目录下创建空白文本文档NotUseResConfig.txt
另
雨松大大也有一个解决方案,贴上来给大家参考
https://www.xuanyusong.com/?s=AssetDatabase.GetDependencies