Unity3D实用脚本(二)—— 检查场景中用到的资源

来源:互联网 发布:如何搜索二次元软件 编辑:程序博客网 时间:2024/05/20 09:22

在项目的开发过程中,经常需要检查场景中所用到的资源,例如Textures,Materials,Meshs等。

今天来实现如图所示的资源检查功能。


代码如下:

// Resource Checker// (c) 2012 Simon Oliver / HandCircus / hello@handcircus.com// Public domain, do with whatever you like, commercial or not// This comes with no warranty, use at your own risk!// https://github.com/handcircus/Unity-Resource-Checkerusing System.Linq;using UnityEngine;using UnityEditor;using System.Collections.Generic;public class TextureDetails{public bool isCubeMap;public int memSizeKB;public Texture texture;public TextureFormat format;public int mipMapCount;public List<Object> FoundInMaterials=new List<Object>();public List<Object> FoundInRenderers=new List<Object>();public TextureDetails(){}};public class MaterialDetails{public Material material;public List<Renderer> FoundInRenderers=new List<Renderer>();public MaterialDetails(){}};public class MeshDetails{public Mesh mesh;public List<MeshFilter> FoundInMeshFilters=new List<MeshFilter>();public List<SkinnedMeshRenderer> FoundInSkinnedMeshRenderer=new List<SkinnedMeshRenderer>();public MeshDetails(){}};public class ResourceChecker : EditorWindow {string[] inspectToolbarStrings = {"Textures", "Materials","Meshes"};enum InspectType {Textures,Materials,Meshes};InspectType ActiveInspectType=InspectType.Textures;float ThumbnailWidth=40;float ThumbnailHeight=40;List<TextureDetails> ActiveTextures=new List<TextureDetails>();List<MaterialDetails> ActiveMaterials=new List<MaterialDetails>();List<MeshDetails> ActiveMeshDetails=new List<MeshDetails>();Vector2 textureListScrollPos=new Vector2(0,0);Vector2 materialListScrollPos=new Vector2(0,0);Vector2 meshListScrollPos=new Vector2(0,0);int TotalTextureMemory=0;int TotalMeshVertices=0;bool ctrlPressed=false;static int MinWidth=455;    [MenuItem ("Custom/Resource Checker")]    static void Init (){          ResourceChecker window = (ResourceChecker) EditorWindow.GetWindow (typeof (ResourceChecker));window.CheckResources();window.minSize=new Vector2(MinWidth,300);    }        void OnGUI (){if (GUILayout.Button("Refresh")) CheckResources();GUILayout.BeginHorizontal();GUILayout.Label("Materials "+ActiveMaterials.Count);GUILayout.Label("Textures "+ActiveTextures.Count+" - "+FormatSizeString(TotalTextureMemory));GUILayout.Label("Meshes "+ActiveMeshDetails.Count+" - "+TotalMeshVertices+" verts");GUILayout.EndHorizontal();ActiveInspectType=(InspectType)GUILayout.Toolbar((int)ActiveInspectType,inspectToolbarStrings);ctrlPressed=Event.current.control || Event.current.command;switch (ActiveInspectType){case InspectType.Textures:ListTextures();break;case InspectType.Materials:ListMaterials();break;case InspectType.Meshes:ListMeshes();break;}}int GetBitsPerPixel(TextureFormat format){switch (format){case TextureFormat.Alpha8: // Alpha-only texture format.return 8;case TextureFormat.ARGB4444: // A 16 bits/pixel texture format. Texture stores color with an alpha channel.return 16;case TextureFormat.RGBA4444: // A 16 bits/pixel texture format.return 16;case TextureFormat.RGB24:// A color texture format.return 24;case TextureFormat.RGBA32://Color with an alpha channel texture format.return 32;case TextureFormat.ARGB32://Color with an alpha channel texture format.return 32;case TextureFormat.RGB565:// A 16 bit color texture format.return 16;case TextureFormat.DXT1:// Compressed color texture format.return 4;case TextureFormat.DXT5:// Compressed color with alpha channel texture format.return 8;/*case TextureFormat.WiiI4:// Wii texture format.case TextureFormat.WiiI8:// Wii texture format. Intensity 8 bit.case TextureFormat.WiiIA4:// Wii texture format. Intensity + Alpha 8 bit (4 + 4).case TextureFormat.WiiIA8:// Wii texture format. Intensity + Alpha 16 bit (8 + 8).case TextureFormat.WiiRGB565:// Wii texture format. RGB 16 bit (565).case TextureFormat.WiiRGB5A3:// Wii texture format. RGBA 16 bit (4443).case TextureFormat.WiiRGBA8:// Wii texture format. RGBA 32 bit (8888).case TextureFormat.WiiCMPR:// Compressed Wii texture format. 4 bits/texel, ~RGB8A1 (Outline alpha is not currently supported).return 0;  //Not supported yet*/case TextureFormat.PVRTC_RGB2:// PowerVR (iOS) 2 bits/pixel compressed color texture format.return 2;case TextureFormat.PVRTC_RGBA2:// PowerVR (iOS) 2 bits/pixel compressed with alpha channel texture formatreturn 2;case TextureFormat.PVRTC_RGB4:// PowerVR (iOS) 4 bits/pixel compressed color texture format.return 4;case TextureFormat.PVRTC_RGBA4:// PowerVR (iOS) 4 bits/pixel compressed with alpha channel texture formatreturn 4;case TextureFormat.ETC_RGB4:// ETC (GLES2.0) 4 bits/pixel compressed RGB texture format.return 4;case TextureFormat.ATC_RGB4:// ATC (ATITC) 4 bits/pixel compressed RGB texture format.return 4;case TextureFormat.ATC_RGBA8:// ATC (ATITC) 8 bits/pixel compressed RGB texture format.return 8;case TextureFormat.BGRA32:// Format returned by iPhone camerareturn 32;//case TextureFormat.ATF_RGB_DXT1:// Flash-specific RGB DXT1 compressed color texture format.//case TextureFormat.ATF_RGBA_JPG:// Flash-specific RGBA JPG-compressed color texture format.//case TextureFormat.ATF_RGB_JPG:// Flash-specific RGB JPG-compressed color texture format.//return 0; //Not supported yet}return 0;}int CalculateTextureSizeBytes(Texture tTexture){int tWidth=tTexture.width;int tHeight=tTexture.height;if (tTexture is Texture2D){Texture2D tTex2D=tTexture as Texture2D; int bitsPerPixel=GetBitsPerPixel(tTex2D.format);int mipMapCount=tTex2D.mipmapCount;int mipLevel=1;int tSize=0;while (mipLevel<=mipMapCount){tSize+=tWidth*tHeight*bitsPerPixel/8;tWidth=tWidth/2;tHeight=tHeight/2;mipLevel++;}return tSize;}if (tTexture is Cubemap){Cubemap tCubemap=tTexture as Cubemap; int bitsPerPixel=GetBitsPerPixel(tCubemap.format);return tWidth*tHeight*6*bitsPerPixel/8;}return 0;}void SelectObject(Object selectedObject,bool append){if (append){List<Object> currentSelection=new List<Object>(Selection.objects);// Allow toggle selectionif (currentSelection.Contains(selectedObject)) currentSelection.Remove(selectedObject);else currentSelection.Add(selectedObject);Selection.objects=currentSelection.ToArray();}else Selection.activeObject=selectedObject;}void SelectObjects(List<Object> selectedObjects,bool append){if (append){List<Object> currentSelection=new List<Object>(Selection.objects);currentSelection.AddRange(selectedObjects);Selection.objects=currentSelection.ToArray();}else Selection.objects=selectedObjects.ToArray();}void ListTextures(){textureListScrollPos = EditorGUILayout.BeginScrollView(textureListScrollPos);foreach (TextureDetails tDetails in ActiveTextures){GUILayout.BeginHorizontal ();GUILayout.Box(tDetails.texture, GUILayout.Width(ThumbnailWidth), GUILayout.Height(ThumbnailHeight));if(GUILayout.Button(tDetails.texture.name,GUILayout.Width(150))){SelectObject(tDetails.texture,ctrlPressed);}string sizeLabel=""+tDetails.texture.width+"x"+tDetails.texture.height;if (tDetails.isCubeMap) sizeLabel+="x6";sizeLabel+=" - "+tDetails.mipMapCount+"mip";sizeLabel+="\n"+FormatSizeString(tDetails.memSizeKB)+" - "+tDetails.format+"";GUILayout.Label (sizeLabel,GUILayout.Width(120));if(GUILayout.Button(tDetails.FoundInMaterials.Count+" Mat",GUILayout.Width(50))){SelectObjects(tDetails.FoundInMaterials,ctrlPressed);}if(GUILayout.Button(tDetails.FoundInRenderers.Count+" GO",GUILayout.Width(50))){List<Object> FoundObjects=new List<Object>();foreach (Renderer renderer in tDetails.FoundInRenderers) FoundObjects.Add(renderer.gameObject);SelectObjects(FoundObjects,ctrlPressed);}GUILayout.EndHorizontal();}if (ActiveTextures.Count>0){GUILayout.BeginHorizontal ();GUILayout.Box(" ",GUILayout.Width(ThumbnailWidth),GUILayout.Height(ThumbnailHeight));if(GUILayout.Button("Select All",GUILayout.Width(150))){List<Object> AllTextures=new List<Object>();foreach (TextureDetails tDetails in ActiveTextures) AllTextures.Add(tDetails.texture);SelectObjects(AllTextures,ctrlPressed);}EditorGUILayout.EndHorizontal();}EditorGUILayout.EndScrollView();    }void ListMaterials(){materialListScrollPos = EditorGUILayout.BeginScrollView(materialListScrollPos);foreach (MaterialDetails tDetails in ActiveMaterials){if (tDetails.material!=null){GUILayout.BeginHorizontal ();if (tDetails.material.mainTexture!=null) GUILayout.Box(tDetails.material.mainTexture, GUILayout.Width(ThumbnailWidth), GUILayout.Height(ThumbnailHeight));else{GUILayout.Box("n/a",GUILayout.Width(ThumbnailWidth),GUILayout.Height(ThumbnailHeight));}if(GUILayout.Button(tDetails.material.name,GUILayout.Width(150))){SelectObject(tDetails.material,ctrlPressed);}string shaderLabel = tDetails.material.shader != null ? tDetails.material.shader.name : "no shader";GUILayout.Label (shaderLabel, GUILayout.Width(200));if(GUILayout.Button(tDetails.FoundInRenderers.Count+" GO",GUILayout.Width(50))){List<Object> FoundObjects=new List<Object>();foreach (Renderer renderer in tDetails.FoundInRenderers) FoundObjects.Add(renderer.gameObject);SelectObjects(FoundObjects,ctrlPressed);}GUILayout.EndHorizontal();}}EditorGUILayout.EndScrollView();    }void ListMeshes(){meshListScrollPos = EditorGUILayout.BeginScrollView(meshListScrollPos);foreach (MeshDetails tDetails in ActiveMeshDetails){if (tDetails.mesh!=null){GUILayout.BeginHorizontal ();/*if (tDetails.material.mainTexture!=null) GUILayout.Box(tDetails.material.mainTexture, GUILayout.Width(ThumbnailWidth), GUILayout.Height(ThumbnailHeight));else{GUILayout.Box("n/a",GUILayout.Width(ThumbnailWidth),GUILayout.Height(ThumbnailHeight));}*/if(GUILayout.Button(tDetails.mesh.name,GUILayout.Width(150))){SelectObject(tDetails.mesh,ctrlPressed);}string sizeLabel=""+tDetails.mesh.vertexCount+" vert";GUILayout.Label (sizeLabel,GUILayout.Width(100));if(GUILayout.Button(tDetails.FoundInMeshFilters.Count + " GO",GUILayout.Width(50))){List<Object> FoundObjects=new List<Object>();foreach (MeshFilter meshFilter in tDetails.FoundInMeshFilters) FoundObjects.Add(meshFilter.gameObject);SelectObjects(FoundObjects,ctrlPressed);}if(GUILayout.Button(tDetails.FoundInSkinnedMeshRenderer.Count + " GO",GUILayout.Width(50))){List<Object> FoundObjects=new List<Object>();foreach (SkinnedMeshRenderer skinnedMeshRenderer in tDetails.FoundInSkinnedMeshRenderer) FoundObjects.Add(skinnedMeshRenderer.gameObject);SelectObjects(FoundObjects,ctrlPressed);}GUILayout.EndHorizontal();}}EditorGUILayout.EndScrollView();    }string FormatSizeString(int memSizeKB){if (memSizeKB<1024) return ""+memSizeKB+"k";else{float memSizeMB=((float)memSizeKB)/1024.0f;return memSizeMB.ToString("0.00")+"Mb";}}TextureDetails FindTextureDetails(Texture tTexture){foreach (TextureDetails tTextureDetails in ActiveTextures){if (tTextureDetails.texture==tTexture) return tTextureDetails;}return null;}MaterialDetails FindMaterialDetails(Material tMaterial){foreach (MaterialDetails tMaterialDetails in ActiveMaterials){if (tMaterialDetails.material==tMaterial) return tMaterialDetails;}return null;}MeshDetails FindMeshDetails(Mesh tMesh){foreach (MeshDetails tMeshDetails in ActiveMeshDetails){if (tMeshDetails.mesh==tMesh) return tMeshDetails;}return null;}void CheckResources(){ActiveTextures.Clear();ActiveMaterials.Clear();ActiveMeshDetails.Clear();Renderer[] renderers = (Renderer[]) FindObjectsOfType(typeof(Renderer));//Debug.Log("Total renderers "+renderers.Length);foreach (Renderer renderer in renderers){//Debug.Log("Renderer is "+renderer.name);foreach (Material material in renderer.sharedMaterials){MaterialDetails tMaterialDetails=FindMaterialDetails(material);if (tMaterialDetails==null){tMaterialDetails=new MaterialDetails();tMaterialDetails.material=material;ActiveMaterials.Add(tMaterialDetails);}tMaterialDetails.FoundInRenderers.Add(renderer);}}foreach (MaterialDetails tMaterialDetails in ActiveMaterials){Material tMaterial=tMaterialDetails.material;var dependencies = EditorUtility.CollectDependencies(new UnityEngine.Object[] {tMaterial});foreach (Object obj in dependencies)    {if (obj is Texture){Texture tTexture=obj as Texture;var tTextureDetail = GetTextureDetail(tTexture, tMaterial, tMaterialDetails);ActiveTextures.Add(tTextureDetail);}    }//if the texture was downloaded, it won't be included in the editor dependenciesif (tMaterial.mainTexture != null && !dependencies.Contains(tMaterial.mainTexture)){var tTextureDetail = GetTextureDetail(tMaterial.mainTexture, tMaterial, tMaterialDetails);ActiveTextures.Add(tTextureDetail);}}MeshFilter[] meshFilters = (MeshFilter[]) FindObjectsOfType(typeof(MeshFilter));foreach (MeshFilter tMeshFilter in meshFilters){Mesh tMesh=tMeshFilter.sharedMesh;if (tMesh!=null){MeshDetails tMeshDetails=FindMeshDetails(tMesh);if (tMeshDetails==null){tMeshDetails=new MeshDetails();tMeshDetails.mesh=tMesh;ActiveMeshDetails.Add(tMeshDetails);}tMeshDetails.FoundInMeshFilters.Add(tMeshFilter);}}SkinnedMeshRenderer[] skinnedMeshRenderers = (SkinnedMeshRenderer[]) FindObjectsOfType(typeof(SkinnedMeshRenderer));foreach (SkinnedMeshRenderer tSkinnedMeshRenderer in skinnedMeshRenderers){Mesh tMesh=tSkinnedMeshRenderer.sharedMesh;if (tMesh!=null){MeshDetails tMeshDetails=FindMeshDetails(tMesh);if (tMeshDetails==null){tMeshDetails=new MeshDetails();tMeshDetails.mesh=tMesh;ActiveMeshDetails.Add(tMeshDetails);}tMeshDetails.FoundInSkinnedMeshRenderer.Add(tSkinnedMeshRenderer);}}TotalTextureMemory=0;foreach (TextureDetails tTextureDetails in ActiveTextures) TotalTextureMemory+=tTextureDetails.memSizeKB;TotalMeshVertices=0;foreach (MeshDetails tMeshDetails in ActiveMeshDetails) TotalMeshVertices+=tMeshDetails.mesh.vertexCount;// Sort by size, descendingActiveTextures.Sort(delegate(TextureDetails details1, TextureDetails details2) {return details2.memSizeKB-details1.memSizeKB;});ActiveMeshDetails.Sort(delegate(MeshDetails details1, MeshDetails details2) {return details2.mesh.vertexCount-details1.mesh.vertexCount;});}private TextureDetails GetTextureDetail(Texture tTexture, Material tMaterial, MaterialDetails tMaterialDetails){TextureDetails tTextureDetails = FindTextureDetails(tTexture);if (tTextureDetails == null){tTextureDetails = new TextureDetails();tTextureDetails.texture = tTexture;tTextureDetails.isCubeMap = tTexture is Cubemap;int memSize = CalculateTextureSizeBytes(tTexture);tTextureDetails.memSizeKB = memSize / 1024;TextureFormat tFormat = TextureFormat.RGBA32;int tMipMapCount = 1;if (tTexture is Texture2D){tFormat = (tTexture as Texture2D).format;tMipMapCount = (tTexture as Texture2D).mipmapCount;}if (tTexture is Cubemap){tFormat = (tTexture as Cubemap).format;}tTextureDetails.format = tFormat;tTextureDetails.mipMapCount = tMipMapCount;}tTextureDetails.FoundInMaterials.Add(tMaterial);foreach (Renderer renderer in tMaterialDetails.FoundInRenderers){if (!tTextureDetails.FoundInRenderers.Contains(renderer)) tTextureDetails.FoundInRenderers.Add(renderer);}return tTextureDetails;}}

原创粉丝点击