检测Unity客户端无效的预设资源-优化手游安装包

扫描Resource目录里面可能未使用的prefab,输出一个可能无效的资源列表

可能未使用的prefab满足以下规则:

1、不被其他prefab和场景直接引用—-遍历GUID校验排除

2、不被其他prefab和场景间接引用,prefab脚本里面传入其他预设的名称或者路径—-遍历prefab名称排除

3、不被代码里面直接引用—-遍历CS文件校验prefab名称排除

为什么说是可能未使用的prefab,因为还有一种情况:

4、不被代码间接引用,如预设Anniver_01,在代码中是”Anniver_“+number,这种暂时没有好办法解决。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112

static public void checkByGUIDPrefab(Dictionary<string, PrefabData> guidPrefabDic, List<string> allResPathList)
{
//校验GUID
int nIndex = 0;
for (nIndex = 0; nIndex != allResPathList.Count; ++nIndex)
{
if (EditorUtility.DisplayCancelableProgressBar("正在扫描预设与场景中--校验GUID引用", "收集中..." + nIndex, (nIndex*1.0f)/ allResPathList.Count))
{
EditorUtility.ClearProgressBar();
return;
}
checkReference(guidPrefabDic, allResPathList[nIndex], true);
}

//校验预设里面包含其他预设的名称
for (nIndex = 0; nIndex != allResPathList.Count; ++nIndex)
{
if (EditorUtility.DisplayCancelableProgressBar("正在扫描预设与场景中--校验预设名引用", "收集中..." + nIndex, (nIndex * 1.0f) / allResPathList.Count))
{
EditorUtility.ClearProgressBar();
return;
}
checkNameReference(guidPrefabDic, allResPathList[nIndex]);
}

//除了预设和场景引用 还有代码引用
List<string> resPathList = new List<string>();
string[] codePath = Directory.GetFiles("Assets", "*.cs", SearchOption.AllDirectories);
foreach (string fi in codePath)
{
resPathList.Add(fi);
}

//校验代码引用
for (nIndex = 0; nIndex != resPathList.Count; ++nIndex)
{
if (EditorUtility.DisplayCancelableProgressBar("正在扫描CS源码中--校验预设名引用", "收集中..." + nIndex, (nIndex * 1.0f) / resPathList.Count))
{
EditorUtility.ClearProgressBar();
return;
}
checkReference(guidPrefabDic, resPathList[nIndex], false);
}
//还有一些主要是为了Alpha通道分离 将一张图片转换成了预设
//判断在OriginRes中是否有同名的.png文件存在 如果存在则淘汰掉

string filePath = "Assets/_OriginRes/";
string[] fis = Directory.GetFiles(filePath, "*.png", SearchOption.AllDirectories);

//写文件吧::::
List<string> unUsePrefabList = new List<string>();
foreach (string key in guidPrefabDic.Keys)
{
if (!guidPrefabDic[key].isReference && !isExistSameNamePngFile(fis, guidPrefabDic[key].fileName))
{
//Assets/Resources/_NewPanel/BillRecordPanel/BillRecordPanel.prefab 路径转文件名
//codeSrcPrefab.Add(AssetDatabase.GUIDToAssetPath(key), 1);
//Debug.LogError("找到未使用的预设名字:" + guidPrefabDic[key].fileName);
unUsePrefabList.Add(guidPrefabDic[key].fileName);
unUsePrefabPathList.Add(AssetDatabase.GUIDToAssetPath(key));
}
}
EditorUtility.DisplayCancelableProgressBar("扫描结束", "写入本地文件...", 1f);

File.WriteAllLines("Assets/possible_unused_prefab.txt", unUsePrefabPathList.ToArray());
EditorUtility.ClearProgressBar();

//for (int i = 0; i < unUsePrefabPathList.Count; i++)
//{
// System.IO.File.Copy(unUsePrefabPathList[i], @"Assets/Resources/Test1/" + Path.GetFileNameWithoutExtension(unUsePrefabPathList[i]), true);
//}
//拷贝文件至指定目录 试试看

}
/// <summary>
/// 校验GUID或者名称
/// </summary>
/// <param name="guidPrefabDic"></param>
/// <param name="resFilePath"></param>
/// <param name="checkGUID"></param>
static public void checkReference(Dictionary<string, PrefabData> guidPrefabDic, string resFilePath, bool checkGUID = true)
{
FileStream fs = new FileStream(resFilePath, FileMode.Open, FileAccess.Read);
byte[] buff = new byte[fs.Length];
fs.Read(buff, 0, (int)fs.Length);
string strText = Encoding.Default.GetString(buff);
fs.Close();

foreach (string key in guidPrefabDic.Keys)
{
if (guidPrefabDic[key].isReference == true)
{
continue;
}
int nStar = 0;
string checkStr = "";
if (checkGUID)
{
checkStr = key;
}
else
{
checkStr = guidPrefabDic[key].fileName;
}
nStar = strText.IndexOf(checkStr);
if (nStar != -1)
{
guidPrefabDic[key].isReference = true;
}
}
}