summaryrefslogtreecommitdiff
path: root/AssetBrowser.cs
diff options
context:
space:
mode:
Diffstat (limited to 'AssetBrowser.cs')
-rw-r--r--AssetBrowser.cs650
1 files changed, 499 insertions, 151 deletions
diff --git a/AssetBrowser.cs b/AssetBrowser.cs
index 4be9386..398c2c2 100644
--- a/AssetBrowser.cs
+++ b/AssetBrowser.cs
@@ -1,42 +1,71 @@
-using UnityEditor;
+/////////////////////////////////////////////////////////////////////////////////
+//
+// author: chaifeixiang
+// date: 2018.5.20
+// desc: Unity中找文件依赖关系的编辑器工具,需要Unity5.4及以上版本
+//
+//
+//
+//
+//
+/////////////////////////////////////////////////////////////////////////////////
+
+using UnityEditor;
using UnityEngine;
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
+using Object = UnityEngine.Object;
class AssetData
{
// 枚举值为遍历的优先级,用于AssetData.Dependcies和AssetDataManager.Assets
- public static readonly int AssetTypeCount = 9;
+ // 必须是紧凑的索引
public enum AssetType
{
- Scene = 0,
- Prefab,
+ Scene = 0,
+ Prefab,
Mesh,
Material,
- Asset,
- Texture,
- Shader,
- Script,
- CSV,
+ Asset,
+ Texture,
+ Shader,
+ Script,
+ CSV,
- Unknown = 255,
+ TypeCount,
+
+ Unknown = 255,
+ }
+
+ public enum SubType
+ {
+ // Texture
+ png = 0,
+ jpg,
+ bmp,
+ // Mesh
+ fbx,
+ FBX,
+ //
+ Unknown = 255,
}
public AssetData(FileSystemInfo f)
{
- for (int i = 0; i < AssetTypeCount; ++i)
+ for (int i = 0; i < (int)AssetType.TypeCount; ++i)
Dependencies[i] = new List<string>();
AssetDataManager manager = AssetDataManager.Get();
AssetPath = manager.FullPathToAssetPath(f.FullName);
GUID = AssetDatabase.AssetPathToGUID(AssetPath);
Name = f.Name;
ObjType = AssetDatabase.GetMainAssetTypeAtPath(AssetPath);
- FileType = ExtensionToAssetType(f.Extension);
Extension = f.Extension;
- string[] depsPath = AssetDatabase.GetDependencies(AssetPath, false);
- for(int i = 0; i < depsPath.Length; ++i)
+ FileType = ExtensionToAssetType(Extension);
+ SubFileType = ExtensionToSubType(Extension);
+ string[] depsPath = AssetDatabase.GetDependencies(AssetPath, false);
+ for (int i = 0; i < depsPath.Length; ++i)
{
string path = depsPath[i];
string guid = AssetDatabase.AssetPathToGUID(path);
@@ -49,10 +78,10 @@ class AssetData
Dependencies[(int)type].Add(guid);
++RefCount;
List<string> data;
- if (!AssetDataManager.AssetsReverse.TryGetValue(guid, out data))
+ if (!manager.AssetsReverse.TryGetValue(guid, out data))
{
data = new List<string>();
- AssetDataManager.AssetsReverse.Add(guid, data);
+ manager.AssetsReverse.Add(guid, data);
}
data.Add(GUID);
}
@@ -64,17 +93,36 @@ class AssetData
#region 资源属性
public string GUID;
public string Name;
- public int RefCount = 0;
- public int RevRefCount = 0;
- public long DiskSize;
+ public int RefCount = 0;
+ //public int RevRefCount = 0;
+ public long DiskSize;
public string DiskSizeStr;
public string AssetPath;
- public Type ObjType;
+ public Type ObjType;
public string Extension;
public AssetType FileType;
- public List<string>[] Dependencies = new List<string>[AssetTypeCount];
+ public SubType SubFileType;
+ public List<string>[] Dependencies = new List<string>[(int)AssetType.TypeCount];
#endregion
+ private SubType ExtensionToSubType(string extension)
+ {
+ SubType subType = SubType.Unknown;
+ // texture
+ if (Extension == ".png")
+ subType = SubType.png;
+ else if (Extension == ".jpg")
+ subType = SubType.jpg;
+ else if (Extension == ".bmp")
+ subType = SubType.bmp;
+ // mesh
+ else if (Extension == ".fbx")
+ subType = SubType.fbx;
+ else if (Extension == ".FBX")
+ subType = SubType.FBX;
+ return subType;
+ }
+
private AssetType ExtensionToAssetType(string extension)
{
if (extension == ".unity") return AssetType.Scene;
@@ -103,17 +151,17 @@ class AssetDataManager
public AssetDataManager()
{
- for (int i = 0; i < AssetData.AssetTypeCount; ++i)
+ for (int i = 0; i < (int)AssetData.AssetType.TypeCount; ++i)
Assets[i] = new Dictionary<string, AssetData>();
}
#region Asset字典
// 所有资源
- public static Dictionary<string, AssetData> AllAssets = new Dictionary<string, AssetData>();
+ public Dictionary<string, AssetData> AllAssets = new Dictionary<string, AssetData>();
// 分类统计
- public static Dictionary<string, AssetData>[] Assets = new Dictionary<string, AssetData>[AssetData.AssetTypeCount];
+ public Dictionary<string, AssetData>[] Assets = new Dictionary<string, AssetData>[(int)AssetData.AssetType.TypeCount];
// 反向依赖
- public static Dictionary<string, List<string>> AssetsReverse = new Dictionary<string, List<string>>();
+ public Dictionary<string, List<string>> AssetsReverse = new Dictionary<string, List<string>>();
#endregion
#region 过滤
@@ -130,13 +178,15 @@ class AssetDataManager
".csv" // CSV
};
- public string GetExtension(string file)
+ public string GetExtension(string path)
{
- if (file == null || file.Length == 0)
+ if (path == null || path.Length <= 0)
return null;
- int len = file.Length;
- int idx = file.LastIndexOf('.');
- return file.Substring(idx, len - idx);
+ int len = path.Length;
+ int idx = path.LastIndexOf('.');
+ if (idx == -1)
+ return null;
+ return path.Substring(path.LastIndexOf('.'), len - idx);
}
public bool IsValidFile(string file)
@@ -156,20 +206,18 @@ class AssetDataManager
public bool IsValidFolder(string folderName)
{
- foreach(var dir in InvalidFolder)
+ foreach (var dir in InvalidFolder)
{
- if(dir == folderName)
+ if (dir == folderName)
return false;
}
- return true;
+ return true;
}
#endregion
public string FullPathToAssetPath(string fullpath)
{
- fullpath = fullpath.Replace('\\', '/');
- string path = "Assets" + fullpath.Replace(Application.dataPath, "");
- path = path.Replace('/', '\\');
+ string path = "Assets" + fullpath.Replace(Application.dataPath.Replace("/", "\\"), "");
return path;
}
@@ -183,13 +231,13 @@ class AssetDataManager
{
DirectoryInfo directoryInfo = new DirectoryInfo(fullpath);
FileSystemInfo[] filesInfo = directoryInfo.GetFileSystemInfos();
- foreach(FileSystemInfo f in filesInfo)
+ foreach (FileSystemInfo f in filesInfo)
{
- if(f is DirectoryInfo && IsValidFolder(f.Name))
+ if (f is DirectoryInfo && IsValidFolder(f.Name))
{
LoadAssets(f.FullName);
}
- else if(f.Extension != ".meta" && IsValidFile(f.Name))
+ else if (f.Extension != ".meta" && IsValidFile(f.Name))
{
AssetData asset = new AssetData(f);
AllAssets.Add(asset.GUID, asset);
@@ -198,6 +246,13 @@ class AssetDataManager
}
}
+ public string FormatPath(string assetpath)
+ {
+ string path = assetpath.Replace('/', '\\');
+ path = path.Replace("\\\\", "\\");
+ return path;
+ }
+
public void ClearAssets()
{
AllAssets.Clear();
@@ -214,30 +269,33 @@ class Drawer
{
SelectorButtonStyle = new GUIStyle(GUIStyle.none);
SelectorButtonStyle.normal.background = CreateTexture(1, 1, new Color32(62, 95, 150, 255));
+ MidAlignment = new GUIStyle(GUIStyle.none);
+ MidAlignment.alignment = TextAnchor.MiddleCenter;
}
- private Texture2D CreateTexture(int w, int h, Color col)
+ private Texture2D CreateTexture(int width, int height, Color color)
{
- Color[] pixels = new Color[w * h];
- for(int i = 0; i < w * h; ++i)
- pixels[i] = col;
- Texture2D texture = new Texture2D(w, h);
- texture.SetPixels(pixels);
- return texture;
+ Color[] pixels = new Color[width * height];
+ for (int i = 0; i < width * height; ++i)
+ pixels[i] = color;
+ Texture2D result = new Texture2D(width, height);
+ result.SetPixels(pixels);
+ result.Apply();
+ return result;
}
- private static Drawer drawer = null;
+ private static Drawer drawer = null;
public static Drawer Get()
{
if (drawer == null)
drawer = new Drawer();
- return drawer;
+ return drawer;
}
-
- public void DrawButtonMid(Rect rect, string content)
+
+ public void DrawButtonMid(Rect rect, string content, out bool click)
{
- GUI.Button(rect, content, EditorStyles.miniButtonMid);
+ click = GUI.Button(rect, content, EditorStyles.miniButtonMid);
}
public void DrawButton(Rect rect, string content, out bool click)
@@ -270,7 +328,10 @@ class Drawer
public void DrawFoldout(Rect rect, ref bool foldout)
{
- foldout = EditorGUI.Foldout(rect, foldout, "");
+ Texture2D foldIcon = foldout ? IconFoldout : IconFoldup;
+ bool clicked = GUI.Button(rect, foldIcon, MidAlignment);
+ if (clicked)
+ foldout = !foldout;
}
public void DrawAssetIcon(Rect rect, AssetData asset)
@@ -282,15 +343,38 @@ class Drawer
public void DrawSelector(Rect rect, bool selected, out bool clicked)
{
- SelectorButtonStyle.normal.background = CreateTexture(1, 1, new Color32(62, 95, 150, 255));
- clicked = GUI.Button(rect, "",selected ? SelectorButtonStyle : GUIStyle.none);
+ clicked = GUI.Button(rect, "", selected ? SelectorButtonStyle : GUIStyle.none);
+ }
+
+ public void DrawPing(Rect rect, ref bool clicked)
+ {
+ GUIContent content = EditorGUIUtility.IconContent("SubAssetCollapseButton");
+ clicked = GUI.Button(rect, content, MidAlignment);
+ }
+
+ public void SetTextColor(Color col)
+ {
+ drawColor = GUI.skin.label.normal.textColor;
+ GUI.skin.label.normal.textColor = col;
+ }
+
+ public void ResetTextColor()
+ {
+ GUI.skin.label.normal.textColor = drawColor;
}
#region 配置项
public Color ColorHeavy = new Color(0.2f, 0.2f, 0.2f);
public Color ColorLight = new Color(0.3f, 0.3f, 0.3f);
public GUIStyle SelectorButtonStyle;
+ public Texture2D IconFoldout = EditorStyles.foldout.onNormal.background;
+ public Texture2D IconFoldup = EditorStyles.foldout.normal.background;
+ public GUIStyle MidAlignment;
#endregion
+
+ #region 状态
+ private Color drawColor = new Color();
+ #endregion
}
// 文件树
@@ -316,7 +400,10 @@ class AssetBrowser : EditorWindow
private static AssetBrowser editor;
private static Drawer drawer;
+ #region 目录
private FileTree assetsTree = new FileTree();
+ private FileTree assetsTreeBuffer = new FileTree();
+ #endregion
#region GUI 组件配置数值
private Rect window = new Rect();
@@ -328,15 +415,15 @@ class AssetBrowser : EditorWindow
private int filtersOffsetY = 27; // 过滤器Y偏移度
private int headerOffsetY = 50; // 标题Y偏移度
private int assetsTreeOffsetY = 70; // 列表偏移度
- private int kTabWidth = 15;
+ private int kTabWidth = 13;
#endregion
#region 数据
- private string directory = "";
private FileTree.Node selectedNode = null;
#endregion
#region 过滤器
+ private string filterdirectory = "";
private string filterFile = "";
private bool filterScene = false;
private bool filterPrefab = false;
@@ -349,7 +436,27 @@ class AssetBrowser : EditorWindow
private bool filterCSV = false;
#endregion
- [MenuItem("Window/Asset Browser")]
+ #region 排序
+ private enum OrderBase
+ {
+ Name,
+ Ref,
+ RevRef,
+ Type,
+ DiskSize,
+ Path
+ }
+ // 排序依据
+ private OrderBase orderBase = OrderBase.Path;
+ private int orderName = 1;
+ private int orderRef = 1;
+ private int orderRevRef = 1;
+ private int orderType = 1;
+ private int orderDiskSize = 1;
+ private int orderPath = 1;
+ #endregion
+
+ [MenuItem("DNTools/查找/资源引用关系", false, 6)]
public static void Show()
{
editor = GetWindow<AssetBrowser>();
@@ -379,21 +486,21 @@ class AssetBrowser : EditorWindow
private Dictionary<Colum, int> ColumWidth = new Dictionary<Colum, int>
{
- {Colum.Name, 500},
- {Colum.Ref, 100},
- {Colum.RevRef, 100},
- {Colum.Type, 100},
- {Colum.DiskSize, 100},
- {Colum.Path, 500},
+ {Colum.Name, 450},
+ {Colum.Ref, 70},
+ {Colum.RevRef, 70},
+ {Colum.Type, 70},
+ {Colum.DiskSize, 70},
+ {Colum.Path, 870},
};
- private Dictionary<Colum, int> ColumOffsetX = new Dictionary<Colum, int>();
+ private Dictionary<Colum, int> ColumOffsetX = null;
private void AdjustColumOffsetX()
{
- if (ColumOffsetX == null)
+ if (ColumOffsetX != null)
return;
- ColumOffsetX.Clear();
+ ColumOffsetX = new Dictionary<Colum, int>();
ColumOffsetX.Add(Colum.Name, 0);
ColumOffsetX.Add(Colum.Ref, ColumOffsetX[Colum.Name] + ColumWidth[Colum.Name]);
ColumOffsetX.Add(Colum.RevRef, ColumOffsetX[Colum.Ref] + ColumWidth[Colum.Ref]);
@@ -406,13 +513,14 @@ class AssetBrowser : EditorWindow
{
window = editor.position;
}
-
+
public void OnGUI()
{
// 调试
if (editor == null)
editor = GetWindow<AssetBrowser>();
- drawer = Drawer.Get();
+ if (drawer == null)
+ drawer = Drawer.Get();
AdjustColumOffsetX();
AdjustWindow();
@@ -444,11 +552,44 @@ class AssetBrowser : EditorWindow
private void OnDirectory()
{
float offsetY = directoryOffsetY + scrollPos.y;
- drawer.DrawLabel(new Rect(0, offsetY, 95, kLineHeight), "资源目录 Assets/");
- drawer.DrawTextfield(new Rect(95, offsetY, 250, kLineHeight), directory, ref directory);
- bool load;
+
+ Rect dragRect = new Rect(0, offsetY, 1000, 20);
+ string olddirectory = filterdirectory;
+ drawer.DrawLabel(new Rect(0, offsetY, 95, kLineHeight), "资源目录 Assets\\");
+ drawer.DrawTextfield(new Rect(95, offsetY, 250, kLineHeight), filterdirectory, ref filterdirectory);
+ if (filterdirectory == null)
+ filterdirectory = "";
+ // 拖拽
+ Event e = Event.current;
+ if (dragRect.Contains(e.mousePosition))
+ {
+ if (e.type == EventType.dragUpdated)
+ DragAndDrop.visualMode = DragAndDropVisualMode.Generic;
+ else if (e.type == EventType.DragPerform)
+ {
+ Object[] objs = DragAndDrop.objectReferences;
+ e.Use();
+ if (DragAndDrop.objectReferences.Length > 0)
+ {
+ Object obj = DragAndDrop.objectReferences[0];
+ filterdirectory = AssetDatabase.GetAssetPath(obj);
+ if (filterdirectory.Equals("Assets"))
+ {
+ filterdirectory = string.Empty;
+ }
+ else
+ {
+ filterdirectory = filterdirectory.Substring(7);
+ }
+ }
+ }
+ }
+ filterdirectory = AssetDataManager.Get().FormatPath(filterdirectory);
+ if (filterdirectory != olddirectory)
+ ProcessTreeBuffer();
+ bool load;
drawer.DrawButton(new Rect(350, offsetY, 50, kLineHeight), "载入", out load);
- if(load)
+ if (load)
{
ProcessAssets();
ProcessTree();
@@ -458,13 +599,23 @@ class AssetBrowser : EditorWindow
private void OnFilters()
{
+ string oldfilterfile = filterFile;
+ bool oldfilterScene = filterScene;
+ bool oldfilterPrefab = filterPrefab;
+ bool oldfilterMaterial = filterMaterial;
+ bool oldfilterAsset = filterAsset;
+ bool oldfilterMesh = filterMesh;
+ bool oldfilterTexture = filterTexture;
+ bool oldfilterShader = filterShader;
+ bool oldfilterScript = filterScript;
+ bool oldfilterCSV = filterCSV;
// 文件匹配
drawer.DrawLabel(new Rect(0, filtersOffsetY + scrollPos.y, 100, kLineHeight), "匹配文件");
drawer.DrawTextfield(new Rect(50, filtersOffsetY + scrollPos.y, 150, kLineHeight), filterFile, ref filterFile);
// 类型过滤
float offsetX = 250;
float offsetY = filtersOffsetY + scrollPos.y;
- int width = 70;
+ int width = 70;
drawer.DrawCheckBox(new Rect(offsetX, offsetY, width, kLineHeight), "场景", filterScene, ref filterScene);
drawer.DrawCheckBox(new Rect(offsetX + width, offsetY, width, kLineHeight), "Prefab", filterPrefab, ref filterPrefab);
drawer.DrawCheckBox(new Rect(offsetX + width * 2, offsetY, width, kLineHeight), "材质", filterMaterial, ref filterMaterial);
@@ -474,6 +625,19 @@ class AssetBrowser : EditorWindow
drawer.DrawCheckBox(new Rect(offsetX + width * 6, offsetY, width, kLineHeight), "Shader", filterShader, ref filterShader);
drawer.DrawCheckBox(new Rect(offsetX + width * 7, offsetY, width, kLineHeight), "脚本", filterScript, ref filterScript);
drawer.DrawCheckBox(new Rect(offsetX + width * 8, offsetY, width, kLineHeight), "CSV", filterCSV, ref filterCSV);
+ // 刷新TreeBuffer
+ if( oldfilterfile != filterFile ||
+ oldfilterScene != filterScene||
+ oldfilterPrefab != filterPrefab||
+ oldfilterMaterial != filterMaterial||
+ oldfilterAsset != filterAsset||
+ oldfilterMesh != filterMesh||
+ oldfilterTexture != filterTexture||
+ oldfilterShader != filterShader||
+ oldfilterScript != filterScript||
+ oldfilterCSV != filterCSV
+ )
+ ProcessTreeBuffer();
}
private void OnAsset()
@@ -490,7 +654,7 @@ class AssetBrowser : EditorWindow
new Rect(scrollPos.x, scrollPos.y + assetsTreeOffsetY, window.width, window.height - assetsTreeOffsetY),
scrollPos,
new Rect(0, 0, contentWidth, contentHeight - assetsTreeOffsetY),
- false , false
+ false, false
);
}
@@ -502,44 +666,87 @@ class AssetBrowser : EditorWindow
private void OnHeader()
{
float scrollY = scrollPos.y;
- drawer.DrawButtonMid(new Rect(ColumOffsetX[Colum.Name], headerOffsetY + scrollY, ColumWidth[Colum.Name], kLineHeight), ColumHeader[Colum.Name]);
- drawer.DrawButtonMid(new Rect(ColumOffsetX[Colum.Ref], headerOffsetY + scrollY, ColumWidth[Colum.Ref], kLineHeight), ColumHeader[Colum.Ref]);
- drawer.DrawButtonMid(new Rect(ColumOffsetX[Colum.RevRef], headerOffsetY + scrollY, ColumWidth[Colum.RevRef], kLineHeight), ColumHeader[Colum.RevRef]);
- drawer.DrawButtonMid(new Rect(ColumOffsetX[Colum.Type], headerOffsetY + scrollY, ColumWidth[Colum.Type], kLineHeight), ColumHeader[Colum.Type]);
- drawer.DrawButtonMid(new Rect(ColumOffsetX[Colum.DiskSize], headerOffsetY + scrollY, ColumWidth[Colum.DiskSize], kLineHeight), ColumHeader[Colum.DiskSize]);
- drawer.DrawButtonMid(new Rect(ColumOffsetX[Colum.Path], headerOffsetY + scrollY, ColumWidth[Colum.Path], kLineHeight), ColumHeader[Colum.Path]);
+ bool clickName = false;
+ bool clickRef = false;
+ bool clickRevRef = false;
+ bool clickType = false;
+ bool clickDiskSize = false;
+ bool clickPath = false;
+ drawer.DrawButtonMid(new Rect(ColumOffsetX[Colum.Name], headerOffsetY + scrollY, ColumWidth[Colum.Name], kLineHeight), ColumHeader[Colum.Name], out clickName);
+ drawer.DrawButtonMid(new Rect(ColumOffsetX[Colum.Ref], headerOffsetY + scrollY, ColumWidth[Colum.Ref], kLineHeight), ColumHeader[Colum.Ref], out clickRef);
+ drawer.DrawButtonMid(new Rect(ColumOffsetX[Colum.RevRef], headerOffsetY + scrollY, ColumWidth[Colum.RevRef], kLineHeight), ColumHeader[Colum.RevRef], out clickRevRef);
+ drawer.DrawButtonMid(new Rect(ColumOffsetX[Colum.Type], headerOffsetY + scrollY, ColumWidth[Colum.Type], kLineHeight), ColumHeader[Colum.Type], out clickType);
+ drawer.DrawButtonMid(new Rect(ColumOffsetX[Colum.DiskSize], headerOffsetY + scrollY, ColumWidth[Colum.DiskSize], kLineHeight), ColumHeader[Colum.DiskSize], out clickDiskSize);
+ drawer.DrawButtonMid(new Rect(ColumOffsetX[Colum.Path], headerOffsetY + scrollY, ColumWidth[Colum.Path], kLineHeight), ColumHeader[Colum.Path], out clickPath);
+ if(clickName)
+ {
+ orderBase = OrderBase.Name;
+ orderName = -orderName;
+ ReorderTreeBuffer();
+ }
+ else if (clickRef)
+ {
+ orderBase = OrderBase.Ref;
+ orderRef = -orderRef;
+ ReorderTreeBuffer();
+ }
+ else if (clickRevRef)
+ {
+ orderBase = OrderBase.RevRef;
+ orderRevRef = -orderRevRef;
+ ReorderTreeBuffer();
+ }
+ else if (clickType)
+ {
+ orderBase = OrderBase.Type;
+ orderType = -orderType;
+ ReorderTreeBuffer();
+ }
+ else if (clickDiskSize)
+ {
+ orderBase = OrderBase.DiskSize;
+ orderDiskSize = -orderDiskSize;
+ ReorderTreeBuffer();
+ }
+ else if (clickPath)
+ {
+ orderBase = OrderBase.Path;
+ orderPath = -orderPath;
+ ReorderTreeBuffer();
+ }
}
private void OnAssetsTree()
{
int count = 0;
- foreach(FileTree.Node node in assetsTree.root)
+ foreach (FileTree.Node node in assetsTreeBuffer.root)
{
DrawNode(node, 0, ref count);
}
}
- private bool Filter(FileTree.Node node, int hierachy)
+ private bool Filter(FileTree.Node node)
{
- if(hierachy == 0)
- {
- AssetData asset;
- if (!AssetDataManager.AllAssets.TryGetValue(node.GUID, out asset))
- return false;
- // 文件类型过滤
- if (asset.FileType == AssetData.AssetType.Scene && !filterScene) return false;
- else if (asset.FileType == AssetData.AssetType.Prefab&& !filterPrefab) return false;
- else if (asset.FileType == AssetData.AssetType.Material&& !filterMaterial) return false;
- else if (asset.FileType == AssetData.AssetType.Asset&& !filterAsset) return false;
- else if (asset.FileType == AssetData.AssetType.Mesh&& !filterMesh) return false;
- else if (asset.FileType == AssetData.AssetType.CSV&& !filterCSV) return false;
- else if (asset.FileType == AssetData.AssetType.Script&& !filterScript) return false;
- else if (asset.FileType == AssetData.AssetType.Shader&& !filterShader) return false;
- else if (asset.FileType == AssetData.AssetType.Texture&& !filterTexture) return false;
- // 文件名
- if (asset.Name.IndexOf(filterFile) == -1)
- return false;
- }
+ AssetData asset;
+ AssetDataManager assetDataManager = AssetDataManager.Get();
+ if (!assetDataManager.AllAssets.TryGetValue(node.GUID, out asset))
+ return false;
+ // 文件类型过滤
+ if (asset.FileType == AssetData.AssetType.Scene && !filterScene) return false;
+ else if (asset.FileType == AssetData.AssetType.Prefab && !filterPrefab) return false;
+ else if (asset.FileType == AssetData.AssetType.Material && !filterMaterial) return false;
+ else if (asset.FileType == AssetData.AssetType.Asset && !filterAsset) return false;
+ else if (asset.FileType == AssetData.AssetType.Mesh && !filterMesh) return false;
+ else if (asset.FileType == AssetData.AssetType.CSV && !filterCSV) return false;
+ else if (asset.FileType == AssetData.AssetType.Script && !filterScript) return false;
+ else if (asset.FileType == AssetData.AssetType.Shader && !filterShader) return false;
+ else if (asset.FileType == AssetData.AssetType.Texture && !filterTexture) return false;
+ // 文件路径
+ if (asset.AssetPath.IndexOf(filterdirectory) == -1)
+ return false;
+ // 文件名
+ if (asset.Name.IndexOf(filterFile) == -1)
+ return false;
return true;
}
@@ -547,8 +754,6 @@ class AssetBrowser : EditorWindow
// 按照深度绘制
private void DrawNode(FileTree.Node node, int hierachy, ref int count)
{
- if (!Filter(node, hierachy))
- return;
++count;
contentHeight = count * kLineHeight + assetsTreeOffsetY;
DrawAssetInfo(node, hierachy, count - 1);
@@ -565,35 +770,52 @@ class AssetBrowser : EditorWindow
{
Drawer drawer = Drawer.Get();
AssetData asset;
- if (!AssetDataManager.AllAssets.TryGetValue(node.GUID, out asset))
+ AssetDataManager assetDataManager = AssetDataManager.Get();
+ if (!assetDataManager.AllAssets.TryGetValue(node.GUID, out asset))
return;
int offsetY = index * kLineHeight;
// 绘制背景
drawer.DrawBackground(new Rect(0, offsetY, contentWidth, kLineHeight), (index & 1) == 1 ? drawer.ColorHeavy : drawer.ColorLight);
+ // 绘制定位按钮
+ if(selectedNode == node)
+ {
+ bool ping = false;
+ drawer.DrawPing(new Rect(hierachy * kTabWidth, offsetY, 10, kLineHeight), ref ping);
+ if (ping)
+ {
+ Object obj = AssetDatabase.LoadAssetAtPath(asset.AssetPath, asset.ObjType);
+ if (obj)
+ {
+ EditorGUIUtility.PingObject(obj);
+ }
+ }
+ }
// 绘制折叠按钮
if (node.Children.Count > 0)
- drawer.DrawFoldout(new Rect(hierachy * kTabWidth, offsetY, 10, kLineHeight), ref node.Foldout);
+ drawer.DrawFoldout(new Rect(hierachy * kTabWidth + 7, offsetY, kLineHeight, kLineHeight), ref node.Foldout);
// 绘制选择按钮
bool clicked;
- drawer.DrawSelector(new Rect(hierachy * kTabWidth + 12, offsetY, contentWidth, kLineHeight), selectedNode == node, out clicked);
+ drawer.DrawSelector(new Rect(hierachy * kTabWidth + 19 + 7, offsetY, contentWidth, kLineHeight), selectedNode == node, out clicked);
if (clicked)
{
- if(selectedNode != node)
+ if (selectedNode != node)
selectedNode = node;
else
{
- AssetReverse.Show(node.GUID);
- selectedNode = null;
+ AssetReverse.ShowWindow(node.GUID);
+ selectedNode = null;
}
- }
+ }
+ if (selectedNode == node)
+ drawer.SetTextColor(Color.white);
// 绘制图标
- drawer.DrawAssetIcon(new Rect(hierachy * kTabWidth + 12, offsetY, ColumWidth[Colum.Name], kLineHeight), asset);
+ drawer.DrawAssetIcon(new Rect(hierachy * kTabWidth + 19 + 7, offsetY, ColumWidth[Colum.Name], kLineHeight), asset);
// 绘制引用数
drawer.DrawLabel(new Rect(ColumOffsetX[Colum.Ref], offsetY, 100, kLineHeight), asset.RefCount.ToString());
// 绘制反向引用数
List<string> revRef;
int revRefCount = 0;
- if (AssetDataManager.AssetsReverse.TryGetValue(node.GUID, out revRef))
+ if (assetDataManager.AssetsReverse.TryGetValue(node.GUID, out revRef))
revRefCount = revRef.Count;
drawer.DrawLabel(new Rect(ColumOffsetX[Colum.RevRef], offsetY, 100, kLineHeight), revRefCount.ToString());
// 绘制资源类型
@@ -602,41 +824,104 @@ class AssetBrowser : EditorWindow
drawer.DrawLabel(new Rect(ColumOffsetX[Colum.DiskSize], offsetY, 100, kLineHeight), asset.DiskSizeStr);
// 绘制资源路径
drawer.DrawLabel(new Rect(ColumOffsetX[Colum.Path], offsetY, 1000, kLineHeight), asset.AssetPath);
+ if (selectedNode == node)
+ drawer.ResetTextColor();
}
private void ProcessAssets()
{
AssetDataManager assetManager = AssetDataManager.Get();
assetManager.ClearAssets();
- assetManager.LoadAssets(assetManager.AssetPathToFullPath("Assets/" + directory));
+ assetManager.LoadAssets(assetManager.AssetPathToFullPath("Assets/"));
}
private void ProcessTree()
{
AssetDataManager assetManager = AssetDataManager.Get();
assetsTree.root.Clear();
- for(int i = 0; i < AssetData.AssetTypeCount; ++i)
+ for (int i = 0; i < (int)AssetData.AssetType.TypeCount; ++i)
{
- Dictionary<string, AssetData> assets = AssetDataManager.Assets[i];
- foreach(var asset in assets)
+ Dictionary<string, AssetData> assets = assetManager.Assets[i];
+ foreach (var asset in assets)
{
AssetData data = asset.Value;
FileTree.Node node = ProcessNode(data);
- assetsTree.root.Add(node);
+ assetsTree.root.Add(node);
}
}
+ ProcessTreeBuffer();
+ }
+
+ // 文件树缓冲
+ private void ProcessTreeBuffer()
+ {
+ assetsTreeBuffer.root.Clear();
+ foreach(FileTree.Node node in assetsTree.root)
+ {
+ if(!Filter(node))
+ continue;
+ assetsTreeBuffer.root.Add(node);
+ }
+ orderBase = OrderBase.Path;
+ orderPath = 1;
+ ReorderTreeBuffer();
+ }
+
+ private int clamp(int n)
+ {
+ if (n > 0) return 1;
+ else if (n < 0) return -1;
+ else return 0;
+ }
+
+ // Tree Buffer重新排序
+ private void ReorderTreeBuffer()
+ {
+ assetsTreeBuffer.root.Sort((FileTree.Node a, FileTree.Node b) =>
+ {
+ AssetData aa, ab;
+ AssetDataManager.Get().AllAssets.TryGetValue(a.GUID, out aa);
+ AssetDataManager.Get().AllAssets.TryGetValue(b.GUID, out ab);
+ if(aa == null || ab == null)
+ return 0;
+ if (orderBase == OrderBase.Name) return clamp(orderName * aa.Name.CompareTo(ab.Name));
+ else if (orderBase == OrderBase.Ref) return clamp(orderRef * (aa.RefCount - ab.RefCount));
+ else if (orderBase == OrderBase.RevRef)
+ {
+ List<string> ra, rb;
+ int rac = 0, rbc = 0;
+ AssetDataManager.Get().AssetsReverse.TryGetValue(a.GUID, out ra);
+ AssetDataManager.Get().AssetsReverse.TryGetValue(b.GUID, out rb);
+ if (ra != null)
+ rac = ra.Count;
+ if (rb != null)
+ rbc = rb.Count;
+ return clamp(orderRevRef * (rac - rbc));
+ }
+ else if (orderBase == OrderBase.Type)
+ {
+ if(aa.FileType == ab.FileType)
+ {
+ return clamp(orderType * ((int)aa.SubFileType - (int)ab.SubFileType));
+ }
+ return clamp(orderType * ((int)aa.FileType - (int)ab.FileType));
+ }
+ else if (orderBase == OrderBase.DiskSize) return clamp(orderDiskSize * (int)(aa.DiskSize - ab.DiskSize));
+ else if (orderBase == OrderBase.Path) return clamp(orderPath * aa.AssetPath.CompareTo(ab.AssetPath));
+ else return 1;
+ });
}
private FileTree.Node ProcessNode(AssetData data)
{
AssetDataManager assetManager = AssetDataManager.Get();
FileTree.Node node = new FileTree.Node(data.GUID);
- foreach(List<string> deps in data.Dependencies)
+ foreach (List<string> deps in data.Dependencies)
{
- foreach(string guid in deps)
+ foreach (string guid in deps)
{
AssetData dep;
- if(AssetDataManager.AllAssets.TryGetValue(guid, out dep))
+ if (assetManager.AllAssets.TryGetValue(guid, out dep))
{
FileTree.Node child = ProcessNode(dep);
node.Children.Add(child);
@@ -648,56 +933,119 @@ class AssetBrowser : EditorWindow
}
-class AssetReverse : EditorWindow
+// 反向查找
+public class AssetReverse : EditorWindow
{
- private static AssetReverse editor;
private static Drawer drawer;
-
+ private static AssetReverse editor;
+ private static AssetDataManager assetDataManager;
private static string GUID;
- private static AssetData asset;
- private Vector2 scrollPos = new Vector2(0, 0);
-
- private int kLineHeight = 20;
- private int contentHeight = 0;
-
- public static void Show(string guid)
+ private static AssetData resource = null;
+ public static void ShowWindow(string guid)
{
editor = GetWindow<AssetReverse>();
editor.titleContent = new GUIContent("Asset Reverse");
+ drawer = Drawer.Get();
+ assetDataManager = AssetDataManager.Get();
+ AdjustkColumOffset();
GUID = guid;
- if(AssetDataManager.AllAssets.TryGetValue(GUID, out asset))
- {
- }
- Drawer dawer = Drawer.Get();
+ if (!assetDataManager.AllAssets.TryGetValue(GUID, out resource))
+ resource = null;
}
- public void OnGUI()
+ private enum Colums
+ {
+ cName, // "资源列表和引用关系"
+ cLocation, // "资源位置"
+ }
+
+ private static readonly Dictionary<Colums, string> kColumHeader = new Dictionary<Colums, string>{
+ {Colums.cName, "资源名"},
+ {Colums.cLocation, "位置"},
+ };
+
+ private static readonly Dictionary<Colums, int> kColumWidth = new Dictionary<Colums, int>{
+ {Colums.cName, 300},
+ {Colums.cLocation, 500},
+ };
+
+ private static Dictionary<Colums, int> kColumOffset = null;
+
+ private static void AdjustkColumOffset()
{
- if (asset == null)
+ if (kColumOffset != null)
return;
- drawer = Drawer.Get();
- drawer.DrawAssetIcon(new Rect(0, 0, 200, kLineHeight), asset);
- scrollPos = GUI.BeginScrollView(new Rect(0, kLineHeight, editor.position.width, editor.position.height - kLineHeight), scrollPos, new Rect(0, 0, 1500, contentHeight));
- // 标题
- drawer.DrawButtonMid(new Rect(0, 0, 400, 20), "资源名");
- drawer.DrawButtonMid(new Rect(400, 0, 400, 20), "资源路径");
- //
- List<string> revRef;
- if(AssetDataManager.AssetsReverse.TryGetValue(GUID, out revRef))
+ kColumOffset = new Dictionary<Colums, int>();
+ kColumOffset.Clear();
+ kColumOffset.Add(Colums.cName, 0);
+ kColumOffset.Add(Colums.cLocation, kColumWidth[Colums.cName] + kColumOffset[Colums.cName]);
+ }
+
+ private Rect windowRect;
+ private readonly int kLineHeight = 20;
+ private Vector2 scrollPos = new Vector2(0, 0);
+
+ private float ContentWidth = 1200;
+ private float ContentHeight = 20;
+ private int kListOffsetY = 40; // 2*kLineHeight
+
+ void OnGUI()
+ {
+ if (resource == null || GUID == null)
+ return;
+ AdjustWindowRect();
+ DrawHeader();
+ BeginScrollView();
+ DrawRevDepend();
+ EndScrollView();
+ }
+
+ private void DrawHeader()
+ {
+ GUIContent content = EditorGUIUtility.ObjectContent(null, resource.ObjType);
+ content.text = resource.AssetPath;
+ GUI.Label(new Rect(0, 0, 1000, kLineHeight), content);
+ GUI.Button(new Rect(kColumOffset[Colums.cName], kLineHeight, kColumWidth[Colums.cName], kLineHeight), kColumHeader[Colums.cName], EditorStyles.miniButtonMid);
+ GUI.Button(new Rect(kColumOffset[Colums.cLocation], kLineHeight, windowRect.width - kColumWidth[Colums.cName], kLineHeight), kColumHeader[Colums.cLocation], EditorStyles.miniButtonMid);
+ }
+
+ private void DrawRevDepend()
+ {
+ List<string> revDeps;
+ if (assetDataManager.AssetsReverse.TryGetValue(GUID, out revDeps))
{
+ int yoffset = 0;
int count = 0;
- foreach(string guid in revRef)
+ ContentHeight = 0;
+ foreach (string guid in revDeps)
{
- AssetData data;
- if(AssetDataManager.AllAssets.TryGetValue(guid, out data))
+ AssetData resource;
+ if (assetDataManager.AllAssets.TryGetValue(guid, out resource))
{
- drawer.DrawAssetIcon(new Rect(0, kLineHeight + count * kLineHeight, 400, kLineHeight), data);
- drawer.DrawLabel(new Rect(400, kLineHeight + count * kLineHeight, 400, kLineHeight), data.AssetPath);
+ drawer.DrawBackground(new Rect(0, yoffset, ContentWidth, kLineHeight), (count & 1) == 1 ? drawer.ColorHeavy : drawer.ColorLight);
+ drawer.DrawAssetIcon(new Rect(0, yoffset, 1000, kLineHeight), resource);
+ drawer.DrawLabel(new Rect(kColumOffset[Colums.cLocation], yoffset, 1000, kLineHeight), resource.AssetPath);
+ yoffset += kLineHeight;
+ ContentHeight += kLineHeight;
++count;
- contentHeight = count * kLineHeight + kLineHeight;
}
}
}
+ }
+
+ private void BeginScrollView()
+ {
+ scrollPos = GUI.BeginScrollView(new Rect(0, kLineHeight * 2, windowRect.width, windowRect.height - kListOffsetY), scrollPos, new Rect(0, 0, windowRect.width, ContentHeight), false, true);
+ }
+
+ private void EndScrollView()
+ {
GUI.EndScrollView();
}
+
+ private void AdjustWindowRect()
+ {
+ windowRect = editor.position;
+ ContentWidth = windowRect.width;
+ }
}