Files
JJBB/Assets/Editor/Scripts/Scene/SceneTextureAnalyze.cs
2024-08-23 15:49:34 +08:00

271 lines
9.0 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Collections.Generic;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.SceneManagement;
public class SceneTextureAnalyze : EditorWindow
{
private List<SceneTextureGroup> _textureGroups;
private List<SceneItemRecord> _itemRecords;
private Vector2 _scrollPos;
private long _totalPixel;
[MenuItem("Scene/Texture Analyzer")]
public static void OpenWindow()
{
GetWindow<SceneTextureAnalyze>();
}
private void ScanSceneObject()
{
_textureGroups = new List<SceneTextureGroup>();
_itemRecords = new List<SceneItemRecord>();
_scrollPos = Vector2.zero;
var renderers = FindObjectsOfType<Renderer>();
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<Texture2D>
{
public List<SceneItemRecord> sceneItems = new List<SceneItemRecord>();
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);
}
}