Automatically locate all unused unity assets

Did you ever work on a unity project where either you or a co-worker did not uphold complete and total order with regards to cleaning up the project folder. If you're one of those rare specimens that has never experienced a touch of kaos, don't read on!

On the other hand if you, as I, from time to time postpones the cleanup to another day, I've made a handy little editorwindow that should make the cleanup process a lot less tedious.

Basically it reads from the editor log after you have build a project, and then compares the included assets with all assets in your project. If an asset exist that is not used in the final build it is listed. It is also clickable so you can easily find it.

The unused assets are organized in 3 folders. "editor", "plugins" and "some other folder". This is helpful for me, as there is a lot in the "editor" folder that I use, but that is not used in final build.

It also lists which .dll's are included in build. If you need it, fine. If not, just delete that part.

DISCLAIMER: It does not locate unused assets in the "Ressources" folder, since everything in there should by default be included in the build. It's a tool to help locate the unused, but should be used with a bit of common sense.

Place the following in the "editor" folder:
 using UnityEngine;  
using UnityEditor;
using System.Collections;
using System.Collections.Generic;

public class CleanUpWindow : EditorWindow
{
bool groupEnabled = false;
List<string> usedAssets = new List<string>();
List<string> includedDependencies = new List<string>();
private Vector2 scrollPos;
private List<Object> unUsed;
private Dictionary<string, List<Object>> unUsedArranged;
private bool needToBuild = false;

// Add menu named "CleanUpWindow" to the Window menu
[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();
}

void OnGUI()
{
if (needToBuild)
{
GUI.color = Color.red;
GUILayout.Label("Are you sure you remembered to build project? Because you really need to...", EditorStyles.boldLabel);
}
GUI.color = Color.white;

if (GUILayout.Button("Load EditorLog"))
{
loadEditorLog();
}


if(!needToBuild)
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.BeginVertical();
if (groupEnabled)
{
GUILayout.Label("DEPENDENCIES");
for (int i = 0; i < includedDependencies.Count; i++)
{
EditorGUILayout.LabelField(i.ToString(), includedDependencies[i]);
}
}
EditorGUILayout.EndVertical();
scrollPos = EditorGUILayout.BeginScrollView(scrollPos);
EditorGUILayout.BeginVertical();

if (groupEnabled)
{
if (unUsedArranged != null)
{
foreach (KeyValuePair<string, List<Object>> objList in unUsedArranged)
{
if (objList.Value.Count >= 1)
{
GUILayout.Label(objList.Key.ToUpper());
for (int i = 0; i < objList.Value.Count; i++)
{
EditorGUILayout.ObjectField(objList.Value[i], typeof(Object), false);
}
}
}
}
}
EditorGUILayout.EndVertical();
EditorGUILayout.EndScrollView();
EditorGUILayout.EndHorizontal();
}

}

private void loadEditorLog()
{
UsedAssets.GetLists(ref usedAssets, ref includedDependencies);

if (usedAssets.Count == 0)
{
needToBuild = true;
}
else
{
compareAssetList(UsedAssets.GetAllAssets());
groupEnabled = true;
needToBuild = false;
}
}

private void compareAssetList(string[] assetList)
{

unUsed = new List<Object>();

unUsedArranged = new Dictionary<string, List<Object>>();
unUsedArranged.Add("plugins", new List<Object>());
unUsedArranged.Add("editor", new List<Object>());
unUsedArranged.Add("some other folder", new List<Object>());

for (int i = 0; i < assetList.Length; i++)
{
if(!usedAssets.Contains(assetList[i]))
{

Object objToFind = AssetDatabase.LoadAssetAtPath(assetList[i], typeof(Object));
unUsed.Add(objToFind);
if (objToFind != null)
{
unUsedArranged[getArrangedPos(objToFind)].Add(objToFind);
}
}
}
}

private string getArrangedPos(Object value)
{
string path = AssetDatabase.GetAssetPath(value).ToLower();

if (path.Contains("/plugins/"))
{
return "plugins";
}
else if (path.Contains("/editor/"))
{
return "editor";
}
else
{
return "some other folder";
}
}
}
You,ll need this too:
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[] tmpAssets2 = Array.FindAll(tmpAssets1, name => !name.EndsWith(".meta"));
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<string> assetResult, ref List<string> 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()) != "")
{

line = line.Substring(line.IndexOf("% ") + 2);
assetResult.Add(line);
}
}
catch (Exception E)
{
Debug.LogError("Error: " + E);
}
}
}
Note that script files might not be shown as unused since the unity build includes then.
Here's an example: Unity Package

  • Digg
  • Del.icio.us
  • StumbleUpon
  • Reddit
  • RSS

0 komentar:

Posting Komentar