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;}}
阅读全文
0 0
- Unity3D实用脚本(二)—— 检查场景中用到的资源
- Unity3D实用脚本(一)—— 导出场景中的3D资源到本地为.obj格式
- zookeeper的实用场景—
- zookeeper的实用场景二
- [unity3d]从服务器端获取资源动态加载到场景
- [unity3d]从服务器端获取资源动态加载到场景
- Unity3D【脚本】 异步切换场景,显示进度到滚动条
- 项目中用到的Shell脚本(部分)
- 为什么Unity3d中看到的场景很小?
- android中用到的资源Color
- Osg 实例中用到的资源
- js一个项目中用到的脚本
- 一些工作中用到的脚本
- Unity3D 场景平移、缩放(二)
- unity3d Game场景漫游脚本
- Unity中用到的C#补充(二)-面向对象
- Unity微端场景加载(二)场景资源的下载和显示
- Unity3D中角色的动画脚本的编写(二)
- 657. Judge Route Circle
- 17ANoldbach problem
- Python基础-高阶函数-Higher-order function
- 查找算法
- 省选专练APIO2009抢掠计划
- Unity3D实用脚本(二)—— 检查场景中用到的资源
- POJ 刷题系列:3006. Dirichlet's Theorem on Arithmetic Progressions
- 欢迎使用CSDN-markdown编辑器
- css3
- java常用的框架介绍
- 十九大总结
- Tcp/Ip理论基础
- Window系统生成CXF Webservice客户端
- 两种网络请求