viernes, 25 de octubre de 2013

Cleaning Unit3d projects, remove unused assets



For some reasons, it´s easy to fill a unity project with a lot of materials, animations, test meshes, unused lightmaps etc... Cleaning by hand a projects it´s not a easy task, because (for example) you could have some materials on some folders that you can delete and then... you will see the magic material:




Here is some help to clean your projects:

(it´s a modification from this one: http://zaxisgames.blogspot.com.es/2012/02/automatically-locate-all-unused-assets.html )


CleanUpWindow.cs
 
 
 using UnityEngine;  
 using UnityEditor;  
 using System.IO;  
 using System.Collections;  
 using System.Collections.Generic; 





////////////////  
//Exclude .metas, .svn folders,prefabs and Editor and Plugin Folders.  
////////////////  


public class CleanUpWindow : EditorWindow  {  



 List usedAssets = new List();
 List unUsedAssetsString = new List();
 List includedDependencies = new List(); 
 
   
 private bool needToBuild = false;  
   static bool readyForDelete = false;  
 
 
 
 
[MenuItem("Window/CleanUpWindow")]  
static void Init(){  
  
 // Get existing open window or if none, make a new one:   
 CleanUpWindow window = (CleanUpWindow)EditorWindow.GetWindow(typeof(CleanUpWindow));  
 window.Show();  
 readyForDelete = false;  
}  
 
 
 
void OnGUI(){  
  
 if (needToBuild){  
  GUI.color = Color.red;  
  GUILayout.Label("Are you sure you remembered to build project?", EditorStyles.boldLabel);  
 }
  
 GUI.color = Color.white;  
 if (GUILayout.Button("Load EditorLog")) {  
  loadEditorLog();  
  if (!needToBuild){  
      readyForDelete = true;  
         listAssest();  
  }  
  }  
  
 if (!needToBuild){  
   
  GUI.color = Color.red;  
  if (GUILayout.Button("Clear EditorLog")){  
   clearEditorLog();  
   readyForDelete = false;  
   needToBuild = true;  
  } 
   
  GUI.color = Color.white;  
  if (readyForDelete){  
   if (GUILayout.Button("Delete Unused Files")){  
        deleteAssets();  
        readyForDelete = false;  
   }  
  }
   
 }
  
}  
 
 
 
 
 
private void listAssest(){  
  
 if (!needToBuild){ 
   
  if (unUsedAssetsString.Count >= 1){  
   // List all unused Files  
   string allUnusedFiles = "";  
   for(int i = 0; i < unUsedAssetsString.Count; i++){  
      allUnusedFiles += unUsedAssetsString[i] + "\n";  
   }  
   Debug.Log("UnUsed Assets*_*");  
   Debug.Log(allUnusedFiles);  
  }  
 } 
  
}  

 
 
 
 
 
 
 
 
 
private void deleteAssets(){  

 if (unUsedAssetsString.Count >= 1){  
  // List all unused Files  
  string allUnusedFiles = "";  
  for(int i = 0; i < unUsedAssetsString.Count; i++){  
    File.Delete(unUsedAssetsString[i]);  
  }  
 }  
 
   
}  
 
 
 

private void clearEditorLog(){  
 
  /*As unity also uses Debug.log file, you will hava a zero bytes size file.
   * The best you can do is close unity and open again
   */
  
}  
 
 
 
 
private void loadEditorLog(){  
  
 UsedAssets.GetLists(ref usedAssets, ref includedDependencies); 
  
 if (usedAssets.Count == 0){  
  needToBuild = true;  
  readyForDelete = false;  
  unUsedAssetsString.Clear();
 }  
 else{  
  compareAssetList(UsedAssets.GetAllAssets());  
  needToBuild = false;  
 }  
}  
 
 
 
 
private void compareAssetList(string[] assetList){  
   
 unUsedAssetsString.Clear();
   
 for (int i = 0; i < assetList.Length; i++){
   
  if (!usedAssets.Contains(assetList[i])) unUsedAssetsString.Add (assetList[i]);                      
   
 }  
  
  
} 


 
}  

//Ignore this, html issue while getting syntax highligh 
//


//Ignore this, html issue while getting syntax highligh 
//

UsedAssets.cs
 

using UnityEngine;  
using UnityEditor;  
using System;  
using System.IO;  
using System.Collections;  
using System.Collections.Generic;  



public class UsedAssets  { 
 
 
public static string[] GetAllAssets()  {  
  
  
    string[] tmpAssets1 = Directory.GetFiles(Application.dataPath, "*.*", SearchOption.AllDirectories);  
    string[] tmpAssets3 = Array.FindAll(tmpAssets1, name => !name.EndsWith(".meta"));  
    string[] tmpAssets4 = Array.FindAll(tmpAssets3, name => !name.Contains("StreamingAssets"));  
    string[] tmpAssets5 = Array.FindAll(tmpAssets4, name => !name.Contains("Resources"));  
    string[] tmpAssets6 = Array.FindAll(tmpAssets5, name => !name.Contains("Plugins"));  
    string[] tmpAssets7 = Array.FindAll(tmpAssets6, name => !name.Contains("Editor"));  
    string[] tmpAssets8 = Array.FindAll(tmpAssets7, name => !name.EndsWith(".prefab"));  
    string[] tmpAssets2 = Array.FindAll(tmpAssets8, name => !name.Contains("svn"));  
    string[] allAssets;
  
 allAssets = Array.FindAll(tmpAssets2, name => !name.EndsWith(".unity"));  
    for (int i = 0; i < allAssets.Length; i++){  
   
      allAssets[i] = allAssets[i].Substring(allAssets[i].IndexOf("/Assets") + 1);  
      allAssets[i] = allAssets[i].Replace(@"\", "/");  
    }  
  
    return allAssets;  
}  
 
 
 
 
public static void GetLists(ref List assetResult, ref List dependencyResult) { 
  
    assetResult.Clear();  
    dependencyResult.Clear();  
    string LocalAppData = string.Empty;  
    string UnityEditorLogfile = string.Empty;  
    if (Application.platform == RuntimePlatform.WindowsEditor){  
   
      LocalAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);  
      UnityEditorLogfile = LocalAppData + "\\Unity\\Editor\\Editor.log";  
    }  
  
    else if (Application.platform == RuntimePlatform.OSXEditor){  
   
      LocalAppData = Environment.GetFolderPath(Environment.SpecialFolder.Personal);  
      UnityEditorLogfile = LocalAppData + "/Library/Logs/Unity/Editor.log";  
    }  
      try {  
   
        // Have to use FileStream to get around sharing violations!  
        FileStream FS = new FileStream(UnityEditorLogfile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);  
        StreamReader SR = new StreamReader(FS);  
        string line;  
        while (!SR.EndOfStream && !(line = SR.ReadLine()).Contains("Mono dependencies included in the build")) ;  
   
        while (!SR.EndOfStream && (line = SR.ReadLine()) != ""){  
          dependencyResult.Add(line);  
        }  
        while (!SR.EndOfStream && !(line = SR.ReadLine()).Contains("Used Assets,")) ;  
   
        while (!SR.EndOfStream && (line = SR.ReadLine()) != ""){  
         if( !line.Contains("System memory") ){  
               line = line.Substring(line.IndexOf("% ") + 2);  
               assetResult.Add(line);  
             }  
        } 
   
   
      }  
      catch (Exception E){
   
        Debug.LogError("Error: " + E);  
      }  
}
 
 

 
 
 
}  
//
//


-Close and open Unity editor and  build your game (to fill the Editor.log with the used assets).
-Open CleanUpWindow (from Window meu), and click on LoadEditorLog.

 At this poing you can see on the Editor a list of all your unused assets.

 -Click on Delete Unused Assets.

 This scripts will not touch the .svn folders, meta files, Plugin, Editor and StreamingAssets Folders, it also avoid to delete the prefab files: As unity does not use prefabs for build the game, all prefabs will show as unused, so you can´t choose between used or unused prefabs. Now you can check for emtpy folders, and move all your materials, textures and models to other folders. It´s a good idea to remove all .svn files too:



find . -type d -name '.svn' -print -exec rm -rf {} \;





No hay comentarios:

Publicar un comentario