前言
我们项目使用TexturePacker打Atlas,随着功能的增加同时资源量也在增加。由于前期没有制定相应的资源使用规范,导致A模块的Prefab会引用到除Common外的B、C等模块的Atlas。为此,我写了一个小工具,用来检查一个Prefab一共引用了哪些Texture,方便资源的规范使用。
思路
-
Prefab如何引用Sprite
首先,我们用Sublime查看Prefab,可以发现,组件引用Sprite的位置,会有类似的格式:
我们可以看出,Sprite是通过fileID和guid联合起来被引用的。 -
Texture的Meta文件
打开图集的Meta文件,以Common.png 为例
我们可以看到图集的guid和原始图片的fileID:
由此,我们需要做的就是在Prefab中找到所有m_Sprite:{fileID:xxxx, guid:yyyyy}
格式的字符串,从中取出guid,然后获得AssetPath即可。
开发
我们使用Menu开发这个小工具
- ValidateFunction
限定prefab的检查路径,因项目而异。
private static string PrefabFolder = "Assets/Resources/prefab";
private static string LOG_TAG = "<color=blue>[OptPrefab]</color> Prefab = {0}";
[MenuItem("Assets/Optimize/FindTextureRef", true, 1004)]
public static bool FindTextureRef_Validation()
{
GameObject prefab = Selection.activeObject as GameObject;
if (prefab == null)
{
return false;
}
string prefabPath = AssetDatabase.GetAssetPath(prefab);
if (!prefabPath.Contains(PrefabFolder))
{
return false;
}
return true;
}
- 以文本格式读取选中的Prefab
GameObject prefab = Selection.activeObject as GameObject;
string prefabPath = AssetDatabase.GetAssetPath(prefab);
string prefabName = U2Utils.GetFileName(prefabPath);
string prefabFolder = U2Utils.GetFolder(prefabPath);
//1.以文本格式读取Prefab的内容
string content = File.ReadAllText(prefabPath);
- 使用正则表达式
//2.Prefab内Sprite的正则表达式
string regStr = "m_Sprite: {fileID:\\s?[a-fA-F0-9]+, guid:\\s?([a-fA-F0-9]+), type: 3}";
Regex reg = new Regex(regStr);
MatchCollection matches = reg.Matches(content);
//3.缓存所有匹配的guid
List<string> tmpGuids = new List<string>();
foreach (Match m in matches)
{
tmpGuids.Add(m.Groups[1].Value);//正则表达式内括号内匹配的guid
}
Match.Groups[0]是匹配的字符串,Match.Groups[1]是匹配的正则表达式内第1个小括号内的字符串,这里是我们要取的guid。
- LINQ剔除冗余
List<string> pureGuids = tmpGuids.Distinct().ToList();
- 根据guid获取路径
//5.1 根据guid获取路径
string path = AssetDatabase.GUIDToAssetPath(guid);
string directory = U2Utils.GetFileDirectory(path);
string folder = U2Utils.GetFolder(path);
//5.2 获取importer,判断是Atlas还是单张Sprite
TextureImporter importer = AssetImporter.GetAtPath(path) as TextureImporter;
//5.3 输出log
string logStr = string.Empty;
if (importer.spriteImportMode == SpriteImportMode.Multiple)
{
if (folder.Contains(prefabFolder))
{
logStr = "引用自己模块Atlas = <color=green>" + path + "</color>";
}
else
{
if (directory.Contains("A_"))
{
logStr = "引用共用Atlas = <color=green>" + path + "</color>";
}
else
{
logStr = "引用Atlas = <color=black>" + path + "</color>";
}
}
}
else if (importer.spriteImportMode == SpriteImportMode.Single)
{
logStr = "引用Sprite = <color=green>" + path + "</color>";
}
获取到TextureImporter,可以判断Texture是Atlas还是单张图。从而输出不同的log。
我们项目中,使用A_ 前缀表示共用资源,同一模块的Texture和Prefab的文件夹名字要相同。Log的输出格式,可以根据大家不同的项目来做不同的规范。
6.输出
结语
希望这个小工具对大家有帮助。