Skip to content

Instantly share code, notes, and snippets.

@tsubaki
Last active June 12, 2016 10:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tsubaki/85ad426180b3bcbf89aa71c0b8786768 to your computer and use it in GitHub Desktop.
Save tsubaki/85ad426180b3bcbf89aa71c0b8786768 to your computer and use it in GitHub Desktop.
Assetbundleの依存関係から重複アセットを見つけ出すプロトタイプ
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using System.Linq;
using System.IO;
public class DependencyAssets : EditorWindow
{
class arrangeData
{
public Object obj;
public string[] names;
public bool isOpen = false;
public int count;
}
class AssetNameAssets
{
public string name;
public List<string> assetList = new List<string>();
public bool isOpen = false;
public int count;
}
#region EditorExtensions
[MenuItem("AssetBundle/Named")]
static void Init()
{
var window = EditorWindow.GetWindow<DependencyAssets>();
AssetDatabase.SaveAssets();
window.Check();
window.Show();
}
Vector2 scrollDependency;
Vector2 scrollAllAssets;
void OnGUI()
{
//AssetListGUI();
DependencyGUI();
}
void DependencyGUI()
{
using (var scrollView = new EditorGUILayout.ScrollViewScope(scrollDependency))
{
if (items.Count() == 0)
{
EditorGUILayout.HelpBox("Not duplicate", MessageType.Info);
}
scrollDependency = scrollView.scrollPosition;
foreach (var item in items)
{
EditorGUILayout.BeginHorizontal();
item.isOpen = EditorGUILayout.Foldout(item.isOpen, item.obj.name + " (" + item.count + ")");
EditorGUILayout.ObjectField(item.obj, item.obj.GetType(), false);
EditorGUILayout.EndHorizontal();
if (item.isOpen == false)
continue;
EditorGUILayout.BeginVertical("box");
EditorGUI.indentLevel = 1;
foreach (var name in item.names)
{
EditorGUILayout.LabelField(name);
}
EditorGUI.indentLevel = 0;
EditorGUILayout.EndVertical();
}
}
}
string currentAssetBundle = string.Empty;
void AssetListGUI()
{
using (var horizonal = new EditorGUILayout.HorizontalScope())
{
using (var scrollView = new EditorGUILayout.ScrollViewScope(scrollAllAssets, "box", GUILayout.Width(200)))
{
scrollAllAssets = scrollView.scrollPosition;
EditorGUI.indentLevel = 0;
foreach (var dependencies in assetbundleDependency)
{
if (GUILayout.Button(dependencies.Key, EditorStyles.label))
{
currentAssetBundle = dependencies.Key;
}
EditorGUI.indentLevel = 1;
foreach (var abname in dependencies.Value)
{
if (GUILayout.Button( " -" + abname, EditorStyles.label))
{
currentAssetBundle = abname;
}
}
}
}
using( var vartical = new EditorGUILayout.VerticalScope())
{
var item = assetbundleAssets.Find(c => c.name == currentAssetBundle);
if (item == null)
{
EditorGUILayout.Space();
return;
}
foreach (var guid in item.assetList)
{
var path = AssetDatabase.GUIDToAssetPath(guid);
if (string.IsNullOrEmpty(path))
continue;
var obj = AssetDatabase.LoadAssetAtPath(path, typeof(object));
EditorGUILayout.ObjectField(obj, obj.GetType(), false);
}
}
}
}
#endregion
List<arrangeData> items = new List<arrangeData>();
List<AssetNameAssets> assetbundleAssets = new List<AssetNameAssets>();
// assetbundle name, dependency assetbundle name
Dictionary<string, List<string>> assetbundleDependency = new Dictionary<string, List<string>>();
void AddAssetBundleIgnoreList( string assetGuid, string assetPath, string bundleName,
ref Dictionary<string, List<string>> allreferencyAssets,
ref List<string> namedAssetList)
{
namedAssetList.Add(assetGuid);
foreach (var asset in AssetDatabase.GetDependencies(assetPath))
{
var guid = AssetDatabase.AssetPathToGUID(asset);
if (allreferencyAssets.ContainsKey(guid) == false)
{
allreferencyAssets.Add(guid, new List<string>());
}
allreferencyAssets[guid].Add(bundleName);
}
}
Dictionary<string, List<string>> GetAllAssetbundleNames()
{
// assetbundle name, assets guid
Dictionary<string, List<string>> allAssetBundleNames = new Dictionary<string, List<string>>();
foreach (var aseetbundleName in AssetDatabase.GetAllAssetBundleNames())
{
allAssetBundleNames.Add(aseetbundleName, new List<string>());
}
foreach (var directryPath in Directory.GetDirectories("Assets", "*", SearchOption.AllDirectories))
{
var bundleName = GetBundleName(directryPath);
if (string.IsNullOrEmpty(bundleName))
continue;
foreach (var assetPath in Directory.GetFiles(directryPath, "*", SearchOption.AllDirectories))
{
var guid = AssetDatabase.AssetPathToGUID(assetPath);
foreach (var assetBundleName in allAssetBundleNames)
{
assetBundleName.Value.Remove(guid);
}
allAssetBundleNames[bundleName].Add(guid);
}
}
foreach (var assetGuid in AssetDatabase.FindAssets(string.Empty))
{
var assetPath = AssetDatabase.GUIDToAssetPath(assetGuid);
var bundleName = GetBundleName(assetPath);
if (string.IsNullOrEmpty(bundleName))
continue;
foreach (var assetBundleName in allAssetBundleNames)
{
assetBundleName.Value.Remove(assetGuid);
}
allAssetBundleNames[bundleName].Add(assetGuid);
}
return allAssetBundleNames;
}
string GetBundleName(string path)
{
var importer = AssetImporter.GetAtPath(path);
var bundleName = importer.assetBundleName;
var variantName = importer.assetBundleVariant;
if (string.IsNullOrEmpty(bundleName))
return string.Empty;
if (string.IsNullOrEmpty(variantName) == false)
bundleName = bundleName + "." + variantName;
return bundleName;
}
/// <summary>
///
/// </summary>
void Check()
{
var allAssetbundlenameDic = GetAllAssetbundleNames();
foreach( var assetBundleName in AssetDatabase.GetAllAssetBundleNames())
{
assetbundleDependency.Add(assetBundleName, new List<string>());
}
// asset guid, assetbundle name list
Dictionary<string, List<string>> allreferencyAssets = new Dictionary<string, List<string>>();
List<string> namedAssetList = new List<string>();
foreach( var assetbundleName in allAssetbundlenameDic)
{
foreach( var assetGuid in assetbundleName.Value)
{
var path = AssetDatabase.GUIDToAssetPath(assetGuid);
foreach( var dependency in AssetDatabase.GetDependencies(path))
{
var guid = AssetDatabase.AssetPathToGUID(dependency);
var result = allAssetbundlenameDic
.Where(c => c.Key != assetbundleName.Key)
.Where(c => c.Value.Contains(guid))
.Select(c => c.Key)
.Distinct()
.ToArray();
assetbundleDependency[assetbundleName.Key].AddRange(result);
}
}
}
foreach( var key in assetbundleDependency.Keys.ToArray())
{
var list = assetbundleDependency[key].ToArray();
assetbundleDependency[key] = list.Distinct().ToList();
}
// register guid to assetbundle
foreach (var directryPath in Directory.GetDirectories("Assets", "*", SearchOption.AllDirectories))
{
var bundleName = GetBundleName(directryPath);
if (string.IsNullOrEmpty(bundleName))
continue;
foreach (var assetPath in Directory.GetFiles(directryPath, "*", SearchOption.AllDirectories))
{
var assetGuid = AssetDatabase.GUIDToAssetPath(assetPath);
AddAssetBundleIgnoreList(assetGuid, assetPath, bundleName, ref allreferencyAssets, ref namedAssetList);
}
}
foreach (var assetGuid in AssetDatabase.FindAssets(string.Empty))
{
var assetPath = AssetDatabase.GUIDToAssetPath(assetGuid);
var bundleName = GetBundleName(assetPath);
if (string.IsNullOrEmpty(bundleName))
continue;
AddAssetBundleIgnoreList(assetGuid, assetPath, bundleName, ref allreferencyAssets, ref namedAssetList);
}
// strip direct dependency
foreach (var assets in allreferencyAssets)
{
foreach (var abName in assetbundleDependency)
{
if (assets.Value.Contains(abName.Key) == false)
continue;
foreach( var targetAb in abName.Value)
{
if (assets.Value.Contains(targetAb))
{
allreferencyAssets[assets.Key].Remove(abName.Key);
}
}
}
}
var referenceFromDependency = allreferencyAssets.Where(c => namedAssetList.Contains(c.Key) == false);
// register for gui
items.Clear();
foreach (var assets in referenceFromDependency)
{
var abNames = assets.Value.Distinct().ToArray();
if (abNames.Count() < 2)
continue;
items.Add(new arrangeData()
{
obj = AssetDatabase.LoadMainAssetAtPath(AssetDatabase.GUIDToAssetPath(assets.Key)),
names = abNames,
count = abNames.Count(),
});
}
assetbundleAssets.Clear();
foreach (var assets in allreferencyAssets)
{
foreach (var ab in assets.Value)
{
var aba = assetbundleAssets.Find(c => c.name == ab);
if (aba == null)
{
aba = new AssetNameAssets() { name = ab, };
assetbundleAssets.Add(aba);
}
aba.assetList.Add(assets.Key);
}
}
foreach( var item in assetbundleAssets)
{
item.assetList = item.assetList.Distinct().ToList();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment