在项目的开发过程中,经常需要检查场景中所用到的资源,例如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实用脚本(二)—— 检查场景中用到的资源相关推荐

  1. 高cpu_实用脚本:检查高 CPU / 内存消耗进程 | Linux 中国

    本教程中包含两个脚本,它们可以帮助你确定 Linux 上高 CPU/内存消耗进程的运行时间. • 来源:linux.cn • 作者:Magesh Maruthamuthu • 译者:geekpi • ...

  2. Unity3D制作3D虚拟漫游场景(二)

    传送门: Unity3D制作3D虚拟漫游场景(一) -------------------------------------------------------------------------- ...

  3. unity3d 挂载脚本_Unity3D 全局脚本

    我们知道Unity3D在是可以创建游戏场景的,在每个游戏场景中又可以创建游戏对象,把每个场景的游戏对象融合在一起就是一款3D游戏.游戏场景之间属于同等级的关系,为了让游戏场景之前交互我们需要有一个凌驾 ...

  4. Python实用脚本实践

    Python实用脚本实践 一.文件相关 查找文件 import os path = 'xxx' files = os.listdir(path)for f in files:if f.endswith ...

  5. 109个shell实用脚本

    109个shell实用脚本 1.Dos 攻击防范(自动屏蔽攻击 IP) #!/bin/bash DATE=$(date +%d/%b/%Y:%H:%M) LOG_FILE=/usr/local/ngi ...

  6. 手把手教你用 Python 编写 3 个实用脚本,早掌握早下班~

    脚本写的好,下班下得早!程序员一大特长就是用程序实现自动化脚本,让枯燥.重复的工作自动执行- 能否写出高效实用的脚本代码,直接影响着一个程序员的幸福生活 [下班时间].今天我们就手把手教你用 Pyth ...

  7. Unity3D 全局脚本

    我们知道Unity3D在是可以创建游戏场景的,在每个游戏场景中又可以创建游戏对象,把每个场景的游戏对象融合在一起就是一款3D游戏.游戏场景之间属于同等级的关系,为了让游戏场景之前交互我们需要有一个凌驾 ...

  8. [转贴]JavaScript 实用脚本

    JavaScript 实用脚本 如果你找的javascript的东西的话,建议你 ctrl+F  直接在这个页上找,因为这里80%有你要找的,但是要让你挨着看的话,你就准备看完就去配眼镜!! 事件源对 ...

  9. JavaScript 实用脚本,很好,珍藏起来[转贴]

    JavaScript 实用脚本,很好,珍藏起来[转贴] 因为这两篇太安逸了,东西很多,很实用,所以转到我格子里! 总的来说,如果你要找js 的东西,而不看这两篇的话,肯定要多花好多时间!!哈哈!! 如 ...

最新文章

  1. Allegro替换过孔类型
  2. delphi中覆盖最大化消息
  3. C语言*在变量前 **p,C语言之指针*p++和*(p++)区别
  4. Vue(二十一)使用express模拟接口数据
  5. linux内核启动后门,Linux内核模块入门之简单内核后门
  6. matlab求RMSECV,CARS 用于matlab模式识别(分类和回归)的特征变量提取方法 联合开发网 - pudn.com...
  7. 卡诺模型案例分析_3个维度看竞品分析!
  8. 重庆的计算机学校排名2015,2015年计算机考研学校排名
  9. 为SSD加速 实战4KB对齐技巧1/3
  10. Vue 事件绑定 事件修饰符 条件判断 循环遍历
  11. 基本数据类型及其对应的包装类
  12. 图像效果的一些专业测试工具和指标:
  13. 测试用例方法--等价类划分法
  14. mac上超好用的文字转语音工具【迅捷文字转语音】
  15. 朗强:连接电脑的HDMI线输入电视上没有反应是什么原因?
  16. 求两点之间的最短路径
  17. 前端 - excel导入 / 导出功能
  18. 这些年我要读的书【不断更新中】
  19. 这个传奇大佬,自杀了!
  20. 树或者二叉树的度怎么算??

热门文章

  1. 搞深度学习用什么笔记本最好?这份报告给你选出了性价比之王
  2. 一文搞定敏捷项目管理精华,40张PPT直接拿去
  3. AD(十三)利用IPC快速创建元件封装
  4. 华东政法大学教学管理系统_华东政法大学教学管理系统(华政研究生管理信息系统)...
  5. win10下运行exe文件
  6. 苹果CMS10灰色高端电影网站模板源码可对接公众号
  7. 玉溪农业职业技术学院公寓维修改造项目竞争性谈判公告
  8. EditPlus的安装与破解
  9. js 获取input 中name值的问题
  10. php任意文件删除漏洞,myblog/phpyun4.3任意文件删除漏洞.md at master · source-trace/myblog · GitHub...