Files
Main/Assets/Editor/DIY/Custom/CheckVFXTextureEditor.cs
2025-01-25 04:38:09 +08:00

396 lines
16 KiB
C#

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<GameObject>(path);
if(prefab != null)
{
var charCon = prefab.GetComponent<CharacterController>();
if(charCon != null)
{
var capsCollider = prefab.GetComponent<CapsuleCollider>();
if(capsCollider == null)
{
capsCollider = prefab.AddComponent<CapsuleCollider>();
}
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<GameObject>(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<SkinnedMeshRenderer>(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<GameObject>(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<ParticleSystem>(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<string> vfxTexNameList = new List<string>(vfxFiles.Length / 2);
Dictionary<string, int> unUsedVfxTexNameList = new Dictionary<string, int>(vfxFiles.Length / 2);
Dictionary<string, string> useDic = new Dictionary<string, string>(vfxFiles.Length / 2);
List<float> vfxSizeList = new List<float>(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<GameObject>(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<string, int> unusedList, Dictionary<string, string> useDic, string resName)
{
var renders = go.GetComponentsInChildren<Renderer>(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;
}
}
}
}
}
}
}
}