using System.Collections.Generic; using UnityEditor; using UnityEditor.SceneManagement; using UnityEngine; using UnityEngine.SceneManagement; public class SceneTextureAnalyze : EditorWindow { private List _textureGroups; private List _itemRecords; private Vector2 _scrollPos; private long _totalPixel; [MenuItem("Scene/Texture Analyzer")] public static void OpenWindow() { GetWindow(); } private void ScanSceneObject() { _textureGroups = new List(); _itemRecords = new List(); _scrollPos = Vector2.zero; var renderers = FindObjectsOfType(); for (var i = 0; i < renderers.Length; i++) { var renderer = renderers[i]; if (renderer.gameObject.activeInHierarchy) { var itemRecord = new SceneItemRecord(renderer); _itemRecords.Add(itemRecord); for (var j = 0; j < renderer.sharedMaterials.Length; j++) { var material = renderer.sharedMaterials[j]; if (material != null) { var shader = material.shader; if (shader != null) { var propertyCount = ShaderUtil.GetPropertyCount(shader); for (var k = 0; k < propertyCount; k++) { if (ShaderUtil.GetPropertyType(shader, k) == ShaderUtil.ShaderPropertyType.TexEnv) { var texture = material.GetTexture(ShaderUtil.GetPropertyName(shader, k)) as Texture2D; if (texture != null) { var textureGroup = _textureGroups.GetItem(texture, ListGetMode.create); if (!textureGroup.sceneItems.Contains(itemRecord)) textureGroup.sceneItems.Add(itemRecord); } } } } } } } } _textureGroups.Sort(SortTextureGroup); GetTotalPixel(); } private int SortTextureGroup(SceneTextureGroup a, SceneTextureGroup b) { var result = -a.sceneItems.Count.CompareTo(b.sceneItems.Count); if (result == 0) result = string.Compare(a.id.name, b.id.name, System.StringComparison.Ordinal); return result; } private void CleanSceneObjects() { _textureGroups = null; _itemRecords = null; _scrollPos = Vector2.zero; GetTotalPixel(); } private void RemoveEmpty() { for (var i = _itemRecords.Count - 1; i >= 0; i--) if (_itemRecords[i].item == null) _itemRecords.RemoveAt(i); for (var i = _textureGroups.Count - 1; i >= 0; i--) { var group = _textureGroups[i]; for (var j = group.sceneItems.Count - 1; j >= 0; j--) { if (group.sceneItems[j].item == null) group.sceneItems.RemoveAt(j); } if (group.sceneItems.Count == 0) _textureGroups.RemoveAt(i); } GetTotalPixel(); } private void GetTotalPixel() { _totalPixel = 0; if (_textureGroups != null) { for (var i = 0; i < _textureGroups.Count; i++) { var texture = _textureGroups[i].id; if (texture != null) _totalPixel += texture.width * texture.height; } } } private void OnGUI() { // ******** Header ******** GUILayout.Space(10f); GUILayout.BeginHorizontal(); if (GUILayout.Button("扫描物体", GUILayout.Width(80f))) ScanSceneObject(); GUILayout.Space(10f); if (GUILayout.Button("清除空项", GUILayout.Width(80f))) RemoveEmpty(); GUILayout.Space(10f); if (GUILayout.Button("清除所有", GUILayout.Width(80f))) CleanSceneObjects(); GUILayout.EndHorizontal(); var refresh = 0; var hideAllBut = -1; if (_textureGroups != null) { GUILayout.Space(10f); GUILayout.Label("******** 贴图总数:" + _textureGroups.Count + ", 总像素:" + _totalPixel.ToString("N0")); GUILayout.Space(5f); GUILayout.BeginHorizontal(); if (GUILayout.Button("显示所有", GUILayout.Width(80f))) { RemoveEmpty(); for (var i = 0; i < _itemRecords.Count; i++) _itemRecords[i].item.enabled = true; } GUILayout.Space(10f); if (GUILayout.Button("隐藏所有", GUILayout.Width(80f))) { RemoveEmpty(); for (var i = 0; i < _itemRecords.Count; i++) _itemRecords[i].item.enabled = false; } GUILayout.EndHorizontal(); GUILayout.Space(10f); _scrollPos = GUILayout.BeginScrollView(_scrollPos); for (var i = 0; i < _textureGroups.Count; i++) { refresh = _textureGroups[i].OnGUI(); if (refresh > 0) { if (refresh == 1) hideAllBut = i; break; } if (i < _textureGroups.Count - 1) GUILayout.Space(10f); } GUILayout.EndScrollView(); if (refresh > 0) { SceneTextureGroup remain = null; if (hideAllBut > -1) remain = _textureGroups[hideAllBut]; RemoveEmpty(); if (remain != null) for (var i = 0; i < _itemRecords.Count; i++) _itemRecords[i].item.enabled = remain.sceneItems.Contains(_itemRecords[i]); EditorSceneManager.MarkAllScenesDirty(); } } } } public class SceneTextureGroup : ListItemBase { public List sceneItems = new List(); public bool expand; public int OnGUI() { var refresh = 0; GUILayout.Label("******** 贴图显示: " + id.name + " " + id.width + " x " + id.height + " 引用物体:" + sceneItems.Count); EditorGUILayout.ObjectField("Texture", id, typeof(Texture2D), false); var show = expand; GUILayout.BeginHorizontal(); GUILayout.Space(3f); if (expand) { if (GUILayout.Button("隐藏列表", GUILayout.Width(80f))) expand = false; } else { if (GUILayout.Button("显示列表", GUILayout.Width(80f))) expand = true; } GUILayout.Space(3f); if (GUILayout.Button("显示物体", GUILayout.Width(80f))) SetEnable(true); if (GUILayout.Button("隐藏其他", GUILayout.Width(80f))) refresh = 1; GUILayout.Space(3f); if (GUILayout.Button("隐藏物体", GUILayout.Width(80f))) SetEnable(false); GUILayout.Space(30f); if (GUILayout.Button("删除贴图", GUILayout.Width(80f))) { refresh = 2; for (var i = 0; i < sceneItems.Count; i++) { var sceneItem = sceneItems[i]; if (sceneItem.item != null) { Object.DestroyImmediate(sceneItem.item); sceneItem.item = null; } } } GUILayout.EndHorizontal(); if (show) { GUILayout.Space(5f); GUILayout.BeginHorizontal(); GUILayout.Space(10f); GUILayout.BeginVertical(); for (var i = 0; i < sceneItems.Count; i++) { sceneItems[i].OnGUI(); if (i < sceneItems.Count - 1) GUILayout.Space(3f); } GUILayout.EndVertical(); GUILayout.EndHorizontal(); } GUILayout.Label("******** 贴图显示结束 ********"); return refresh; } private void SetEnable(bool isEnable) { for (var i = sceneItems.Count - 1; i >= 0; i--) { if (sceneItems[i].item == null) sceneItems.RemoveAt(i); else sceneItems[i].item.enabled = isEnable; } } } public class SceneItemRecord { public Renderer item; public SceneItemRecord(Renderer item) { this.item = item; } public void OnGUI() { EditorGUILayout.ObjectField("GameObject", item.gameObject, typeof(GameObject), false); } }