using System.Collections; using System.Collections.Generic; using System.IO; using System.Text; using UnityEditor; using UnityEngine; public class CheckVfxInvalidTex { #region//路径 //特效纹理贴图文件夹路径 public const string CONST_TEX_FOLDER_PATH = "GameAssets/RawResources/vfx/fxresources/texture"; public const string CONST_MAT_FOLDER_PATH = "GameAssets/RawResources/vfx/fxresources/fxmaterials"; public const string CONST_SAVE_PATH = "EditorOut"; #endregion #region//私有变量 private List _relationTexMetaPath = new List(); private List _cacheCehckTexInfoList = new List(); private Dictionary _cacheAllTexInfo = new Dictionary(); #endregion #region//静态变量 private static CheckVfxInvalidTex _instance = null; public static CheckVfxInvalidTex Instance { get { if (_instance == null) { _instance = new CheckVfxInvalidTex(); } return _instance; } } #endregion #region//公共函数 public void Start() { InitAllTex(); } #endregion #region//私有变量 //初始化特效贴图 private void InitAllTex() { string path = Application.dataPath; string texFolderPath = string.Format("{0}/{1}", path, CONST_TEX_FOLDER_PATH); string matFolderPath = string.Format("{0}/{1}", path, CONST_MAT_FOLDER_PATH); if(!Directory.Exists(texFolderPath)) { Debug.LogError("特效贴图文件夹路径不存在!"); return; } DirectoryInfo dir = new DirectoryInfo(texFolderPath); SerializeFile(dir); if (!Directory.Exists(matFolderPath)) { Debug.LogError("特效材质球文件夹路径不存在!"); return; } dir = new DirectoryInfo(matFolderPath); SerializeMat(dir); //获取依赖Tex的guid列表并且剔除未使用的tex for (int i = 0; i < _relationTexMetaPath.Count; i++) { string _relationPath = _relationTexMetaPath[i]; List guidList = GetFileGUID(_relationPath); for (int m = 0; m < guidList.Count; m++) { string guid = guidList[m]; if (_cacheAllTexInfo.ContainsKey(guid)) { int index = _cacheAllTexInfo[guid]; if (index >= 0 && index < _cacheCehckTexInfoList.Count) { _cacheCehckTexInfoList.RemoveAt(index); } } } } SaveCSV(); } public void SaveCSV() { string saveFolderPath = Application.dataPath.Substring(0, Application.dataPath.IndexOf("Client") - 1); saveFolderPath = string.Format("{0}/{1}", saveFolderPath, CONST_SAVE_PATH); string savePath = string.Format("{0}/无效特效Tex贴图.csv", saveFolderPath); if (!Directory.Exists(saveFolderPath)) { Directory.CreateDirectory(saveFolderPath); } if (File.Exists(savePath)) { File.Delete(savePath); } StringBuilder sb = new StringBuilder(); //写出列名称 for (int i = 0; i < _cacheCehckTexInfoList.Count; i++) { var info = _cacheCehckTexInfoList[i]; sb.Append(string.Format("纹理名字: {0} 纹理路径: {1}", info.Name, info.Path)); sb.Append("\n"); } File.WriteAllText(savePath, sb.ToString(), Encoding.UTF8); Debug.LogError(string.Format("检查完成!!!!!!!!!!请去{0}目录提取文件", saveFolderPath)); } //序列化文件 private void SerializeFile(DirectoryInfo dir) { if (dir == null) return; //查找所有文件 FileInfo[] infos = dir.GetFiles(); if (infos == null) return; for (int i = 0; i < infos.Length; i++) { FileInfo info = infos[i]; if (info.Name.IndexOf(".meta") > 0) { CacheTexInfo(info.FullName, info.Name); } } //查找子文件夹 DirectoryInfo[] childDirs = dir.GetDirectories(); if (childDirs == null) return; for (int i = 0; i < childDirs.Length; i++) { DirectoryInfo childDir = childDirs[i]; SerializeFile(childDir); } } //读取guid private void CacheTexInfo(string texPath, string name) { string path = texPath; try { if (File.Exists(path)) { FileStream fs = File.Open(path, FileMode.Open); byte[] bss = new byte[fs.Length]; fs.Read(bss, 0, (int)fs.Length); string result = Encoding.Default.GetString(bss); string cacheStr = string.Empty; int start = 0; int end = result.LastIndexOf("\n"); int orStart = start; int lastEnd = end; while (start < lastEnd) { start = result.IndexOf("guid:", start); if (start == -1) break; start += 5; end = result.IndexOf("\n", start); string ss = result.Substring(start); if (start >= end || end == -1) break; int index = start; for (int i = start; i < end; i++) { int findPos = result.IndexOf(' ', i); if (findPos < end && findPos != -1) { index = findPos; } else { break; } } start = index + 1; string guiIdStr = result.Substring(start, end - start); if (!_cacheAllTexInfo.ContainsKey(guiIdStr)) { _cacheAllTexInfo[guiIdStr] = _cacheCehckTexInfoList.Count; CheckTexInfo texInfo = new CheckTexInfo(); texInfo.Guid = guiIdStr; texInfo.Path = texPath; texInfo.Name = name; _cacheCehckTexInfoList.Add(texInfo); } orStart = end; start = end + 1; } fs.Close(); } } catch { } } private List GetFileGUID(string texPath) { string path = texPath; List retList = new List(); try { if (File.Exists(path)) { FileStream fs = File.Open(path, FileMode.Open); byte[] bss = new byte[fs.Length]; fs.Read(bss, 0, (int)fs.Length); string result = Encoding.Default.GetString(bss); string cacheStr = string.Empty; int start = 0; int end = result.LastIndexOf("\n"); int orStart = start; int lastEnd = end; while (start < lastEnd) { start = result.IndexOf("guid:", start); if (start == -1) break; start += 5; end = result.IndexOf("\n", start); string ss = result.Substring(start); if (start >= end || end == -1) break; int index = start; for (int i = start; i < end; i++) { int findPos = result.IndexOf(' ', i); if (findPos < end && findPos != -1) { index = findPos; } else { break; } } start = index + 1; string guiIdStr = result.Substring(start, end - start); retList.Add(guiIdStr); orStart = end; start = end + 1; } fs.Close(); } } catch { } return retList; } //序列化材质球 private void SerializeMat(DirectoryInfo dir) { if (dir == null) return; string assetFolderPath = dir.FullName.Substring(dir.FullName.IndexOf("Assets")); //查找所有文件 FileInfo[] infos = dir.GetFiles(); if (infos == null) return; for (int i = 0; i < infos.Length; i++) { FileInfo info = infos[i]; if (info.Name.IndexOf(".meta") < 0) { string assetPath = string.Format("{0}/{1}", assetFolderPath, info.Name); var mat = AssetDatabase.LoadAssetAtPath(assetPath, typeof(Material)) as Material; if (mat != null) { GetMatRelationTexMetaPathList(mat, ref _relationTexMetaPath); } } } ////查找子文件夹 DirectoryInfo[] childDirs = dir.GetDirectories(); if (childDirs == null) return; for (int i = 0; i < childDirs.Length; i++) { DirectoryInfo childDir = childDirs[i]; SerializeMat(childDir); } } //获取材质球的texture private void GetMatRelationTexMetaPathList(Material mat, ref List relationList) { if (mat == null) return; var shader = mat.shader; int shaderPropertyCount = UnityEditor.ShaderUtil.GetPropertyCount(shader); for (int i = 0; i < shaderPropertyCount; i++) { var type = UnityEditor.ShaderUtil.GetPropertyType(shader, i); var name = UnityEditor.ShaderUtil.GetPropertyName(shader, i); if (type == ShaderUtil.ShaderPropertyType.TexEnv) { Texture tex = null; Vector2 offset = Vector2.zero; Vector2 scale = Vector2.one; tex = mat.GetTexture(name); if (tex != null) { string path = UnityEditor.AssetDatabase.GetAssetPath(tex); path = string.Format("{0}/{1}.meta", Application.dataPath, path.Substring(7)); relationList.Add(path); } } } } #endregion } public class CheckTexInfo { public string Guid = string.Empty; public string Path = string.Empty; public string Name = string.Empty; }