Files
Main/Assets/Editor/DIY/Custom/CheckInvalidUISpriteEditor.cs

208 lines
8.0 KiB
C#
Raw Normal View History

2025-01-25 04:38:09 +08:00
using UnityEngine;
using UnityEditor;
using System.IO;
using System.Collections.Generic;
using System.Text;
using Thousandto.Editor.Excel;
public class CheckInvalidUISpriteEditor : EditorWindow
{
[MenuItem("Ares/检查无效的UISprite")]
static void DoIt()
{
var win = (CheckInvalidUISpriteEditor)EditorWindow.GetWindow(typeof(CheckInvalidUISpriteEditor));
win.Show();
}
private string _prefabPath = string.Empty;
private Dictionary<string, List<string>> _showTexts = new Dictionary<string, List<string>>(65535);
void OnGUI()
{
EditorGUILayout.BeginVertical();
EditorGUILayout.LabelField("选择路径");
EditorGUILayout.Space();
EditorGUILayout.LabelField("需要检测的UIForm路径");
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("浏览", GUILayout.Width(100)))
{
_prefabPath = EditorUtility.OpenFolderPanel("Check UIForm Prefab Path", _prefabPath, "");
}
if (string.IsNullOrEmpty(_prefabPath))
{
EditorGUILayout.LabelField("null...");
}
else
{
EditorGUILayout.LabelField(_prefabPath);
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.EndVertical();
EditorGUILayout.BeginVertical();
EditorGUILayout.BeginHorizontal();
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
EditorGUILayout.EndHorizontal();
EditorGUILayout.EndVertical();
if (GUILayout.Button("检测并导出", GUILayout.Width(100)))
{
string excelPath = EditorUtility.SaveFilePanel("Export Excel", "", "InvalidUISprite", "xlsx");
if (string.IsNullOrEmpty(excelPath))
return;
if (string.IsNullOrEmpty(_prefabPath))
return;
if (Directory.Exists(_prefabPath))
{
_showTexts.Clear();
var rowCount = 0;
DirectoryInfo direction = new DirectoryInfo(_prefabPath);
FileInfo[] files = direction.GetFiles("*.prefab", SearchOption.AllDirectories);
for (int i = 0; i < files.Length; ++i)
{
var path = files[i].FullName.Replace('\\', '/');
var starIndex = path.IndexOf("/Assets/", 0);
path = path.Remove(0, starIndex + 1);
var go = AssetDatabase.LoadAssetAtPath<GameObject>(path);
if (go != null)
{
var fileName = files[i].Name;
fileName = fileName.Replace(".prefab", "");
var csCodePath = files[i].FullName.Replace('\\', '/');
csCodePath = csCodePath.Remove(starIndex);
csCodePath = csCodePath + "/Assets/GameAssets/Resources/GameUI/Form/" + fileName;
List<string> codeTexts = new List<string>(64);
if(Directory.Exists(csCodePath))
{
DirectoryInfo csdirection = new DirectoryInfo(csCodePath);
FileInfo[] csFiles = csdirection.GetFiles("*.cs", SearchOption.AllDirectories);
for (int j = 0; j < csFiles.Length; ++j)
{
codeTexts.Add(File.ReadAllText(csFiles[j].FullName));
}
}
var luaCodePath = files[i].FullName.Replace('\\', '/');
luaCodePath = luaCodePath.Remove(starIndex);
luaCodePath = luaCodePath + "/Assets/GameAssets/Resources/Lua/UI/Forms/" + fileName;
if(Directory.Exists(luaCodePath))
{
DirectoryInfo luadirection = new DirectoryInfo(luaCodePath);
FileInfo[] luaFiles = luadirection.GetFiles("*.lua", SearchOption.AllDirectories);
for (int j = 0; j < luaFiles.Length; ++j)
{
codeTexts.Add(File.ReadAllText(luaFiles[j].FullName));
}
}
var sprites = go.GetComponentsInChildren<UISprite>(true);
for (int j = 0; j < sprites.Length; ++j)
{
if(!IsUsedSprite(sprites[j], codeTexts))
{
List<string> findList = null;
if (!_showTexts.TryGetValue(fileName, out findList))
{
findList = new List<string>();
_showTexts.Add(fileName, findList);
++rowCount;
}
findList.Add(FindNodePath(sprites[j].gameObject, fileName));
++rowCount;
}
}
}
}
NormalExcelInfo excelInfo = new NormalExcelInfo();
excelInfo.Name = "InvalidUISprite";
excelInfo.Values = new string[rowCount, 2];
var iter = _showTexts.GetEnumerator();
int curRow = 0;
while(iter.MoveNext())
{
excelInfo.Values[curRow++, 0] = iter.Current.Key;
for(int i = 0; i < iter.Current.Value.Count;++ i)
{
excelInfo.Values[curRow++, 1] = iter.Current.Value[i];
}
}
ExcelWriter.Write(excelPath, excelInfo);
_showTexts.Clear();
}
}
}
private bool IsUsedSprite(UISprite sprite, List<string> codeText)
{
var name = sprite.name;
if (name == "Icon" || name == "Bind")
return true;
if (sprite.GetAtlasSprite() == null || !sprite.gameObject.activeSelf)
{
string number = string.Empty;
bool findNumber = false;
for (int i = 0; i < name.Length; ++i)
{
if (name[i] >= '0' && name[i] <= '9')
{
number += name[i];
findNumber = true;
}
else if (findNumber)
{
break;
}
}
var findText1 = name + "\"";
var findText2 = string.Empty;
var findText3 = string.Empty;
if (!string.IsNullOrEmpty(number))
{
findText2 = name.Replace(number, "{0}");
findText3 = name.Replace(number, "%d");
}
//需要检测是否代码有调用
bool isFind = false;
for (int k = 0; k < codeText.Count; ++k)
{
if (codeText[k].IndexOf(findText1) >= 0)
{
isFind = true;
break;
}
if (!string.IsNullOrEmpty(findText2) && codeText[k].IndexOf(findText2) >= 0)
{
isFind = true;
break;
}
if (!string.IsNullOrEmpty(findText3) && codeText[k].IndexOf(findText3) >= 0)
{
isFind = true;
break;
}
}
return isFind;
}
return true;
}
private string FindNodePath(GameObject go, string formName)
{
StringBuilder pathSB = new StringBuilder();
pathSB.Length = 0;
Transform parent = go.transform;
while (parent != null && parent.name != formName)
{
string cpPath = "/" + parent.gameObject.name;
pathSB.Insert(0, cpPath);
parent = parent.transform.parent;
}
return pathSB.ToString().TrimStart('/');
}
}