372 lines
11 KiB
C#
372 lines
11 KiB
C#
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using UnityEngine;
|
||
using System.IO;
|
||
using System.Linq;
|
||
using UnityEditor;
|
||
using System.Text;
|
||
using System.Text.RegularExpressions;
|
||
using GameLogic;
|
||
/// <summary>
|
||
/// 查找无引用资源(当前为贴图)version 2.0
|
||
/// Copyright (c) 2018 Ganchong Xingli
|
||
/// </summary>
|
||
public class FindNoReferenceAssetWindow:EditorWindow {
|
||
/// <summary>
|
||
/// 匹配资源类型库
|
||
/// </summary>
|
||
public static string ContainsExtensions = "*.prefab*.unity*.mat*.asset";
|
||
/// <summary>
|
||
/// Lua文件夹屏蔽库
|
||
/// </summary>
|
||
public static string WithoutLuaExtensions = "*3rd*.idea*Base*Common*UITools*Logic*";
|
||
|
||
/// <summary>
|
||
/// 所有游戏
|
||
/// </summary>
|
||
string[] games;
|
||
/// <summary>
|
||
/// 匹配资源类型库
|
||
/// </summary>
|
||
string containsExtensions = ContainsExtensions;
|
||
/// <summary>
|
||
/// Lua文件夹屏蔽库
|
||
/// </summary>
|
||
string withoutLuaExtensions = WithoutLuaExtensions;
|
||
/// <summary>
|
||
/// 是否检查所有游戏
|
||
/// </summary>
|
||
bool isCheckAllGames;
|
||
/// <summary>
|
||
/// 是否交叉检查
|
||
/// </summary>
|
||
bool isCorssCheck;
|
||
/// <summary>
|
||
/// 是否显示动态加载列表
|
||
/// </summary>
|
||
bool isShowDynamicList;
|
||
/// <summary>
|
||
/// 资源GUID列表
|
||
/// </summary>
|
||
List<string> AssetFileGuidList;
|
||
/// <summary>
|
||
/// 无引用资源 guid列表
|
||
/// </summary>
|
||
List<string> NoRefAssetGuidList;
|
||
/// <summary>
|
||
/// 没有直接引用但动态加载列表
|
||
/// </summary>
|
||
Dictionary<string,string> DynamicLoadAssetList;
|
||
/// <summary>
|
||
/// 所有检查的游戏
|
||
/// </summary>
|
||
Dictionary<string,bool> CheckGames;
|
||
|
||
/// <summary>
|
||
/// 查找资源目录
|
||
/// </summary>
|
||
public static string FindPath = AppConst.GameResRealPath + "/{0}";
|
||
/// <summary>
|
||
/// 资源目录
|
||
/// </summary>
|
||
public static string AssetPath = AppConst.GameResRealPath + "/{0}/Atlas";
|
||
/// <summary>
|
||
/// Lua文件路径
|
||
/// </summary>
|
||
public static string LuaFilesPath = AppConst.GameResRealPath + "/{0}/~Lua";
|
||
|
||
List<string> checkList = new List<string>();
|
||
|
||
[MenuItem("Tools/查找无引用贴图", false, 1)]
|
||
static void Init()
|
||
{
|
||
// Get existing open window or if none, make a new one:
|
||
FindNoReferenceAssetWindow window = (FindNoReferenceAssetWindow)EditorWindow.GetWindow(typeof(FindNoReferenceAssetWindow));
|
||
window.Show();
|
||
window.titleContent = new GUIContent("查找无引用资源");
|
||
window.InitWindow();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 初始化窗口
|
||
/// </summary>
|
||
void InitWindow()
|
||
{
|
||
InitSize();
|
||
InitGames ();
|
||
//FindNoReferences();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 初始化大小
|
||
/// </summary>
|
||
void InitSize()
|
||
{
|
||
minSize = new Vector2(512, 400);
|
||
maxSize = new Vector2(512, 400);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 初始化游戏
|
||
/// </summary>
|
||
void InitGames()
|
||
{
|
||
CheckGames = new Dictionary<string, bool> ();
|
||
games = Directory.GetDirectories(AppConst.GameResRealPath);
|
||
for (int i = 0; i < games.Length; i++)
|
||
{
|
||
games[i] = Path.GetFileNameWithoutExtension(games[i]);
|
||
CheckGames.Add (games[i],false);
|
||
}
|
||
}
|
||
|
||
void OnGUI()
|
||
{
|
||
ShowCheckGames ();
|
||
ShowWithout();
|
||
ShowButtons();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 选择哪些游戏需要检查
|
||
/// </summary>
|
||
void ShowCheckGames()
|
||
{
|
||
EditorGUILayout.BeginVertical();
|
||
EditorGUILayout.HelpBox("请勾选需要检查的游戏", MessageType.None, true);
|
||
//全选/反选
|
||
bool tmpAllGames = isCheckAllGames;
|
||
isCheckAllGames = EditorGUILayout.Toggle("All/None", isCheckAllGames);
|
||
EditorGUILayout.Space();
|
||
if (tmpAllGames != isCheckAllGames)
|
||
{
|
||
string[] keys = CheckGames.Keys.ToArray<string>();
|
||
foreach (var each in keys)
|
||
{
|
||
CheckGames[each] = isCheckAllGames;
|
||
}
|
||
}
|
||
|
||
for (int i = 0; i < games.Length; i++)
|
||
{
|
||
CheckGames[games[i]] = EditorGUILayout.Toggle(games[i], CheckGames[games[i]]);
|
||
}
|
||
EditorGUILayout.EndVertical();
|
||
EditorGUILayout.Space();
|
||
EditorGUILayout.Space();
|
||
|
||
EditorGUILayout.BeginVertical();
|
||
isCorssCheck = EditorGUILayout.Toggle("是否交叉检查?", isCorssCheck);
|
||
isShowDynamicList = EditorGUILayout.Toggle("是否显示动态加载列表?", isShowDynamicList);
|
||
EditorGUILayout.EndVertical();
|
||
EditorGUILayout.Space();
|
||
}
|
||
/// <summary>
|
||
/// 显示屏蔽库
|
||
/// </summary>
|
||
void ShowWithout()
|
||
{
|
||
EditorGUILayout.BeginVertical();
|
||
containsExtensions = EditorGUILayout.TextField("匹配资源类型库?", containsExtensions);
|
||
withoutLuaExtensions = EditorGUILayout.TextField("Lua文件夹屏蔽库?", withoutLuaExtensions);
|
||
EditorGUILayout.EndVertical();
|
||
EditorGUILayout.Space();
|
||
}
|
||
/// <summary>
|
||
/// 显示Build按钮
|
||
/// </summary>
|
||
void ShowButtons()
|
||
{
|
||
if (GUILayout.Button("开始检查", GUILayout.Height(40f)))
|
||
{
|
||
FindNoReferences();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查找无引用贴图
|
||
/// </summary>
|
||
void FindNoReferences()
|
||
{
|
||
checkList.Clear();
|
||
if (isCorssCheck)
|
||
{
|
||
ResetList();
|
||
foreach (var game in CheckGames)
|
||
{
|
||
if (!game.Value) continue;
|
||
CollectAllAsset(game.Key);
|
||
}
|
||
foreach(var game in CheckGames)
|
||
{
|
||
if (!game.Value) continue;
|
||
checkList.Add(game.Key);
|
||
}
|
||
ResetList();
|
||
CollectAllAsset(checkList[0]);
|
||
FindReferences(checkList[0]);
|
||
}
|
||
else {
|
||
foreach (var game in CheckGames) {
|
||
if (!game.Value) continue;
|
||
checkList.Add(game.Key);
|
||
}
|
||
ResetList();
|
||
CollectAllAsset(checkList[0]);
|
||
FindReferences(checkList[0]);
|
||
}
|
||
}
|
||
|
||
void ResetList()
|
||
{
|
||
AssetFileGuidList = new List<string>();
|
||
NoRefAssetGuidList = new List<string>();
|
||
DynamicLoadAssetList = new Dictionary<string, string>();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 搜集所有的资源
|
||
/// </summary>
|
||
void CollectAllAsset(string game)
|
||
{
|
||
string assetPath = string.Format(AssetPath, game);
|
||
var files = Directory.GetFiles(assetPath, "*.*", SearchOption.AllDirectories).Where(item => { return Path.GetExtension(item) == ".png" || Path.GetExtension(item) == ".jpg"; });
|
||
foreach (var path in files) {
|
||
if(string.IsNullOrEmpty(path))continue;
|
||
var guid = AssetDatabase.AssetPathToGUID (GetRelativeAssetsPath(path));
|
||
AssetFileGuidList.Add(guid);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查找引用
|
||
/// </summary>
|
||
void FindReferences(string game)
|
||
{
|
||
int startIndex = 0;
|
||
int count = AssetFileGuidList.Count;
|
||
string guid = AssetFileGuidList [startIndex];
|
||
string curAssetPath = AssetDatabase.GUIDToAssetPath (guid);
|
||
string findPath = string.Format(FindPath,game);
|
||
string[] files = Directory.GetFiles(findPath, "*.*", SearchOption.AllDirectories)
|
||
.Where(s => containsExtensions.Contains(Path.GetExtension(s).ToLower())).ToArray();
|
||
int findIndex = 0;
|
||
bool haveRef = false;
|
||
EditorApplication.update += delegate() {
|
||
string file = files [findIndex];
|
||
|
||
bool isCancel = EditorUtility.DisplayCancelableProgressBar ("查找资源中。。。", curAssetPath.Replace(AssetPath.Replace(Application.dataPath,"Assets")+"/",""), (float)(findIndex+startIndex*files.Length) / (float)(count*files.Length));
|
||
|
||
if (Regex.IsMatch (File.ReadAllText (file), guid)) {
|
||
haveRef = true;
|
||
}
|
||
findIndex++;
|
||
if(findIndex>=files.Length)
|
||
{
|
||
findIndex = 0;
|
||
startIndex++;
|
||
if(!haveRef&&!MatchLuaFiles(curAssetPath,game)){
|
||
NoRefAssetGuidList.Add(guid);
|
||
}
|
||
haveRef = false;
|
||
if(startIndex<count){
|
||
guid = AssetFileGuidList[startIndex];
|
||
curAssetPath = AssetDatabase.GUIDToAssetPath (guid);
|
||
}
|
||
}
|
||
if (isCancel || startIndex >= count) {
|
||
EditorUtility.ClearProgressBar ();
|
||
EditorApplication.update = null;
|
||
findIndex = 0;
|
||
startIndex = 0;
|
||
DebugNoRefList(game);
|
||
DebugDynamicLoadList(game);
|
||
checkList.Remove(game);
|
||
if (checkList.Count > 0)
|
||
{
|
||
ResetList();
|
||
CollectAllAsset(checkList[0]);
|
||
FindReferences(checkList[0]);
|
||
}
|
||
}
|
||
};
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取资源真实路径
|
||
/// </summary>
|
||
private string GetRelativeAssetsPath(string path)
|
||
{
|
||
return "Assets" + Path.GetFullPath(path).Replace(Path.GetFullPath(Application.dataPath), "").Replace('\\', '/');
|
||
}
|
||
|
||
/// <summary>
|
||
/// 打印无引用资源列表
|
||
/// </summary>
|
||
void DebugNoRefList(string game)
|
||
{
|
||
Debug.Log(string.Format("=============================={0}无引用资源列表Start================================",game));
|
||
foreach (var guid in NoRefAssetGuidList) {
|
||
if (string.IsNullOrEmpty (guid))
|
||
continue;
|
||
Debug.Log (AssetDatabase.GUIDToAssetPath (guid));
|
||
}
|
||
Debug.Log(string.Format("=============================={0}无引用资源列表 End================================\n", game));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 打印动态加载资源列表
|
||
/// </summary>
|
||
void DebugDynamicLoadList(string game)
|
||
{
|
||
if (!isShowDynamicList) return;
|
||
Debug.Log(string.Format("=============================={0}动态加载资源列表Start================================", game));
|
||
DirectoryInfo directoryInfo;
|
||
foreach (var dic in DynamicLoadAssetList) {
|
||
if (string.IsNullOrEmpty (dic.Key))
|
||
continue;
|
||
directoryInfo = new DirectoryInfo (dic.Key);
|
||
Debug.Log (string.Format("Asset:{0} is dynamic load in lua file {1}",directoryInfo.Name,dic.Value));
|
||
}
|
||
Debug.Log(string.Format("=============================={0}动态加载资源列表 End================================\n", game));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 匹配lua文件
|
||
/// </summary>
|
||
bool MatchLuaFiles(string assetPath,string game)
|
||
{
|
||
DirectoryInfo directoryInfo = new DirectoryInfo (assetPath);
|
||
var assetName = directoryInfo.Name.Replace(".jpg","").Replace(".png","");
|
||
var luaFilesPath = string.Format(LuaFilesPath,game);
|
||
directoryInfo = new DirectoryInfo(luaFilesPath);
|
||
var dirctoryInfos = directoryInfo.GetDirectories ().Where(item=>!withoutLuaExtensions.Contains(item.Name));
|
||
foreach(var info in dirctoryInfos)
|
||
{
|
||
if (info == null)
|
||
continue;
|
||
var files = Directory.GetFiles (info.FullName, "*.*", SearchOption.AllDirectories);
|
||
foreach(var file in files)
|
||
{
|
||
if (file.EndsWith (".meta"))
|
||
continue;
|
||
var text = File.ReadAllText (file);
|
||
if (Regex.IsMatch (File.ReadAllText (file), assetName)) {
|
||
DynamicLoadAssetList.Add (assetPath,file);
|
||
return true;
|
||
}
|
||
if(Regex.IsMatch(assetName,"[0-9]{1,}$")){
|
||
var str = assetName.Substring(0, assetName.Length - 1);
|
||
if (Regex.IsMatch(File.ReadAllText(file), str))
|
||
{
|
||
DynamicLoadAssetList.Add(assetPath, file);
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
}
|