Unity3D实用脚本(二)—— 检查场景中用到的资源
在项目的开发过程中,经常需要检查场景中所用到的资源,例如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;}
}
Unity3D实用脚本(二)—— 检查场景中用到的资源相关推荐
- 高cpu_实用脚本:检查高 CPU / 内存消耗进程 | Linux 中国
本教程中包含两个脚本,它们可以帮助你确定 Linux 上高 CPU/内存消耗进程的运行时间. • 来源:linux.cn • 作者:Magesh Maruthamuthu • 译者:geekpi • ...
- Unity3D制作3D虚拟漫游场景(二)
传送门: Unity3D制作3D虚拟漫游场景(一) -------------------------------------------------------------------------- ...
- unity3d 挂载脚本_Unity3D 全局脚本
我们知道Unity3D在是可以创建游戏场景的,在每个游戏场景中又可以创建游戏对象,把每个场景的游戏对象融合在一起就是一款3D游戏.游戏场景之间属于同等级的关系,为了让游戏场景之前交互我们需要有一个凌驾 ...
- Python实用脚本实践
Python实用脚本实践 一.文件相关 查找文件 import os path = 'xxx' files = os.listdir(path)for f in files:if f.endswith ...
- 109个shell实用脚本
109个shell实用脚本 1.Dos 攻击防范(自动屏蔽攻击 IP) #!/bin/bash DATE=$(date +%d/%b/%Y:%H:%M) LOG_FILE=/usr/local/ngi ...
- 手把手教你用 Python 编写 3 个实用脚本,早掌握早下班~
脚本写的好,下班下得早!程序员一大特长就是用程序实现自动化脚本,让枯燥.重复的工作自动执行- 能否写出高效实用的脚本代码,直接影响着一个程序员的幸福生活 [下班时间].今天我们就手把手教你用 Pyth ...
- Unity3D 全局脚本
我们知道Unity3D在是可以创建游戏场景的,在每个游戏场景中又可以创建游戏对象,把每个场景的游戏对象融合在一起就是一款3D游戏.游戏场景之间属于同等级的关系,为了让游戏场景之前交互我们需要有一个凌驾 ...
- [转贴]JavaScript 实用脚本
JavaScript 实用脚本 如果你找的javascript的东西的话,建议你 ctrl+F 直接在这个页上找,因为这里80%有你要找的,但是要让你挨着看的话,你就准备看完就去配眼镜!! 事件源对 ...
- JavaScript 实用脚本,很好,珍藏起来[转贴]
JavaScript 实用脚本,很好,珍藏起来[转贴] 因为这两篇太安逸了,东西很多,很实用,所以转到我格子里! 总的来说,如果你要找js 的东西,而不看这两篇的话,肯定要多花好多时间!!哈哈!! 如 ...
最新文章
- Allegro替换过孔类型
- delphi中覆盖最大化消息
- C语言*在变量前 **p,C语言之指针*p++和*(p++)区别
- Vue(二十一)使用express模拟接口数据
- linux内核启动后门,Linux内核模块入门之简单内核后门
- matlab求RMSECV,CARS 用于matlab模式识别(分类和回归)的特征变量提取方法 联合开发网 - pudn.com...
- 卡诺模型案例分析_3个维度看竞品分析!
- 重庆的计算机学校排名2015,2015年计算机考研学校排名
- 为SSD加速 实战4KB对齐技巧1/3
- Vue 事件绑定 事件修饰符 条件判断 循环遍历
- 基本数据类型及其对应的包装类
- 图像效果的一些专业测试工具和指标:
- 测试用例方法--等价类划分法
- mac上超好用的文字转语音工具【迅捷文字转语音】
- 朗强:连接电脑的HDMI线输入电视上没有反应是什么原因?
- 求两点之间的最短路径
- 前端 - excel导入 / 导出功能
- 这些年我要读的书【不断更新中】
- 这个传奇大佬,自杀了!
- 树或者二叉树的度怎么算??
热门文章
- 搞深度学习用什么笔记本最好?这份报告给你选出了性价比之王
- 一文搞定敏捷项目管理精华,40张PPT直接拿去
- AD(十三)利用IPC快速创建元件封装
- 华东政法大学教学管理系统_华东政法大学教学管理系统(华政研究生管理信息系统)...
- win10下运行exe文件
- 苹果CMS10灰色高端电影网站模板源码可对接公众号
- 玉溪农业职业技术学院公寓维修改造项目竞争性谈判公告
- EditPlus的安装与破解
- js 获取input 中name值的问题
- php任意文件删除漏洞,myblog/phpyun4.3任意文件删除漏洞.md at master · source-trace/myblog · GitHub...