using UnityEditor; using UnityEngine; using System.IO; using System.Collections.Generic; using ResMgr; using GameCore; using GameEditor.Core; using GameLogic; using System.Linq; namespace GameEditor { /// /// 资源路径编辑器类 /// public static class ResourcesPathEditor { /// /// /// private const string ResDirName = AppConst.GameResName + "/"; /// /// 忽略列表 /// private static StringArrayConfig ignoreConfig; /// /// 获取本地资源路径 /// /// /// private static string GetResLocalPath (string fullPath) { var strindex = fullPath.IndexOf (ResDirName); if (strindex == -1) return fullPath; var localDir = fullPath.Substring (strindex + ResDirName.Length) + "/"; return localDir; } static List dirPaths = new List(); static List abNames = new List(); static Dictionary resPaths = new Dictionary(); static Dictionary dependences = new Dictionary(); /// /// 创建资源配置 /// /// public static void CreateResourcePathConfig (bool isRename) { dirPaths = new List (); abNames = new List (); resPaths = new Dictionary (); dependences = new Dictionary (); InitIgnoreList(); System.Diagnostics.Stopwatch time = new System.Diagnostics.Stopwatch(); time.Start(); ForEachDirectories (AppConst.GameResPath, isRename); time.Stop(); Debug.Log(" 耗时:" + time.ElapsedMilliseconds*0.001 + "秒"); //初始化配置类 string assetPath = AppConst.GameResPath + "/ResConfigs/ResourcePathConfig.asset"; string fullPath = EditorUtil.GetFullPath (assetPath); ResourcePathConfig configClass = null; if (!File.Exists (fullPath)) { FileUtils.CreateDirectory (fullPath); configClass = ScriptableObject.CreateInstance (); configClass.Init (dirPaths, abNames, resPaths, dependences); AssetDatabase.CreateAsset (configClass, assetPath); } else { configClass = AssetDatabase.LoadAssetAtPath (assetPath); configClass.Init (dirPaths, abNames, resPaths, dependences); } EditorUtility.SetDirty (configClass); EditorUtility.ClearProgressBar (); AssetDatabase.SaveAssets (); AssetDatabase.Refresh (); } static void GetDirectories(string path, List list) { string[] directies = Directory.GetDirectories(path, "*", SearchOption.TopDirectoryOnly); foreach (var item in directies) { list.Add(item.Replace("\\", "/")); GetDirectories(item, list); } } /// /// 遍历目录 /// /// /// /// /// /// public static void ForEachDirectories (string path, bool isRename) { List directories = new List(); GetDirectories(path, directories); for (int i = 0; i < directories.Count; i++) { string str = directories[i]; if(str.Length > 32) { string a = str.Substring(0, 32); if (a == "Assets/ManagedResources/LuaBytes") continue; } EditorUtility.DisplayProgressBar(string.Format("正在刷新资源配置:({0}/{1})", i, directories.Count), "路径:"+ directories[i], (float)i / directories.Count); AssetImporter ai = AssetImporter.GetAtPath(EditorUtil.GetAssetsPath(directories[i])); if (IsMarked(ai)) { if (abNames.IndexOf(ai.assetBundleName) == -1) abNames.Add(ai.assetBundleName); if (!dependences.ContainsKey(ai.assetBundleName)) { string assetBundleName = ai.assetBundleName + "." + ai.assetBundleVariant; AssetBundleInfo info = new AssetBundleInfo(assetBundleName, AssetDatabase.GetAssetBundleDependencies(assetBundleName, false)); dependences.Add(ai.assetBundleName, info); } } else { ai = null; } List files = Directory.GetFiles(directories[i], "*", SearchOption.TopDirectoryOnly).Where(s => !s.EndsWith(".meta")).ToList(); if (files.Count > 0) { dirPaths.Add(EditorUtil.GetAssetsPath(directories[i])); for (int j = 0; j < files.Count; j++) { ForEachFiles(files[j], ai, isRename); } } } } /// /// 遍历检查资源循环依赖 /// /// /// /// /// /// public static void ForEachCheckDependences() { System.Diagnostics.Stopwatch time = new System.Diagnostics.Stopwatch(); time.Start(); InitIgnoreList(); List directories = new List(); Dictionary dependences = new Dictionary(); List tmpList = new List(); GetDirectories(AppConst.GameResPath, directories); for (int i = 0; i < directories.Count; i++) { EditorUtility.DisplayProgressBar(string.Format("正在检查:({0}/{1})", i, directories.Count), "路径:" + directories[i], (float)i / directories.Count); AssetImporter ai = AssetImporter.GetAtPath(EditorUtil.GetAssetsPath(directories[i])); if (IsMarked(ai)) { if (!dependences.ContainsKey(ai.assetBundleName)) { string assetBundleName = ai.assetBundleName + "." + ai.assetBundleVariant; dependences.Add(ai.assetBundleName, assetBundleName); string[] array = AssetDatabase.GetAssetBundleDependencies(assetBundleName, false); if (array.Length > 0) { tmpList.Clear(); CheckDependences(assetBundleName, assetBundleName, string.Empty, tmpList); } } } else { ai = null; } List files = Directory.GetFiles(directories[i], "*", SearchOption.TopDirectoryOnly).Where(s => !s.EndsWith(".meta")).ToList(); for (int j = 0; j < files.Count; j++) { if (ai == null) { ai = AssetImporter.GetAtPath(EditorUtil.GetAssetsPath(files[j])); if (IsMarked(ai)) { if (!dependences.ContainsKey(ai.assetBundleName)) { string assetBundleName = ai.assetBundleName + "." + ai.assetBundleVariant; dependences.Add(ai.assetBundleName, assetBundleName); string[] array = AssetDatabase.GetAssetBundleDependencies(assetBundleName, false); if (array.Length > 0) { tmpList.Clear(); CheckDependences(assetBundleName, assetBundleName, string.Empty, tmpList); } } } } } } EditorUtility.ClearProgressBar(); time.Stop(); Debug.Log(" 耗时:" + time.ElapsedMilliseconds); } public static void CheckDependences(string root, string assetBundleName, string log,List list) { if (list.Contains(assetBundleName)) return; string[] array = AssetDatabase.GetAssetBundleDependencies(assetBundleName, false); log+=assetBundleName+"=>"; list.Add(assetBundleName); for (int i = 0; i < array.Length; i++) { if (array[i] == root) { Debug.LogErrorFormat("Error=>存在资源循环依赖:{0}", log + array[i]); } else { CheckDependences(root, array[i], log, list); } } } /// /// 遍历文件 /// /// /// /// /// /// public static void ForEachFiles (string path, AssetImporter ai, bool isRename) { if (IsIgnore (path)) return; if (ai == null) ai = AssetImporter.GetAtPath (EditorUtil.GetAssetsPath(path)); if (ai == null) return; if (IsMarked(ai)) { if (abNames.IndexOf(ai.assetBundleName) == -1) abNames.Add(ai.assetBundleName); if (!dependences.ContainsKey(ai.assetBundleName)) { string assetBundleName = ai.assetBundleName + "." + ai.assetBundleVariant; AssetBundleInfo info = new AssetBundleInfo(assetBundleName, AssetDatabase.GetAssetBundleDependencies(assetBundleName, false)); dependences.Add(ai.assetBundleName, info); } } string fileName = Path.GetFileNameWithoutExtension (path); string extension = Path.GetExtension (path); if (resPaths.ContainsKey (fileName)) { var info = resPaths[fileName]; string oldPath = string.Format("{0}/{1}{2}", dirPaths[info.resPathIndex], info.resName, info.extension); Debug.LogErrorFormat("资源名重复:{0}=>{1}", path, oldPath); if(isRename) { string exName = Path.GetExtension(path).Replace(".", ""); if (!string.IsNullOrEmpty(exName)) //给资源文件加后缀名规避重复 { if (exName != "prefab")//避免给prefab文件更名 { string newPath = AssetDatabase.RenameAsset(path, Path.GetFileNameWithoutExtension(path) + "_" + exName); Debug.LogErrorFormat("资源名已修正:{0} 请再次刷新文件路径", path); } else { string newPath = AssetDatabase.RenameAsset(oldPath, Path.GetFileNameWithoutExtension(oldPath) + "_" + Path.GetExtension(oldPath).Replace(".", "")); Debug.LogErrorFormat("资源名已修正:{0} 请再次刷新文件路径", oldPath); } } } } else { resPaths.Add (fileName, new ResPathInfo (fileName, extension, dirPaths.Count - 1, abNames.Count - 1)); } } /// /// 初始化忽略列表 /// public static void InitIgnoreList () { if (ignoreConfig != null) return; string path = "Assets/ManagedResources/EditorConfigs/IgnoreList.asset"; StringArrayConfig tmpList = AssetDatabase.LoadAssetAtPath (path); if (tmpList == null) { ignoreConfig = ScriptableObject.CreateInstance (); string fullPath = EditorUtil.GetFullPath (path); fullPath = Path.GetDirectoryName (fullPath); if (!Directory.Exists (fullPath)) Directory.CreateDirectory (fullPath); AssetDatabase.CreateAsset (ignoreConfig, path); } else { ignoreConfig = tmpList; } } /// /// 是否忽略掉 /// /// /// private static bool IsIgnore (string path) { if (ignoreConfig == null) return false; if (ignoreConfig.Configs == null) return false; for (int i = 0; i < ignoreConfig.Configs.Length; i++) { if (path.Contains (ignoreConfig.Configs[i])) { //Debug.LogError("被忽略掉的资源路径:" + path); return true; } } return false; } /// /// 是否标记过 /// /// /// public static bool IsMarked (AssetImporter ai) { return ai != null && !string.IsNullOrEmpty (ai.assetBundleName) && !string.IsNullOrEmpty (ai.assetBundleVariant); } } }