using System.Collections.Generic; using System.IO; using System.Text; using UnityEditor; using UnityEditor.SceneManagement; using UnityEngine; using UnityEngine.Gonbest.MagicCube; namespace Thousandto.DIY { public class CheckVFXTextureEditor : EditorWindow { [MenuItem("Ares/将角色控制器修改为胶囊体")] static void ChangeCharacterController() { var guids = AssetDatabase.FindAssets("t:Prefab"); for (int i = 0; i < guids.Length; ++i) { string path = AssetDatabase.GUIDToAssetPath(guids[i]); if (path.Contains("Resources/Prefab")) { var prefab = AssetDatabase.LoadAssetAtPath(path); if(prefab != null) { var charCon = prefab.GetComponent(); if(charCon != null) { var capsCollider = prefab.GetComponent(); if(capsCollider == null) { capsCollider = prefab.AddComponent(); } capsCollider.isTrigger = false; capsCollider.material = null; capsCollider.center = charCon.center; capsCollider.radius = charCon.radius; capsCollider.height = charCon.height; GameObject.DestroyImmediate(charCon, true); EditorUtility.SetDirty(prefab); AssetDatabase.SaveAssets(); EditorUtility.DisplayProgressBar("ChangeCharacterController", string.Format("change {0}/{1}", i, guids.Length), i / (float)guids.Length); } } } } EditorUtility.ClearProgressBar(); } [MenuItem("Ares/关闭Model ReadWrite选项")] static void CloseModelReadWrite() { var guids = AssetDatabase.FindAssets("t:Model"); for (int i = 0; i < guids.Length; ++i) { string path = AssetDatabase.GUIDToAssetPath(guids[i]); if(path.Contains("RawResources/scene")) { var ai = AssetImporter.GetAtPath(path) as ModelImporter; if (ai != null && ai.isReadable) { ai.isReadable = false; AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate); EditorUtility.DisplayProgressBar("CloseModelReadWrite", string.Format("CloseModelReadWrite {0}/{1}", i, guids.Length), i / (float)guids.Length); } } } EditorUtility.ClearProgressBar(); } [MenuItem("Ares/将所有SkinMesh MotionVector关闭")] static void SetMotionVector() { var guids = AssetDatabase.FindAssets("t:Prefab"); for (int i = 0; i < guids.Length; ++i) { string path = AssetDatabase.GUIDToAssetPath(guids[i]); var prefab = AssetDatabase.LoadAssetAtPath(path); EditorUtility.DisplayProgressBar("SetVfxPrewarmPrefab", string.Format("SetVfxPrewarm {0}/{1}", i, guids.Length), i / (float)guids.Length); if (CloseSkinMotionVector(prefab)) { EditorUtility.SetDirty(prefab); AssetDatabase.SaveAssets(); } } guids = AssetDatabase.FindAssets("t:Scene"); for (int i = 0; i < guids.Length; ++i) { string path = AssetDatabase.GUIDToAssetPath(guids[i]); if (!path.Contains("RawResources")) { continue; } EditorUtility.DisplayProgressBar("SetVfxPrewarmScene", string.Format("SetVfxPrewarm {0}/{1}", i, guids.Length), i / (float)guids.Length); var scene = EditorSceneManager.OpenScene(path, OpenSceneMode.Single); GameObject root = GameObject.Find("SceneRoot"); if (root != null) { if (CloseSkinMotionVector(root)) { EditorSceneManager.SaveScene(scene); } } } EditorUtility.ClearProgressBar(); } private static bool CloseSkinMotionVector(GameObject go) { if (go == null) return false; var change = false; var pats = go.GetComponentsInChildren(true); for (int j = 0; j < pats.Length; ++j) { var par = pats[j]; if(par.skinnedMotionVectors) { par.skinnedMotionVectors = false; change = true; } if (par.motionVectorGenerationMode != MotionVectorGenerationMode.ForceNoMotion) { par.motionVectorGenerationMode = MotionVectorGenerationMode.ForceNoMotion; change = true; } } return change; } [MenuItem("Ares/将所有特效Prewarm关闭")] static void SetVfxPrewarm() { var guids = AssetDatabase.FindAssets("t:Prefab"); for (int i = 0; i < guids.Length; ++i) { string path = AssetDatabase.GUIDToAssetPath(guids[i]); var prefab = AssetDatabase.LoadAssetAtPath(path); EditorUtility.DisplayProgressBar("SetVfxPrewarmPrefab", string.Format("SetVfxPrewarm {0}/{1}", i, guids.Length), i / (float)guids.Length); if(ClosePrewarm(prefab)) { EditorUtility.SetDirty(prefab); AssetDatabase.SaveAssets(); } } guids = AssetDatabase.FindAssets("t:Scene"); for (int i = 0; i < guids.Length; ++i) { string path = AssetDatabase.GUIDToAssetPath(guids[i]); if(!path.Contains("RawResources")) { continue; } EditorUtility.DisplayProgressBar("SetVfxPrewarmScene", string.Format("SetVfxPrewarm {0}/{1}", i, guids.Length), i / (float)guids.Length); var scene = EditorSceneManager.OpenScene(path, OpenSceneMode.Single); GameObject root = GameObject.Find("SceneRoot"); if (root != null) { if (ClosePrewarm(root)) { EditorSceneManager.SaveScene(scene); } } } EditorUtility.ClearProgressBar(); } private static bool ClosePrewarm(GameObject go) { if (go == null) return false; var change = false; var pats = go.GetComponentsInChildren(true); for (int j = 0; j < pats.Length; ++j) { var par = pats[j]; if(par.main.loop && par.main.prewarm) { var main = par.main; main.prewarm = false; change = true; } } return change; } [MenuItem("Ares/CheckVFXTextureEditor")] static void Open() { if (Application.isPlaying) { return; } var win = (CheckVFXTextureEditor)EditorWindow.GetWindow(typeof(CheckVFXTextureEditor)); win.Show(); } private string _prefabPath = string.Empty; private string _scenePath = string.Empty; private string _vfxTexPath = string.Empty; void OnGUI() { EditorGUILayout.BeginVertical(); EditorGUILayout.LabelField("选择路径"); EditorGUILayout.Space(); EditorGUILayout.LabelField("需要检查Prefab路径"); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("浏览", GUILayout.Width(50))) { _prefabPath = EditorUtility.OpenFolderPanel("Change Layer Prefab Path", _prefabPath, ""); } if (string.IsNullOrEmpty(_prefabPath)) { EditorGUILayout.LabelField("null..."); } else { EditorGUILayout.LabelField(_prefabPath); } EditorGUILayout.EndHorizontal(); EditorGUILayout.LabelField("需要检查Scene路径"); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("浏览", GUILayout.Width(50))) { _scenePath = EditorUtility.OpenFolderPanel("Change Layer Prefab Path", _scenePath, ""); } if (string.IsNullOrEmpty(_scenePath)) { EditorGUILayout.LabelField("null..."); } else { EditorGUILayout.LabelField(_scenePath); } EditorGUILayout.EndHorizontal(); EditorGUILayout.LabelField("特效图片资源路径"); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("浏览", GUILayout.Width(50))) { _vfxTexPath = EditorUtility.OpenFolderPanel("Change Layer Prefab Path", _vfxTexPath, ""); } if (string.IsNullOrEmpty(_vfxTexPath)) { EditorGUILayout.LabelField("null..."); } else { EditorGUILayout.LabelField(_vfxTexPath); } EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); EditorGUILayout.BeginVertical(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); if (GUILayout.Button("检查", GUILayout.Width(50))) { if (string.IsNullOrEmpty(_prefabPath)) return; if (Directory.Exists(_prefabPath)) { //载入所有特效贴图的名字 DirectoryInfo vfxDir = new DirectoryInfo(_vfxTexPath); FileInfo[] vfxFiles = vfxDir.GetFiles("*.*", SearchOption.AllDirectories); List vfxTexNameList = new List(vfxFiles.Length / 2); Dictionary unUsedVfxTexNameList = new Dictionary(vfxFiles.Length / 2); Dictionary useDic = new Dictionary(vfxFiles.Length / 2); List vfxSizeList = new List(vfxFiles.Length / 2); for (int i = 0; i < vfxFiles.Length; ++i) { var size = vfxFiles[i].Length / 1024.0f; var filePath = vfxFiles[i].FullName.ToLower(); if(filePath.EndsWith(".tga") || filePath.EndsWith(".jpg") || filePath.EndsWith(".png") || filePath.EndsWith(".exr") || filePath.EndsWith(".dds")) { filePath = filePath.Replace('\\', '/'); var starIndex = filePath.IndexOf("/assets/", 0); filePath = filePath.Remove(0, starIndex + 1); vfxTexNameList.Add(filePath); unUsedVfxTexNameList.Add(filePath, 0); vfxSizeList.Add(size); } } //检查目录下的所有prefab 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(path); if (go != null) { Check(go, unUsedVfxTexNameList, useDic, path); } } //检查目录下的所有prefab DirectoryInfo scenedirection = new DirectoryInfo(_scenePath); FileInfo[] scenefiles = scenedirection.GetFiles("*.unity", SearchOption.AllDirectories); for (int i = 0; i < scenefiles.Length; ++i) { var path = scenefiles[i].FullName.Replace('\\', '/'); var starIndex = path.IndexOf("/Assets/", 0); path = path.Remove(0, starIndex + 1); var scene = EditorSceneManager.OpenScene(path, OpenSceneMode.Single); GameObject root = GameObject.Find("SceneRoot"); if (root != null) { Check(root, unUsedVfxTexNameList, useDic, path); } } var text = new StringBuilder(1024 * 1024); for(int i = 0; i < vfxTexNameList.Count; ++i) { var count = 0; unUsedVfxTexNameList.TryGetValue(vfxTexNameList[i], out count); var usePath = string.Empty; useDic.TryGetValue(vfxTexNameList[i], out usePath); text.AppendFormat("{0},{1},{2},{3}\n", vfxTexNameList[i], vfxSizeList[i], count, usePath); } var savePath = EditorUtility.OpenFilePanel("选择保存的文件", "", "*.txt"); if (!string.IsNullOrEmpty(savePath)) { File.WriteAllText(savePath, text.ToString()); } ////删除文件 //var iter = unUsedVfxTexNameList.GetEnumerator(); //try //{ // while (iter.MoveNext()) // { // if(iter.Current.Value <= 0) // { // File.Delete(iter.Current.Key); // } // } //} //finally //{ // iter.Dispose(); //} } } } private void Check(GameObject go, Dictionary unusedList, Dictionary useDic, string resName) { var renders = go.GetComponentsInChildren(true); for (int j = 0; j < renders.Length; ++j) { var mats = renders[j].sharedMaterials; for (int k = 0; k < mats.Length; ++k) { if (mats[k] == null) { continue; } var texNames = mats[k].GetTexturePropertyNames(); for (int n = 0; n < texNames.Length; ++n) { var tex = mats[k].GetTexture(texNames[n]) as Texture2D; if (tex != null) { var texPath = AssetDatabase.GetAssetPath(tex); texPath = texPath.Replace('\\', '/').ToLower(); var count = 0; if(unusedList.TryGetValue(texPath, out count)) { ++count; unusedList[texPath] = count; useDic[texPath] = resName; } } } } } } } }