这个插件是我在国外网站逛论坛发现的,试用了一下非常好用,是一个轻量级的插件就一个类。开发中尤其是和美术合作的时候,可能你会发现Project视图中有很多没有用到的资源,但是你又不敢删除,因为你不知道那些资源是没用到的,那些资源是用到的。这时候ResourceChecker可以帮上大忙。

gitHub地址:https://github.com/handcircus/Unity-Resource-Checker

将ResourceChecker放在Project视图中的Editor文件夹中,如果没有该文件夹就创建一个。如下图所示,在Unity导航菜单栏中选择 Windows -> Resource Checker 即可呼出窗口。

在Textures选项卡最下面点击 Select Al l 可在Project视图中展开目录结构,这时候你删除没有选中的文件就可以。。 

定位贴图、材质、网格。定位所有文件,总这这个小插件你值得拥有!

代码如下:

using UnityEngine;

using UnityEditor;

using System.Collections.Generic;

public class TextureDetails

{

public bool isCubeMap;

public int memSizeKB;

publicTexture texture;

publicTextureFormat format;

public int mipMapCount;

public List<Object> FoundInMaterials=new List<Object>();

public List<Object> FoundInRenderers=new List<Object>();

public TextureDetails()

{

}

};

public class MaterialDetails

{

publicMaterial material;

public List<Renderer> FoundInRenderers=new List<Renderer>();

public MaterialDetails()

{

}

};

public class MeshDetails

{

publicMesh mesh;

public List<MeshFilter> FoundInMeshFilters=new List<MeshFilter>();

public List<SkinnedMeshRenderer> FoundInSkinnedMeshRenderer=new List<SkinnedMeshRenderer>();

public MeshDetails()

{

}

};

publicclass 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 ("Window/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)

{

caseTextureFormat.Alpha8: // Alpha-only texture format.

return 8;

caseTextureFormat.ARGB4444: // A 16 bits/pixel texture format. Texture stores color with an alpha channel.

return 16;

caseTextureFormat.RGB24:// A color texture format.

return 24;

caseTextureFormat.RGBA32://Color with an alpha channel texture format.

return 32;

caseTextureFormat.ARGB32://Color with an alpha channel texture format.

return 32;

caseTextureFormat.RGB565:// A 16 bit color texture format.

return 16;

caseTextureFormat.DXT1:// Compressed color texture format.

return 4;

caseTextureFormat.DXT5:// Compressed color with alpha channel texture format.

return 8;

/*

caseTextureFormat.WiiI4:// Wii texture format.

caseTextureFormat.WiiI8:// Wii texture format. Intensity 8 bit.

caseTextureFormat.WiiIA4:// Wii texture format. Intensity + Alpha 8 bit (4 + 4).

caseTextureFormat.WiiIA8:// Wii texture format. Intensity + Alpha 16 bit (8 + 8).

caseTextureFormat.WiiRGB565:// Wii texture format. RGB 16 bit (565).

caseTextureFormat.WiiRGB5A3:// Wii texture format. RGBA 16 bit (4443).

caseTextureFormat.WiiRGBA8:// Wii texture format. RGBA 32 bit (8888).

caseTextureFormat.WiiCMPR:// Compressed Wii texture format. 4 bits/texel, ~RGB8A1 (Outline alpha is not currently supported).

return0;  //Not supported yet

*/

caseTextureFormat.PVRTC_RGB2:// PowerVR (iOS) 2 bits/pixel compressed color texture format.

return 2;

caseTextureFormat.PVRTC_RGBA2:// PowerVR (iOS) 2 bits/pixel compressed with alpha channel texture format

return 2;

caseTextureFormat.PVRTC_RGB4:// PowerVR (iOS) 4 bits/pixel compressed color texture format.

return 4;

caseTextureFormat.PVRTC_RGBA4:// PowerVR (iOS) 4 bits/pixel compressed with alpha channel texture format

return 4;

caseTextureFormat.ETC_RGB4:// ETC (GLES2.0) 4 bits/pixel compressed RGB texture format.

return 4;

caseTextureFormat.ATC_RGB4:// ATC (ATITC) 4 bits/pixel compressed RGB texture format.

return 4;

caseTextureFormat.ATC_RGBA8:// ATC (ATITC) 8 bits/pixel compressed RGB texture format.

return 8;

caseTextureFormat.BGRA32:// Format returned by iPhone camera

return 32;

caseTextureFormat.ATF_RGB_DXT1:// Flash-specific RGB DXT1 compressed color texture format.

caseTextureFormat.ATF_RGBA_JPG:// Flash-specific RGBA JPG-compressed color texture format.

caseTextureFormat.ATF_RGB_JPG:// Flash-specific RGB JPG-compressed color texture format.

return0; //Not supported yet

}

return0;

}

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;

}

return0;

}

void SelectObject(Object selectedObject,bool append)

{

if (append)

{

List<Object> currentSelection=new List<Object>(Selection.objects);

// Allow toggle selection

if (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;

}

returnnull;

}

MaterialDetails FindMaterialDetails(Material tMaterial)

{

foreach (MaterialDetails tMaterialDetails in ActiveMaterials)

{

if (tMaterialDetails.material==tMaterial) return tMaterialDetails;

}

returnnull;

}

MeshDetails FindMeshDetails(Mesh tMesh)

{

foreach (MeshDetails tMeshDetails in ActiveMeshDetails)

{

if (tMeshDetails.mesh==tMesh) return tMeshDetails;

}

returnnull;

}

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;

foreach (Object obj in EditorUtility.CollectDependencies(new UnityEngine.Object[] {tMaterial}))

{

if (obj is Texture)

{

Texture tTexture=obj as Texture;

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;

ActiveTextures.Add(tTextureDetails);

}

tTextureDetails.FoundInMaterials.Add(tMaterial);

foreach (Renderer renderer in tMaterialDetails.FoundInRenderers)

{

if (!tTextureDetails.FoundInRenderers.Contains(renderer)) tTextureDetails.FoundInRenderers.Add(renderer);

}

}

}

}

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, descending

ActiveTextures.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;});

}

}

Unity3d删除无用的美术资源的更多相关文章

  1. android删除无用资源文件的python脚本

    随着android项目的进行,如果没有及时删除无用的资源时安装包会越来越大,是时候整理一下废弃资源缩小压缩包了,少年! 其实判断一个资源(drawable,layout)是否没有被使用很简单,文件名( ...

  2. Android lint 删除无用图片文件和配置文件

    Android lint  删除无用.冗余的  配置文件和 图片资源    转载请注明  http://blog.csdn.net/aaawqqq?viewmode=contents Android项 ...

  3. iOS ipa包瘦身------删除无用图片资源

         随着客户端业务的增多和业务的更新,App包大小越来越大,优化包大小是迫在眉睫,客户端需要优化的地方也有很多,本期主要讲如何查找无用图片并且删除无用图片的方法.      方案1:(暴力方法) ...

  4. Oracle监控用户索引使用情况,删除无用索引

    监控当前业务用户索引 一段时间后查询从未被使用的索引,删除无用索引 停止监控索引 1. 监控当前用户所有索引 得到监控所有索引的语句: select 'alter index ' || index_n ...

  5. Win7系统下彻底删除无用服务的方法

    win7系统下中有非常多的服务项,用户来满足不同行业用户间的所有需求,系统服务也是执行指定系统功能的程序,许多情况下我们想要运行软件或执行外接设备都无法离开系统服务,但并非所有系统服务都是我们用到的, ...

  6. Linux - 修改内核启动顺序及删除无用内核

    现象: CentOS7开机启动界面显示多个内核选项 原因: 正常情况下,有两个启动项,一个是"正常启动",另一个是"救援模式启动"(rescue). 如果启动项 ...

  7. docker 删除无用的镜像文件的命令小计

    df -h  查看当前服务器的内存情况 docker system prune  删除无用镜像文件命令 执行ok之后,再次查看内存情况.

  8. ubuntu的boot分区报警,删除无用内核文件。

    1. 查看当前使用内核:uname -r4.4.0-97-generic 2. 查看安装的内核dpkg --list 'linux-image*' 3. 删除旧内核sudo apt-get remov ...

  9. centos7 选定默认启动内核,及删除无用内核

    #使用cat /boot/grub2/grub.cfg |grep menuentry 查看系统可用内核 [root@bigapp-slave27 ~]# cat /boot/grub2/grub.c ...

随机推荐

  1. [ucgui] 对话框4——模式消息窗口

    >_<" 这里实现点击灰色窗口的按钮出现一个模式消息窗口,点击OK之后才能再聚焦到灰窗口:点击灰窗口除了按钮的地方,弹出一个非模式窗口.

  2. spring mvc 配置对静态资源的访问

    在spring mvc的配置文件中做如下配置: 1. <?xml version="1.0" encoding="UTF-8"?> <bean ...

  3. 微软 PowerShell Script Explorer 满血复活,正式发布

    一年前的今天,微软在其Windows PowerShell官方博客声明中止 ‘Script Explorer’ 应用程序的开发. 一年后的今天,微软为其Script Explorer注入了新的生命.一 ...

  4. servlet web文件上传

    web文件上传也是一种POST方式,特别之处在于,需设置FORM的enctype属性为multipart/form-data. 并且需要使用文件域. servlet的代码比较关键是这几句: // 使用 ...

  5. JProfiler8 注册码序列号

    JProfiler_SN_8_x.txt 按默认选择"Single or evaluation license" Name 和 Company 随意 --------------- ...

  6. 连接数据库——模拟ATM机查、存、取、开户功能

    1.界面:包含开户.查询.存款.取款.功能 package com.bank.test; /** * * @author Administrator *界面类 */ public class Jiem ...

  7. (转载)新手如何正确理解GitHub中“PR(pull request)”中的意思

    我从知乎看到的两个答案,分别从实际意义以及语言学角度告诉你改怎么理解PR,很简洁,这个理解非常棒,会解决新手刚看到PR(pull request)这个词时的困惑.   实际意义:   有一个仓库,叫R ...

  8. asynchttpClient框架关于多文件批量上传的问题,改用xUtil

    RequestParams params = new RequestParams(); params.add("ordernum",ordernum); params.add(&q ...

  9. 远哥教你MuleESB系列视频教程

    远哥教你MuleESB系列视频课程介绍(共11个视频) —1.Mule ESB介绍 —2.社区版/企业版的区别和安装 —3.MuleESB快速入门,以及MEL和Message结构 —4.官方例子讲解( ...

  10. GTD时间管理(2)---管理收集箱

    通过上面一篇文章,相信大家对GTD收集有了原理大致的了解,如果大家对收集不是很了解,可以去看一下. 当我们收集到很多想法和事情之后,在晚会的时候必须要清空收集箱,否则收集箱会堆积如山,最终收集箱成了垃 ...