using UnityEngine;
using UnityEditor;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Collections.Generic;
public class FindReferences : EditorWindow
{
[MenuItem("自定义工具/检查图片资源/替换通用资源")]
public static void ShowWindow()
{
EditorWindow.GetWindow(typeof(FindReferences), false, "替换通用资源");
}
private UnityEngine.Object OnCheckFolder; //检测模型文件夹目录
private UnityEngine.Object Pictures; //需要查找的图片
private List<Object> ViewObject = new List<Object>(); //使用过的View
private List<Object> PicturesObj_list = new List<Object>(); //重复的图片list
private Vector2 m_v2ScrollPos;
void OnGUI()
{
if (OnCheckFolder == null)
{
OnCheckFolder = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>("Assets/Game");
}
OnCheckFolder = EditorGUILayout.ObjectField("拖入搜索目录", OnCheckFolder, typeof(UnityEngine.Object), false);
Pictures = EditorGUILayout.ObjectField("拖入检查的图片", Pictures, typeof(UnityEngine.Object), false);
if (Pictures!= null && GUILayout.Button("开始查找", GUILayout.Width(80)))
{
string[] assetsPath = this.GetFlodString(OnCheckFolder);
this.GetMD5(assetsPath, Pictures);
if (PicturesObj_list.Count > 0)
{
this.Find(assetsPath, PicturesObj_list);
}
}
if (PicturesObj_list.Count > 0)
{
GUILayout.BeginHorizontal();
EditorGUILayout.LabelField("相同的图片", GUILayout.Width(60));
GUILayout.EndHorizontal();
for (var nIdx = 0; nIdx < PicturesObj_list.Count; nIdx++)
{
var obj = PicturesObj_list[nIdx];
GUILayout.BeginHorizontal();
EditorGUILayout.ObjectField(obj, typeof(GameObject), false, GUILayout.Width(170));
GUILayout.EndHorizontal();
}
}
if (ViewObject.Count > 0)
{
GUILayout.BeginHorizontal();
EditorGUILayout.LabelField("序号", GUILayout.Width(50));
EditorGUILayout.LabelField("使用过此类图片的预制体", GUILayout.Width(170));
GUILayout.EndHorizontal();
m_v2ScrollPos = EditorGUILayout.BeginScrollView(m_v2ScrollPos, GUILayout.Width(300), GUILayout.Height(300));
for (var nIdx = 0; nIdx < ViewObject.Count; nIdx++)
{
var obj = ViewObject[nIdx];
GUILayout.BeginHorizontal();
EditorGUILayout.LabelField((nIdx).ToString(), GUILayout.Width(50));
EditorGUILayout.ObjectField(obj, typeof(GameObject), false, GUILayout.Width(170));
GUILayout.EndHorizontal();
}
EditorGUILayout.EndScrollView();
}
}
/// <summary>
/// 查找使用过图片的预制体
/// </summary>
/// <param name="FoldassetsPath">查找的支援目录路径</param>
/// <param name="ListPictures">图片集路径</param>
private void Find(string[] FoldassetsPath, List<Object> ListPictures)
{
ViewObject.Clear();
string[] files = FoldassetsPath;
int startIndex = 0;
EditorApplication.update = delegate ()
{
string file = files[startIndex];
bool isCancel = EditorUtility.DisplayCancelableProgressBar("匹配资源中", file, (float)startIndex / (float)files.Length);
for (var nIdx = 0; nIdx < ListPictures.Count; nIdx++)
{
var obj = ListPictures[nIdx];
string Pictures_path = AssetDatabase.GetAssetPath(obj);
string guid = AssetDatabase.AssetPathToGUID(Pictures_path);
if (Regex.IsMatch(File.ReadAllText(file), guid))
{
//Debug.Log(file, AssetDatabase.LoadAssetAtPath<Object>(GetRelativeAssetsPath(file)));
Object PictureObject1 = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(GetRelativeAssetsPath(file));
ViewObject.Add(PictureObject1);
}
}
startIndex++;
if (isCancel || startIndex >= files.Length)
{
EditorUtility.ClearProgressBar();
EditorApplication.update = null;
startIndex = 0;
Debug.Log("匹配结束");
}
};
}
/// <summary>
/// 查找相同的图片
/// </summary>
/// <param name="FoldassetsPath">查询文件夹地址</param>
/// <param name="Pictures">图片地址</param>
private void GetMD5(string[] FoldassetsPath, Object Pictures)
{
if (!Pictures)
{
Debug.LogError("文件夹获取错误,请检查!");
return;
}
PicturesObj_list.Clear();
string filemdPicture = null;
string[] assetsPath = FoldassetsPath;
Dictionary<string, string> MD5Dic = new Dictionary<string, string>();
System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();
byte[] Picturesmd5bytes = md5.ComputeHash(getTextureByte(AssetDatabase.GetAssetPath(Pictures)));
filemdPicture = System.BitConverter.ToString(Picturesmd5bytes).Replace("-", "");
MD5Dic.Add(filemdPicture, AssetDatabase.GetAssetPath(Pictures));
string filemd5 = null;
for (int i = 0; i < assetsPath.Length; i++)
{
//过滤meta和prefab文件
if (assetsPath[i].EndsWith(".png"))
{
byte[] md5bytes = md5.ComputeHash(getTextureByte(assetsPath[i]));
filemd5 = System.BitConverter.ToString(md5bytes).Replace("-", "");
//存入字典,检验重复资源
if (MD5Dic.ContainsKey(filemd5))
{
//Debug.LogError("资源 重复:MD5:" + filemd5 + ",\n path:" + assetsPath[i] + "\n path:" + MD5Dic[filemd5]);
Object PictureObject1 = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(assetsPath[i]);
PicturesObj_list.Add(PictureObject1);
}
}
}
}
static private string GetRelativeAssetsPath(string path)
{
return "Assets" + Path.GetFullPath(path).Replace(Path.GetFullPath(Application.dataPath), "").Replace('\\', '/');
}
private string[] GetFlodString(Object OnCheckFolder)
{
string StrCheckFolderPath = AssetDatabase.GetAssetPath(OnCheckFolder);
List<string> withoutExtensions = new List<string>() { ".prefab", ".unity", ".mat", ".asset", ".png" };
string[] assetsPath = Directory.GetFiles(StrCheckFolderPath, "*.*", SearchOption.AllDirectories).Where(s => withoutExtensions.Contains(Path.GetExtension(s).ToLower())).ToArray();
//string StrCheckFolderPath = AssetDatabase.GetAssetPath(OnCheckFolder);
//string[] assetsPath = Directory.GetFiles(StrCheckFolderPath, "*.*", SearchOption.AllDirectories);
return assetsPath;
}
/// <summary>
/// 根据图片路径返回字节流
/// </summary>
/// <param name="texturePath"></param>
/// <returns></returns>
static byte[] getTextureByte(string assetsPath)
{
FileStream file = new FileStream(assetsPath, FileMode.Open);
byte[] txByte = new byte[file.Length];
file.Read(txByte, 0, txByte.Length);
file.Close();
return txByte;
}
}