纳金网

标题: 删除项目中没有用到的资源 [打印本页]

作者: 狂风大尉    时间: 2014-6-28 01:50
标题: 删除项目中没有用到的资源
  1. // Resource Checker
  2. // (c) 2012 Simon Oliver / HandCircus / [email]hello@handcircus.com[/email]
  3. // Public domain, do with whatever you like, commercial or not
  4. // This comes with no warranty, use at your own risk!
  5. // https://github.com/handcircus/Unity-Resource-Checker

  6. using System.Linq;
  7. using UnityEngine;
  8. using UnityEditor;
  9. using System.Collections.Generic;


  10. public class TextureDetails
  11. {
  12.     public bool isCubeMap;
  13.     public int memSizeKB;
  14.     public Texture texture;
  15.     public TextureFormat format;
  16.     public int mipMapCount;
  17.     public List<Object> FoundInMaterials = new List<Object>();
  18.     public List<Object> FoundInRenderers = new List<Object>();
  19.     public TextureDetails()
  20.     {

  21.     }
  22. };

  23. public class MaterialDetails
  24. {

  25.     public Material material;

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

  27.     public MaterialDetails()
  28.     {

  29.     }
  30. };

  31. public class MeshDetails
  32. {

  33.     public Mesh mesh;

  34.     public List<MeshFilter> FoundInMeshFilters = new List<MeshFilter>();
  35.     public List<SkinnedMeshRenderer> FoundInSkinnedMeshRenderer = new List<SkinnedMeshRenderer>();

  36.     public MeshDetails()
  37.     {

  38.     }
  39. };

  40. public class ResourceChecker : EditorWindow
  41. {


  42.     string[] inspectToolbarStrings = { "Textures", "Materials", "Meshes" };

  43.     enum InspectType
  44.     {
  45.         Textures, Materials, Meshes
  46.     };

  47.     InspectType ActiveInspectType = InspectType.Textures;

  48.     float ThumbnailWidth = 40;
  49.     float ThumbnailHeight = 40;

  50.     List<TextureDetails> ActiveTextures = new List<TextureDetails>();
  51.     List<MaterialDetails> ActiveMaterials = new List<MaterialDetails>();
  52.     List<MeshDetails> ActiveMeshDetails = new List<MeshDetails>();

  53.     Vector2 textureListScrollPos = new Vector2(0, 0);
  54.     Vector2 materialListScrollPos = new Vector2(0, 0);
  55.     Vector2 meshListScrollPos = new Vector2(0, 0);

  56.     int TotalTextureMemory = 0;
  57.     int TotalMeshVertices = 0;

  58.     bool ctrlPressed = false;

  59.     static int MinWidth = 455;

  60.     [MenuItem("Window/Resource Checker")]
  61.     static void Init()
  62.     {
  63.         ResourceChecker window = (ResourceChecker)EditorWindow.GetWindow(typeof(ResourceChecker));
  64.         window.CheckResources();
  65.         window.minSize = new Vector2(MinWidth, 300);
  66.     }

  67.     void OnGUI()
  68.     {
  69.         if (GUILayout.Button("Refresh")) CheckResources();
  70.         GUILayout.BeginHorizontal();
  71.         GUILayout.Label("Materials " + ActiveMaterials.Count);
  72.         GUILayout.Label("Textures " + ActiveTextures.Count + " - " + FormatSizeString(TotalTextureMemory));
  73.         GUILayout.Label("Meshes " + ActiveMeshDetails.Count + " - " + TotalMeshVertices + " verts");
  74.         GUILayout.EndHorizontal();
  75.         ActiveInspectType = (InspectType)GUILayout.Toolbar((int)ActiveInspectType, inspectToolbarStrings);

  76.         ctrlPressed = Event.current.control || Event.current.command;

  77.         switch (ActiveInspectType)
  78.         {
  79.             case InspectType.Textures:
  80.                 ListTextures();
  81.                 break;
  82.             case InspectType.Materials:
  83.                 ListMaterials();
  84.                 break;
  85.             case InspectType.Meshes:
  86.                 ListMeshes();
  87.                 break;


  88.         }
  89.     }


  90.     int GetBitsPerPixel(TextureFormat format)
  91.     {
  92.         switch (format)
  93.         {
  94.             case TextureFormat.Alpha8: //    Alpha-only texture format.
  95.                 return 8;
  96.             case TextureFormat.ARGB4444: //  A 16 bits/pixel texture format. Texture stores color with an alpha channel.
  97.                 return 16;
  98.             case TextureFormat.RGBA4444: //  A 16 bits/pixel texture format.
  99.                 return 16;
  100.             case TextureFormat.RGB24:   // A color texture format.
  101.                 return 24;
  102.             case TextureFormat.RGBA32:  //Color with an alpha channel texture format.
  103.                 return 32;
  104.             case TextureFormat.ARGB32:  //Color with an alpha channel texture format.
  105.                 return 32;
  106.             case TextureFormat.RGB565:  //   A 16 bit color texture format.
  107.                 return 16;
  108.             case TextureFormat.DXT1:    // Compressed color texture format.
  109.                 return 4;
  110.             case TextureFormat.DXT5:    // Compressed color with alpha channel texture format.
  111.                 return 8;
  112.             /*
  113.             case TextureFormat.WiiI4:   // Wii texture format.
  114.             case TextureFormat.WiiI8:   // Wii texture format. Intensity 8 bit.
  115.             case TextureFormat.WiiIA4:  // Wii texture format. Intensity + Alpha 8 bit (4 + 4).
  116.             case TextureFormat.WiiIA8:  // Wii texture format. Intensity + Alpha 16 bit (8 + 8).
  117.             case TextureFormat.WiiRGB565:   // Wii texture format. RGB 16 bit (565).
  118.             case TextureFormat.WiiRGB5A3:   // Wii texture format. RGBA 16 bit (4443).
  119.             case TextureFormat.WiiRGBA8:    // Wii texture format. RGBA 32 bit (8888).
  120.             case TextureFormat.WiiCMPR: //   Compressed Wii texture format. 4 bits/texel, ~RGB8A1 (Outline alpha is not currently supported).
  121.                 return 0;  //Not supported yet
  122.             */
  123.             case TextureFormat.PVRTC_RGB2://     PowerVR (iOS) 2 bits/pixel compressed color texture format.
  124.                 return 2;
  125.             case TextureFormat.PVRTC_RGBA2://    PowerVR (iOS) 2 bits/pixel compressed with alpha channel texture format
  126.                 return 2;
  127.             case TextureFormat.PVRTC_RGB4://     PowerVR (iOS) 4 bits/pixel compressed color texture format.
  128.                 return 4;
  129.             case TextureFormat.PVRTC_RGBA4://    PowerVR (iOS) 4 bits/pixel compressed with alpha channel texture format
  130.                 return 4;
  131.             case TextureFormat.ETC_RGB4://   ETC (GLES2.0) 4 bits/pixel compressed RGB texture format.
  132.                 return 4;
  133.             case TextureFormat.ATC_RGB4://   ATC (ATITC) 4 bits/pixel compressed RGB texture format.
  134.                 return 4;
  135.             case TextureFormat.ATC_RGBA8://  ATC (ATITC) 8 bits/pixel compressed RGB texture format.
  136.                 return 8;
  137.             case TextureFormat.BGRA32://     Format returned by iPhone camera
  138.                 return 32;
  139.             case TextureFormat.ATF_RGB_DXT1://   Flash-specific RGB DXT1 compressed color texture format.
  140.             case TextureFormat.ATF_RGBA_JPG://   Flash-specific RGBA JPG-compressed color texture format.
  141.             case TextureFormat.ATF_RGB_JPG://    Flash-specific RGB JPG-compressed color texture format.
  142.                 return 0; //Not supported yet
  143.         }
  144.         return 0;
  145.     }

  146.     int CalculateTextureSizeBytes(Texture tTexture)
  147.     {

  148.         int tWidth = tTexture.width;
  149.         int tHeight = tTexture.height;
  150.         if (tTexture is Texture2D)
  151.         {
  152.             Texture2D tTex2D = tTexture as Texture2D;
  153.             int bitsPerPixel = GetBitsPerPixel(tTex2D.format);
  154.             int mipMapCount = tTex2D.mipmapCount;
  155.             int mipLevel = 1;
  156.             int tSize = 0;
  157.             while (mipLevel <= mipMapCount)
  158.             {
  159.                 tSize += tWidth * tHeight * bitsPerPixel / 8;
  160.                 tWidth = tWidth / 2;
  161.                 tHeight = tHeight / 2;
  162.                 mipLevel++;
  163.             }
  164.             return tSize;
  165.         }

  166.         if (tTexture is Cubemap)
  167.         {
  168.             Cubemap tCubemap = tTexture as Cubemap;
  169.             int bitsPerPixel = GetBitsPerPixel(tCubemap.format);
  170.             return tWidth * tHeight * 6 * bitsPerPixel / 8;
  171.         }
  172.         return 0;
  173.     }


  174.     void SelectObject(Object selectedObject, bool append)
  175.     {
  176.         if (append)
  177.         {
  178.             List<Object> currentSelection = new List<Object>(Selection.objects);
  179.             // Allow toggle selection
  180.             if (currentSelection.Contains(selectedObject)) currentSelection.Remove(selectedObject);
  181.             else currentSelection.Add(selectedObject);

  182.             Selection.objects = currentSelection.ToArray();
  183.         }
  184.         else Selection.activeObject = selectedObject;
  185.     }

  186.     void SelectObjects(List<Object> selectedObjects, bool append)
  187.     {
  188.         if (append)
  189.         {
  190.             List<Object> currentSelection = new List<Object>(Selection.objects);
  191.             currentSelection.AddRange(selectedObjects);
  192.             Selection.objects = currentSelection.ToArray();
  193.         }
  194.         else Selection.objects = selectedObjects.ToArray();
  195.     }

  196.     void ListTextures()
  197.     {
  198.         textureListScrollPos = EditorGUILayout.BeginScrollView(textureListScrollPos);

  199.         foreach (TextureDetails tDetails in ActiveTextures)
  200.         {

  201.             GUILayout.BeginHorizontal();
  202.             GUILayout.Box(tDetails.texture, GUILayout.Width(ThumbnailWidth), GUILayout.Height(ThumbnailHeight));

  203.             if (GUILayout.Button(tDetails.texture.name, GUILayout.Width(150)))
  204.             {
  205.                 SelectObject(tDetails.texture, ctrlPressed);
  206.             }

  207.             string sizeLabel = "" + tDetails.texture.width + "x" + tDetails.texture.height;
  208.             if (tDetails.isCubeMap) sizeLabel += "x6";
  209.             sizeLabel += " - " + tDetails.mipMapCount + "mip";
  210.             sizeLabel += "\n" + FormatSizeString(tDetails.memSizeKB) + " - " + tDetails.format + "";

  211.             GUILayout.Label(sizeLabel, GUILayout.Width(120));

  212.             if (GUILayout.Button(tDetails.FoundInMaterials.Count + " Mat", GUILayout.Width(50)))
  213.             {
  214.                 SelectObjects(tDetails.FoundInMaterials, ctrlPressed);
  215.             }

  216.             if (GUILayout.Button(tDetails.FoundInRenderers.Count + " GO", GUILayout.Width(50)))
  217.             {
  218.                 List<Object> FoundObjects = new List<Object>();
  219.                 foreach (Renderer renderer in tDetails.FoundInRenderers) FoundObjects.Add(renderer.gameObject);
  220.                 SelectObjects(FoundObjects, ctrlPressed);
  221.             }

  222.             GUILayout.EndHorizontal();
  223.         }
  224.         if (ActiveTextures.Count > 0)
  225.         {
  226.             GUILayout.BeginHorizontal();
  227.             GUILayout.Box(" ", GUILayout.Width(ThumbnailWidth), GUILayout.Height(ThumbnailHeight));

  228.             if (GUILayout.Button("Select All", GUILayout.Width(150)))
  229.             {
  230.                 List<Object> AllTextures = new List<Object>();
  231.                 foreach (TextureDetails tDetails in ActiveTextures) AllTextures.Add(tDetails.texture);
  232.                 SelectObjects(AllTextures, ctrlPressed);
  233.             }
  234.             EditorGUILayout.EndHorizontal();
  235.         }
  236.         EditorGUILayout.EndScrollView();
  237.     }

  238.     void ListMaterials()
  239.     {
  240.         materialListScrollPos = EditorGUILayout.BeginScrollView(materialListScrollPos);

  241.         foreach (MaterialDetails tDetails in ActiveMaterials)
  242.         {
  243.             if (tDetails.material != null)
  244.             {
  245.                 GUILayout.BeginHorizontal();

  246.                 if (tDetails.material.mainTexture != null) GUILayout.Box(tDetails.material.mainTexture, GUILayout.Width(ThumbnailWidth), GUILayout.Height(ThumbnailHeight));
  247.                 else
  248.                 {
  249.                     GUILayout.Box("n/a", GUILayout.Width(ThumbnailWidth), GUILayout.Height(ThumbnailHeight));
  250.                 }

  251.                 if (GUILayout.Button(tDetails.material.name, GUILayout.Width(150)))
  252.                 {
  253.                     SelectObject(tDetails.material, ctrlPressed);
  254.                 }

  255.                 string shaderLabel = tDetails.material.shader != null ? tDetails.material.shader.name : "no shader";
  256.                 GUILayout.Label(shaderLabel, GUILayout.Width(200));

  257.                 if (GUILayout.Button(tDetails.FoundInRenderers.Count + " GO", GUILayout.Width(50)))
  258.                 {
  259.                     List<Object> FoundObjects = new List<Object>();
  260.                     foreach (Renderer renderer in tDetails.FoundInRenderers) FoundObjects.Add(renderer.gameObject);
  261.                     SelectObjects(FoundObjects, ctrlPressed);
  262.                 }


  263.                 GUILayout.EndHorizontal();
  264.             }
  265.         }
  266.         EditorGUILayout.EndScrollView();
  267.     }

  268.     void ListMeshes()
  269.     {
  270.         meshListScrollPos = EditorGUILayout.BeginScrollView(meshListScrollPos);

  271.         foreach (MeshDetails tDetails in ActiveMeshDetails)
  272.         {
  273.             if (tDetails.mesh != null)
  274.             {
  275.                 GUILayout.BeginHorizontal();
  276.                 /*
  277.                 if (tDetails.material.mainTexture!=null) GUILayout.Box(tDetails.material.mainTexture, GUILayout.Width(ThumbnailWidth), GUILayout.Height(ThumbnailHeight));
  278.                 else   
  279.                 {
  280.                     GUILayout.Box("n/a",GUILayout.Width(ThumbnailWidth),GUILayout.Height(ThumbnailHeight));
  281.                 }
  282.                 */

  283.                 if (GUILayout.Button(tDetails.mesh.name, GUILayout.Width(150)))
  284.                 {
  285.                     SelectObject(tDetails.mesh, ctrlPressed);
  286.                 }
  287.                 string sizeLabel = "" + tDetails.mesh.vertexCount + " vert";

  288.                 GUILayout.Label(sizeLabel, GUILayout.Width(100));


  289.                 if (GUILayout.Button(tDetails.FoundInMeshFilters.Count + " GO", GUILayout.Width(50)))
  290.                 {
  291.                     List<Object> FoundObjects = new List<Object>();
  292.                     foreach (MeshFilter meshFilter in tDetails.FoundInMeshFilters) FoundObjects.Add(meshFilter.gameObject);
  293.                     SelectObjects(FoundObjects, ctrlPressed);
  294.                 }

  295.                 if (GUILayout.Button(tDetails.FoundInSkinnedMeshRenderer.Count + " GO", GUILayout.Width(50)))
  296.                 {
  297.                     List<Object> FoundObjects = new List<Object>();
  298.                     foreach (SkinnedMeshRenderer skinnedMeshRenderer in tDetails.FoundInSkinnedMeshRenderer) FoundObjects.Add(skinnedMeshRenderer.gameObject);
  299.                     SelectObjects(FoundObjects, ctrlPressed);
  300.                 }


  301.                 GUILayout.EndHorizontal();
  302.             }
  303.         }
  304.         EditorGUILayout.EndScrollView();
  305.     }

  306.     string FormatSizeString(int memSizeKB)
  307.     {
  308.         if (memSizeKB < 1024) return "" + memSizeKB + "k";
  309.         else
  310.         {
  311.             float memSizeMB = ((float)memSizeKB) / 1024.0f;
  312.             return memSizeMB.ToString("0.00") + "Mb";
  313.         }
  314.     }


  315.     TextureDetails FindTextureDetails(Texture tTexture)
  316.     {
  317.         foreach (TextureDetails tTextureDetails in ActiveTextures)
  318.         {
  319.             if (tTextureDetails.texture == tTexture) return tTextureDetails;
  320.         }
  321.         return null;

  322.     }

  323.     MaterialDetails FindMaterialDetails(Material tMaterial)
  324.     {
  325.         foreach (MaterialDetails tMaterialDetails in ActiveMaterials)
  326.         {
  327.             if (tMaterialDetails.material == tMaterial) return tMaterialDetails;
  328.         }
  329.         return null;

  330.     }

  331.     MeshDetails FindMeshDetails(Mesh tMesh)
  332.     {
  333.         foreach (MeshDetails tMeshDetails in ActiveMeshDetails)
  334.         {
  335.             if (tMeshDetails.mesh == tMesh) return tMeshDetails;
  336.         }
  337.         return null;

  338.     }


  339.     void CheckResources()
  340.     {
  341.         ActiveTextures.Clear();
  342.         ActiveMaterials.Clear();
  343.         ActiveMeshDetails.Clear();

  344.         Renderer[] renderers = (Renderer[])FindObjectsOfType(typeof(Renderer));
  345.         //Debug.Log("Total renderers "+renderers.Length);
  346.         foreach (Renderer renderer in renderers)
  347.         {
  348.             //Debug.Log("Renderer is "+renderer.name);
  349.             foreach (Material material in renderer.sharedMaterials)
  350.             {

  351.                 MaterialDetails tMaterialDetails = FindMaterialDetails(material);
  352.                 if (tMaterialDetails == null)
  353.                 {
  354.                     tMaterialDetails = new MaterialDetails();
  355.                     tMaterialDetails.material = material;
  356.                     ActiveMaterials.Add(tMaterialDetails);
  357.                 }
  358.                 tMaterialDetails.FoundInRenderers.Add(renderer);
  359.             }
  360.         }

  361.         foreach (MaterialDetails tMaterialDetails in ActiveMaterials)
  362.         {
  363.             Material tMaterial = tMaterialDetails.material;
  364.             var dependencies = EditorUtility.CollectDependencies(new UnityEngine.Object[] { tMaterial });
  365.             foreach (Object obj in dependencies)
  366.             {
  367.                 if (obj is Texture)
  368.                 {
  369.                     Texture tTexture = obj as Texture;
  370.                     var tTextureDetail = GetTextureDetail(tTexture, tMaterial, tMaterialDetails);
  371.                     ActiveTextures.Add(tTextureDetail);
  372.                 }
  373.             }

  374.             //if the texture was downloaded, it won't be included in the editor dependencies
  375.             if (tMaterial.mainTexture != null && !dependencies.Contains(tMaterial.mainTexture))
  376.             {
  377.                 var tTextureDetail = GetTextureDetail(tMaterial.mainTexture, tMaterial, tMaterialDetails);
  378.                 ActiveTextures.Add(tTextureDetail);
  379.             }
  380.         }


  381.         MeshFilter[] meshFilters = (MeshFilter[])FindObjectsOfType(typeof(MeshFilter));

  382.         foreach (MeshFilter tMeshFilter in meshFilters)
  383.         {
  384.             Mesh tMesh = tMeshFilter.sharedMesh;
  385.             if (tMesh != null)
  386.             {
  387.                 MeshDetails tMeshDetails = FindMeshDetails(tMesh);
  388.                 if (tMeshDetails == null)
  389.                 {
  390.                     tMeshDetails = new MeshDetails();
  391.                     tMeshDetails.mesh = tMesh;
  392.                     ActiveMeshDetails.Add(tMeshDetails);
  393.                 }
  394.                 tMeshDetails.FoundInMeshFilters.Add(tMeshFilter);
  395.             }
  396.         }

  397.         SkinnedMeshRenderer[] skinnedMeshRenderers = (SkinnedMeshRenderer[])FindObjectsOfType(typeof(SkinnedMeshRenderer));

  398.         foreach (SkinnedMeshRenderer tSkinnedMeshRenderer in skinnedMeshRenderers)
  399.         {
  400.             Mesh tMesh = tSkinnedMeshRenderer.sharedMesh;
  401.             if (tMesh != null)
  402.             {
  403.                 MeshDetails tMeshDetails = FindMeshDetails(tMesh);
  404.                 if (tMeshDetails == null)
  405.                 {
  406.                     tMeshDetails = new MeshDetails();
  407.                     tMeshDetails.mesh = tMesh;
  408.                     ActiveMeshDetails.Add(tMeshDetails);
  409.                 }
  410.                 tMeshDetails.FoundInSkinnedMeshRenderer.Add(tSkinnedMeshRenderer);
  411.             }
  412.         }


  413.         TotalTextureMemory = 0;
  414.         foreach (TextureDetails tTextureDetails in ActiveTextures) TotalTextureMemory += tTextureDetails.memSizeKB;

  415.         TotalMeshVertices = 0;
  416.         foreach (MeshDetails tMeshDetails in ActiveMeshDetails) TotalMeshVertices += tMeshDetails.mesh.vertexCount;

  417.         // Sort by size, descending
  418.         ActiveTextures.Sort(delegate(TextureDetails details1, TextureDetails details2) { return details2.memSizeKB - details1.memSizeKB; });
  419.         ActiveMeshDetails.Sort(delegate(MeshDetails details1, MeshDetails details2) { return details2.mesh.vertexCount - details1.mesh.vertexCount; });

  420.     }

  421.     private TextureDetails GetTextureDetail(Texture tTexture, Material tMaterial, MaterialDetails tMaterialDetails)
  422.     {
  423.         TextureDetails tTextureDetails = FindTextureDetails(tTexture);
  424.         if (tTextureDetails == null)
  425.         {
  426.             tTextureDetails = new TextureDetails();
  427.             tTextureDetails.texture = tTexture;
  428.             tTextureDetails.isCubeMap = tTexture is Cubemap;

  429.             int memSize = CalculateTextureSizeBytes(tTexture);

  430.             tTextureDetails.memSizeKB = memSize / 1024;
  431.             TextureFormat tFormat = TextureFormat.RGBA32;
  432.             int tMipMapCount = 1;
  433.             if (tTexture is Texture2D)
  434.             {
  435.                 tFormat = (tTexture as Texture2D).format;
  436.                 tMipMapCount = (tTexture as Texture2D).mipmapCount;
  437.             }
  438.             if (tTexture is Cubemap)
  439.             {
  440.                 tFormat = (tTexture as Cubemap).format;
  441.             }

  442.             tTextureDetails.format = tFormat;
  443.             tTextureDetails.mipMapCount = tMipMapCount;

  444.         }
  445.         tTextureDetails.FoundInMaterials.Add(tMaterial);
  446.         foreach (Renderer renderer in tMaterialDetails.FoundInRenderers)
  447.         {
  448.             if (!tTextureDetails.FoundInRenderers.Contains(renderer)) tTextureDetails.FoundInRenderers.Add(renderer);
  449.         }
  450.         return tTextureDetails;
  451.     }

  452. }
复制代码

作者: hyui    时间: 2014-6-28 02:22
wow, let's try to explore it !




欢迎光临 纳金网 (http://rs.narkii.com/club/) Powered by Discuz! X2.5