音乐效果
This commit is contained in:
1653
Assets/FindReference2/Editor/Script/FR2_Asset.cs
Normal file
1653
Assets/FindReference2/Editor/Script/FR2_Asset.cs
Normal file
File diff suppressed because it is too large
Load Diff
10
Assets/FindReference2/Editor/Script/FR2_Asset.cs.meta
Normal file
10
Assets/FindReference2/Editor/Script/FR2_Asset.cs.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7f1ed5d1134de134a9e052ef368e3a84
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
304
Assets/FindReference2/Editor/Script/FR2_AssetType.cs
Normal file
304
Assets/FindReference2/Editor/Script/FR2_AssetType.cs
Normal file
@@ -0,0 +1,304 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace vietlabs.fr2
|
||||
{
|
||||
public class AssetType
|
||||
{
|
||||
// ------------------------------- STATIC -----------------------------
|
||||
|
||||
internal static readonly AssetType[] FILTERS =
|
||||
{
|
||||
new AssetType("Scene", ".unity"),
|
||||
new AssetType("Prefab", ".prefab"),
|
||||
new AssetType("Model", ".3df", ".3dm", ".3dmf", ".3dv", ".3dx", ".c5d", ".lwo", ".lws", ".ma", ".mb",
|
||||
".mesh", ".vrl", ".wrl", ".wrz", ".fbx", ".dae", ".3ds", ".dxf", ".obj", ".skp", ".max", ".blend"),
|
||||
new AssetType("Material", ".mat", ".cubemap", ".physicsmaterial"),
|
||||
new AssetType("Texture", ".ai", ".apng", ".png", ".bmp", ".cdr", ".dib", ".eps", ".exif", ".ico", ".icon",
|
||||
".j", ".j2c", ".j2k", ".jas", ".jiff", ".jng", ".jp2", ".jpc", ".jpe", ".jpeg", ".jpf", ".jpg", "jpw",
|
||||
"jpx", "jtf", ".mac", ".omf", ".qif", ".qti", "qtif", ".tex", ".tfw", ".tga", ".tif", ".tiff", ".wmf",
|
||||
".psd", ".exr", ".rendertexture"),
|
||||
new AssetType("Video", ".asf", ".asx", ".avi", ".dat", ".divx", ".dvx", ".mlv", ".m2l", ".m2t", ".m2ts",
|
||||
".m2v", ".m4e", ".m4v", "mjp", ".mov", ".movie", ".mp21", ".mp4", ".mpe", ".mpeg", ".mpg", ".mpv2",
|
||||
".ogm", ".qt", ".rm", ".rmvb", ".wmv", ".xvid", ".flv"),
|
||||
new AssetType("Audio", ".mp3", ".wav", ".ogg", ".aif", ".aiff", ".mod", ".it", ".s3m", ".xm"),
|
||||
new AssetType("Script", ".cs", ".js", ".boo", ".h"),
|
||||
new AssetType("Text", ".txt", ".json", ".xml", ".bytes", ".sql"),
|
||||
new AssetType("Shader", ".shader", ".cginc"),
|
||||
new AssetType("Animation", ".anim", ".controller", ".overridecontroller", ".mask"),
|
||||
new AssetType("Unity Asset", ".asset", ".guiskin", ".flare", ".fontsettings", ".prefs"),
|
||||
new AssetType("Others") //
|
||||
};
|
||||
|
||||
private static FR2_Ignore _ignore;
|
||||
public HashSet<string> extension;
|
||||
public string name;
|
||||
|
||||
public AssetType(string name, params string[] exts)
|
||||
{
|
||||
this.name = name;
|
||||
extension = new HashSet<string>();
|
||||
for (var i = 0; i < exts.Length; i++)
|
||||
{
|
||||
extension.Add(exts[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private static FR2_Ignore ignore
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_ignore == null)
|
||||
{
|
||||
_ignore = new FR2_Ignore();
|
||||
}
|
||||
|
||||
return _ignore;
|
||||
}
|
||||
}
|
||||
|
||||
public static int GetIndex(string ext)
|
||||
{
|
||||
for (var i = 0; i < FILTERS.Length - 1; i++)
|
||||
{
|
||||
if (FILTERS[i].extension.Contains(ext))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return FILTERS.Length - 1; //Others
|
||||
}
|
||||
|
||||
public static bool DrawSearchFilter()
|
||||
{
|
||||
int n = FILTERS.Length;
|
||||
var nCols = 4;
|
||||
int nRows = Mathf.CeilToInt(n / (float)nCols);
|
||||
var result = false;
|
||||
|
||||
EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
|
||||
{
|
||||
if (GUILayout.Button("All", EditorStyles.toolbarButton) && !FR2_Setting.IsIncludeAllType())
|
||||
{
|
||||
FR2_Setting.IncludeAllType();
|
||||
result = true;
|
||||
}
|
||||
|
||||
if (GUILayout.Button("None", EditorStyles.toolbarButton) && FR2_Setting.GetExcludeType() != -1)
|
||||
{
|
||||
FR2_Setting.ExcludeAllType();
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
for (var i = 0; i < nCols; i++)
|
||||
{
|
||||
GUILayout.BeginVertical();
|
||||
for (var j = 0; j < nRows; j++)
|
||||
{
|
||||
int idx = i * nCols + j;
|
||||
if (idx >= n)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
bool s = !FR2_Setting.IsTypeExcluded(idx);
|
||||
bool s1 = GUILayout.Toggle(s, FILTERS[idx].name);
|
||||
if (s1 != s)
|
||||
{
|
||||
result = true;
|
||||
FR2_Setting.ToggleTypeExclude(idx);
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.EndVertical();
|
||||
if ((i + 1) * nCols >= n)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void SetDirtyIgnore()
|
||||
{
|
||||
ignore.SetDirty();
|
||||
}
|
||||
|
||||
public static bool DrawIgnoreFolder()
|
||||
{
|
||||
var change = false;
|
||||
ignore.Draw();
|
||||
|
||||
|
||||
|
||||
|
||||
// FR2_Helper.GuiLine();
|
||||
// List<string> lst = FR2_Setting.IgnoreFolder.ToList();
|
||||
// bool change = false;
|
||||
// pos = EditorGUILayout.BeginScrollView(pos);
|
||||
// for(int i =0; i < lst.Count; i++)
|
||||
// {
|
||||
// GUILayout.BeginHorizontal();
|
||||
// {
|
||||
// if(GUILayout.Button("X", GUILayout.Width(30)))
|
||||
// {
|
||||
// change = true;
|
||||
// FR2_Setting.RemoveIgnore(lst[i]);
|
||||
// }
|
||||
// GUILayout.Label(lst[i]);
|
||||
// }GUILayout.EndHorizontal();
|
||||
// }
|
||||
// EditorGUILayout.EndScrollView();
|
||||
return change;
|
||||
}
|
||||
|
||||
private class FR2_Ignore
|
||||
{
|
||||
public readonly FR2_TreeUI2.GroupDrawer groupIgnore;
|
||||
private bool dirty;
|
||||
private Dictionary<string, FR2_Ref> refs;
|
||||
|
||||
public FR2_Ignore()
|
||||
{
|
||||
groupIgnore = new FR2_TreeUI2.GroupDrawer(DrawGroup, DrawItem);
|
||||
groupIgnore.hideGroupIfPossible = false;
|
||||
|
||||
ApplyFiter();
|
||||
}
|
||||
|
||||
private void DrawItem(Rect r, string guid)
|
||||
{
|
||||
FR2_Ref rf;
|
||||
if (!refs.TryGetValue(guid, out rf))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (rf.depth == 1) //mode != Mode.Dependency &&
|
||||
{
|
||||
Color c = GUI.color;
|
||||
GUI.color = Color.blue;
|
||||
GUI.DrawTexture(new Rect(r.x - 4f, r.y + 2f, 2f, 2f), EditorGUIUtility.whiteTexture);
|
||||
GUI.color = c;
|
||||
}
|
||||
|
||||
rf.asset.Draw(r, false,
|
||||
true,
|
||||
false, false, false, false, null);
|
||||
|
||||
Rect drawR = r;
|
||||
drawR.x = drawR.x + drawR.width - 50f; // (groupDrawer.TreeNoScroll() ? 60f : 70f) ;
|
||||
drawR.width = 30;
|
||||
drawR.y += 1;
|
||||
drawR.height -= 2;
|
||||
|
||||
if (GUI.Button(drawR, "X", EditorStyles.miniButton))
|
||||
{
|
||||
FR2_Setting.RemoveIgnore(rf.asset.assetPath);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawGroup(Rect r, string id, int childCound)
|
||||
{
|
||||
GUI.Label(r, id, EditorStyles.boldLabel);
|
||||
if (childCound <= 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Rect drawR = r;
|
||||
drawR.x = drawR.x + drawR.width - 50f; // (groupDrawer.TreeNoScroll() ? 60f : 70f) ;
|
||||
drawR.width = 30;
|
||||
drawR.y += 1;
|
||||
drawR.height -= 2;
|
||||
}
|
||||
|
||||
public void SetDirty()
|
||||
{
|
||||
dirty = true;
|
||||
}
|
||||
//private float sizeRatio {
|
||||
// get{
|
||||
// if(FR2_Window.window != null)
|
||||
// return FR2_Window.window.sizeRatio;
|
||||
// return .3f;
|
||||
// }
|
||||
//}
|
||||
|
||||
public void Draw()
|
||||
{
|
||||
if (dirty)
|
||||
{
|
||||
ApplyFiter();
|
||||
}
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
{
|
||||
GUILayout.Space(4f);
|
||||
var drops = GUI2.DropZone("Drag & Drop folders here to exclude", 100, 95);
|
||||
if (drops != null && drops.Length > 0)
|
||||
{
|
||||
for (var i = 0; i < drops.Length; i++)
|
||||
{
|
||||
string path = AssetDatabase.GetAssetPath(drops[i]);
|
||||
if (path.Equals(FR2_Cache.DEFAULT_CACHE_PATH))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
FR2_Setting.AddIgnore(path);
|
||||
}
|
||||
}
|
||||
|
||||
groupIgnore.DrawLayout();
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
|
||||
private void ApplyFiter()
|
||||
{
|
||||
dirty = false;
|
||||
refs = new Dictionary<string, FR2_Ref>();
|
||||
|
||||
//foreach (KeyValuePair<string, List<string>> item in FR2_Setting.IgnoreFiltered)
|
||||
foreach (string item2 in FR2_Setting.s.listIgnore)
|
||||
{
|
||||
string guid = AssetDatabase.AssetPathToGUID(item2);
|
||||
if (string.IsNullOrEmpty(guid))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
FR2_Asset asset = FR2_Cache.Api.Get(guid, true);
|
||||
var r = new FR2_Ref(0, 0, asset, null, "Ignore");
|
||||
refs.Add(guid, r);
|
||||
}
|
||||
|
||||
groupIgnore.Reset
|
||||
(
|
||||
refs.Values.ToList(),
|
||||
rf => rf.asset != null ? rf.asset.guid : "",
|
||||
GetGroup,
|
||||
SortGroup
|
||||
);
|
||||
}
|
||||
|
||||
private string GetGroup(FR2_Ref rf)
|
||||
{
|
||||
return "Ignore";
|
||||
}
|
||||
|
||||
private void SortGroup(List<string> groups) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
10
Assets/FindReference2/Editor/Script/FR2_AssetType.cs.meta
Normal file
10
Assets/FindReference2/Editor/Script/FR2_AssetType.cs.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: af50e16ff6b530b4b808183a3ae0722b
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
257
Assets/FindReference2/Editor/Script/FR2_Bookmark.cs
Normal file
257
Assets/FindReference2/Editor/Script/FR2_Bookmark.cs
Normal file
@@ -0,0 +1,257 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityObject = UnityEngine.Object;
|
||||
|
||||
namespace vietlabs.fr2
|
||||
{
|
||||
public class FR2_Bookmark : IRefDraw
|
||||
{
|
||||
internal static HashSet<string> guidSet = new HashSet<string>();
|
||||
internal static HashSet<string> instSet = new HashSet<string>(); // Do not reference directly to SceneObject (which might be destroyed anytime)
|
||||
|
||||
public static int Count
|
||||
{
|
||||
get { return guidSet.Count + instSet.Count; }
|
||||
}
|
||||
|
||||
public static bool Contains(string guidOrInstID)
|
||||
{
|
||||
return guidSet.Contains(guidOrInstID) || instSet.Contains(guidOrInstID);
|
||||
}
|
||||
|
||||
public static bool Contains(UnityObject sceneObject)
|
||||
{
|
||||
var id = sceneObject.GetInstanceID().ToString();
|
||||
return instSet.Contains(id);
|
||||
}
|
||||
public static bool Contains(FR2_Ref rf)
|
||||
{
|
||||
if (rf.isSceneRef)
|
||||
{
|
||||
if (instSet == null) return false;
|
||||
return instSet.Contains(rf.component.GetInstanceID().ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (guidSet == null) return false;
|
||||
return guidSet.Contains(rf.asset.guid);
|
||||
}
|
||||
}
|
||||
public static void Add(UnityObject sceneObject)
|
||||
{
|
||||
if (sceneObject == null) return;
|
||||
var id = sceneObject.GetInstanceID().ToString();
|
||||
instSet.Add(id); // hashset does not need to check exist before add
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
public static void Add(string guid)
|
||||
{
|
||||
if (guidSet.Contains(guid)) return;
|
||||
var assetPath = AssetDatabase.GUIDToAssetPath(guid);
|
||||
if (string.IsNullOrEmpty(assetPath))
|
||||
{
|
||||
Debug.LogWarning("Invalid GUID: " + guid);
|
||||
return;
|
||||
}
|
||||
|
||||
guidSet.Add(guid);
|
||||
dirty = true;
|
||||
//Debug.Log(instSet.Count + " : " + guidSet.Count);
|
||||
}
|
||||
|
||||
public static void Remove(UnityObject sceneObject)
|
||||
{
|
||||
if (sceneObject == null) return;
|
||||
var id = sceneObject.GetInstanceID().ToString();
|
||||
instSet.Remove(id);
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
public static void Remove(string guidOrInstID)
|
||||
{
|
||||
guidSet.Remove(guidOrInstID);
|
||||
instSet.Remove(guidOrInstID);
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
public static void Clear()
|
||||
{
|
||||
guidSet.Clear();
|
||||
instSet.Clear();
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
public static void Add(FR2_Ref rf)
|
||||
{
|
||||
|
||||
if (rf.isSceneRef)
|
||||
{
|
||||
//Debug.Log("add " + rf.component);
|
||||
Add(rf.component);
|
||||
}
|
||||
else
|
||||
{
|
||||
Add(rf.asset.guid);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Remove(FR2_Ref rf)
|
||||
{
|
||||
|
||||
if (rf.isSceneRef)
|
||||
{
|
||||
//Debug.Log("remove: " + rf.component);
|
||||
Remove(rf.component);
|
||||
}
|
||||
else
|
||||
{
|
||||
Remove(rf.asset.guid);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Commit()
|
||||
{
|
||||
var list = new List<Object>();
|
||||
|
||||
foreach (string guid in guidSet)
|
||||
{
|
||||
string path = AssetDatabase.GUIDToAssetPath(guid);
|
||||
Object obj = AssetDatabase.LoadAssetAtPath(path, typeof(Object));
|
||||
if (obj != null) list.Add(obj);
|
||||
}
|
||||
|
||||
foreach (string instID in instSet)
|
||||
{
|
||||
var id = int.Parse(instID);
|
||||
var obj = EditorUtility.InstanceIDToObject(id);
|
||||
if (obj != null) list.Add(obj);
|
||||
}
|
||||
|
||||
Selection.objects = list.ToArray();
|
||||
}
|
||||
|
||||
// ------------ instance
|
||||
|
||||
//private readonly FR2_TreeUI2.GroupDrawer groupDrawer;
|
||||
private static bool dirty;
|
||||
private readonly FR2_RefDrawer drawer;
|
||||
internal Dictionary<string, FR2_Ref> refs = new Dictionary<string, FR2_Ref>();
|
||||
|
||||
public FR2_Bookmark(IWindow window)
|
||||
{
|
||||
this.window = window;
|
||||
drawer = new FR2_RefDrawer(window);
|
||||
drawer.messageNoRefs = "Do bookmark something!";
|
||||
|
||||
drawer.groupDrawer.hideGroupIfPossible = true;
|
||||
drawer.forceHideDetails = true;
|
||||
drawer.level0Group = string.Empty;
|
||||
|
||||
dirty = true;
|
||||
drawer.SetDirty();
|
||||
}
|
||||
|
||||
public IWindow window { get; set; }
|
||||
|
||||
public int ElementCount()
|
||||
{
|
||||
return refs == null ? 0 : refs.Count;
|
||||
}
|
||||
|
||||
public bool DrawLayout()
|
||||
{
|
||||
if (dirty) RefreshView();
|
||||
return drawer.DrawLayout();
|
||||
}
|
||||
|
||||
public bool Draw(Rect rect)
|
||||
{
|
||||
if (dirty) RefreshView();
|
||||
if (refs == null)
|
||||
{
|
||||
Debug.Log("Refs is null!");
|
||||
return false;
|
||||
}
|
||||
|
||||
var bottomRect = new Rect(rect.x + 1f, rect.yMax - 16f, rect.width - 2f, 16f);
|
||||
DrawButtons(bottomRect);
|
||||
|
||||
rect.yMax -= 16f;
|
||||
return drawer.Draw(rect);
|
||||
}
|
||||
|
||||
public void SetDirty()
|
||||
{
|
||||
drawer.SetDirty();
|
||||
}
|
||||
|
||||
void DrawButtons(Rect rect)
|
||||
{
|
||||
if (Count == 0) return;
|
||||
|
||||
GUILayout.BeginArea(rect);
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
{
|
||||
if (GUILayout.Button("Select"))
|
||||
{
|
||||
Commit();
|
||||
window.WillRepaint = true;
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Clear"))
|
||||
{
|
||||
Clear();
|
||||
window.WillRepaint = true;
|
||||
}
|
||||
|
||||
if (GUILayout.Button("CSV"))
|
||||
{
|
||||
FR2_Export.ExportCSV(refs.Values.ToArray());
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Delete"))
|
||||
{
|
||||
FR2_Unity.BackupAndDeleteAssets(refs.Values.ToArray());
|
||||
Clear();
|
||||
GUIUtility.ExitGUI();
|
||||
}
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
GUILayout.EndArea();
|
||||
}
|
||||
|
||||
public void RefreshView()
|
||||
{
|
||||
if (refs == null) refs = new Dictionary<string, FR2_Ref>();
|
||||
refs.Clear();
|
||||
|
||||
foreach (var guid in guidSet)
|
||||
{
|
||||
var asset = FR2_Cache.Api.Get(guid, false);
|
||||
refs.Add(guid, new FR2_Ref(0, 0, asset, null));
|
||||
}
|
||||
|
||||
foreach (var instId in instSet)
|
||||
{
|
||||
refs.Add(instId, new FR2_SceneRef(0, EditorUtility.InstanceIDToObject(int.Parse(instId))));
|
||||
}
|
||||
|
||||
|
||||
drawer.SetRefs(refs);
|
||||
|
||||
//Debug.Log("RefreshView: " + refs.Count);
|
||||
dirty = false;
|
||||
}
|
||||
|
||||
internal void RefreshSort()
|
||||
{
|
||||
drawer.RefreshSort();
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/FindReference2/Editor/Script/FR2_Bookmark.cs.meta
Normal file
11
Assets/FindReference2/Editor/Script/FR2_Bookmark.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 83d267126bcce4c9495361e0502fd04c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
144
Assets/FindReference2/Editor/Script/FR2_CSV.cs
Normal file
144
Assets/FindReference2/Editor/Script/FR2_CSV.cs
Normal file
@@ -0,0 +1,144 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using vietlabs.fr2;
|
||||
|
||||
public class FR2_CSV
|
||||
{
|
||||
private const string SEPARATOR = ",";
|
||||
public static string GetCSVRow(FR2_Ref r, params string[] suffixes)
|
||||
{
|
||||
var asset = r.asset;
|
||||
var sr = r.isSceneRef ? (FR2_SceneRef)r : null;
|
||||
var go = (GameObject)null;
|
||||
|
||||
if (sr != null)
|
||||
{
|
||||
if (sr.component is Component)
|
||||
{
|
||||
go = ((Component)sr.component).gameObject;
|
||||
}
|
||||
|
||||
if (sr.component is GameObject)
|
||||
{
|
||||
go = (GameObject)sr.component;
|
||||
}
|
||||
}
|
||||
|
||||
var sb = new StringBuilder();
|
||||
|
||||
sb.Append(r.depth);
|
||||
sb.Append(SEPARATOR);
|
||||
|
||||
sb.Append(r.isSceneRef ? sr.component.name : asset.assetName);
|
||||
sb.Append(SEPARATOR);
|
||||
|
||||
sb.Append(r.isSceneRef ? FR2_SceneRef.FindUsageScene(new[] { go }, false).Count : asset.UsageCount());
|
||||
sb.Append(SEPARATOR);
|
||||
|
||||
sb.Append(r.isSceneRef ? string.Empty : asset.extension);
|
||||
sb.Append(SEPARATOR);
|
||||
|
||||
sb.Append(r.isSceneRef ? "0" : asset.fileSize.ToString());
|
||||
sb.Append(SEPARATOR);
|
||||
|
||||
var type = r.isSceneRef ? "SceneObject" : "(missing)";
|
||||
if (!r.isSceneRef)
|
||||
{
|
||||
var obj = AssetDatabase.GetMainAssetTypeAtPath(asset.assetPath);
|
||||
if (obj != null) type = obj.ToString();
|
||||
|
||||
if (type.StartsWith("UnityEngine.") || type.StartsWith("UnityEditor."))
|
||||
{
|
||||
var idx = type.LastIndexOf(".", StringComparison.Ordinal) + 1;
|
||||
type = type.Substring(idx, type.Length - idx);
|
||||
}
|
||||
}
|
||||
|
||||
sb.Append(type);
|
||||
sb.Append(SEPARATOR);
|
||||
|
||||
sb.Append(r.isSceneRef ? string.Empty : asset.guid);
|
||||
sb.Append(SEPARATOR);
|
||||
|
||||
sb.Append(r.isSceneRef ? string.Empty : asset.AtlasName);
|
||||
sb.Append(SEPARATOR);
|
||||
|
||||
sb.Append(r.isSceneRef ? string.Empty : asset.AssetBundleName);
|
||||
sb.Append(SEPARATOR);
|
||||
|
||||
sb.Append(r.group);
|
||||
sb.Append(SEPARATOR);
|
||||
|
||||
sb.Append(r.isSceneRef ? sr.sceneFullPath : asset.assetPath);
|
||||
|
||||
foreach (var t in suffixes)
|
||||
{
|
||||
sb.Append(SEPARATOR);
|
||||
sb.Append(t);
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static string GetCSVTitle()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
|
||||
sb.Append("depth");
|
||||
sb.Append(SEPARATOR);
|
||||
|
||||
sb.Append("name");
|
||||
sb.Append(SEPARATOR);
|
||||
|
||||
sb.Append("usage count");
|
||||
sb.Append(SEPARATOR);
|
||||
|
||||
sb.Append("extension");
|
||||
sb.Append(SEPARATOR);
|
||||
|
||||
sb.Append("size");
|
||||
sb.Append(SEPARATOR);
|
||||
|
||||
sb.Append("type");
|
||||
sb.Append(SEPARATOR);
|
||||
|
||||
sb.Append("guid");
|
||||
sb.Append(SEPARATOR);
|
||||
|
||||
sb.Append("atlas");
|
||||
sb.Append(SEPARATOR);
|
||||
|
||||
sb.Append("assetbundle");
|
||||
sb.Append(SEPARATOR);
|
||||
|
||||
sb.Append("group");
|
||||
sb.Append(SEPARATOR);
|
||||
|
||||
sb.Append("full path");
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static string GetCSVRows(FR2_Ref[] source)
|
||||
{
|
||||
if (source == null)
|
||||
{
|
||||
//Debug.LogWarning("source should not be null!");
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine(GetCSVTitle());
|
||||
foreach (var s in source)
|
||||
{
|
||||
if (s == null) continue;
|
||||
sb.AppendLine(GetCSVRow(s));
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
11
Assets/FindReference2/Editor/Script/FR2_CSV.cs.meta
Normal file
11
Assets/FindReference2/Editor/Script/FR2_CSV.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ff73dd2521fff4f7d83012da98db1b89
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
1710
Assets/FindReference2/Editor/Script/FR2_Cache.cs
Normal file
1710
Assets/FindReference2/Editor/Script/FR2_Cache.cs
Normal file
File diff suppressed because it is too large
Load Diff
10
Assets/FindReference2/Editor/Script/FR2_Cache.cs.meta
Normal file
10
Assets/FindReference2/Editor/Script/FR2_Cache.cs.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 933e0cc22e789714c87e348a699023d7
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
44
Assets/FindReference2/Editor/Script/FR2_CacheEditor.cs
Normal file
44
Assets/FindReference2/Editor/Script/FR2_CacheEditor.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using vietlabs.fr2;
|
||||
|
||||
[CustomEditor(typeof(FR2_Cache))]
|
||||
internal class FR2_CacheEditor : Editor
|
||||
{
|
||||
private static string inspectGUID;
|
||||
private static int index;
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
var c = (FR2_Cache)target;
|
||||
|
||||
GUILayout.Label("Total : " + c.AssetList.Count);
|
||||
FR2_Cache.DrawPriorityGUI();
|
||||
|
||||
Object s = Selection.activeObject;
|
||||
if (s == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(s));
|
||||
|
||||
if (inspectGUID != guid)
|
||||
{
|
||||
inspectGUID = guid;
|
||||
index = c.AssetList.FindIndex(item => item.guid == guid);
|
||||
}
|
||||
|
||||
if (index != -1)
|
||||
{
|
||||
if (index >= c.AssetList.Count)
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
|
||||
serializedObject.Update();
|
||||
SerializedProperty prop = serializedObject.FindProperty("AssetList").GetArrayElementAtIndex(index);
|
||||
EditorGUILayout.PropertyField(prop, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
10
Assets/FindReference2/Editor/Script/FR2_CacheEditor.cs.meta
Normal file
10
Assets/FindReference2/Editor/Script/FR2_CacheEditor.cs.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f9b9c04ea6b703343b8aff08a26cf9aa
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
831
Assets/FindReference2/Editor/Script/FR2_Duplicate.cs
Normal file
831
Assets/FindReference2/Editor/Script/FR2_Duplicate.cs
Normal file
@@ -0,0 +1,831 @@
|
||||
//#define FR2_DEBUG
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using CBParams = System.Collections.Generic.List<System.Collections.Generic.List<string>>;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace vietlabs.fr2
|
||||
{
|
||||
internal class FR2_DuplicateTree2 : IRefDraw
|
||||
{
|
||||
private const float TimeDelayDelete = .5f;
|
||||
|
||||
private static readonly FR2_FileCompare fc = new FR2_FileCompare();
|
||||
private readonly FR2_TreeUI2.GroupDrawer groupDrawer;
|
||||
private CBParams cacheAssetList;
|
||||
public bool caseSensitive = false;
|
||||
private Dictionary<string, List<FR2_Ref>> dicIndex; //index, list
|
||||
|
||||
private bool dirty;
|
||||
private int excludeCount;
|
||||
private string guidPressDelete;
|
||||
internal List<FR2_Ref> list;
|
||||
internal Dictionary<string, FR2_Ref> refs;
|
||||
public int scanExcludeByIgnoreCount;
|
||||
public int scanExcludeByTypeCount;
|
||||
private string searchTerm = "";
|
||||
private float TimePressDelete;
|
||||
|
||||
public FR2_DuplicateTree2(IWindow window)
|
||||
{
|
||||
this.window = window;
|
||||
groupDrawer = new FR2_TreeUI2.GroupDrawer(DrawGroup, DrawAsset);
|
||||
}
|
||||
|
||||
public IWindow window { get; set; }
|
||||
|
||||
public bool Draw(Rect rect)
|
||||
{
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool DrawLayout()
|
||||
{
|
||||
if (dirty)
|
||||
{
|
||||
RefreshView(cacheAssetList);
|
||||
}
|
||||
|
||||
if (fc.nChunks2 > 0 && fc.nScaned < fc.nChunks2)
|
||||
{
|
||||
Rect rect = GUILayoutUtility.GetRect(1, Screen.width, 18f, 18f);
|
||||
float p = fc.nScaned / (float)fc.nChunks2;
|
||||
|
||||
EditorGUI.ProgressBar(rect, p, string.Format("Scanning {0} / {1}", fc.nScaned, fc.nChunks2));
|
||||
GUILayout.FlexibleSpace();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (groupDrawer.hasValidTree)
|
||||
{
|
||||
groupDrawer.tree.itemPaddingRight = 60f;
|
||||
}
|
||||
groupDrawer.DrawLayout();
|
||||
DrawHeader();
|
||||
return false;
|
||||
}
|
||||
|
||||
public int ElementCount()
|
||||
{
|
||||
return list == null ? 0 : list.Count;
|
||||
}
|
||||
|
||||
private void DrawAsset(Rect r, string guid)
|
||||
{
|
||||
FR2_Ref rf;
|
||||
if (!refs.TryGetValue(guid, out rf))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
rf.asset.Draw(r, false,
|
||||
FR2_Setting.GroupMode != FR2_RefDrawer.Mode.Folder,
|
||||
FR2_Setting.ShowFileSize,
|
||||
FR2_Setting.s.displayAssetBundleName,
|
||||
FR2_Setting.s.displayAtlasName,
|
||||
FR2_Setting.s.showUsedByClassed,
|
||||
window);
|
||||
|
||||
Texture tex = AssetDatabase.GetCachedIcon(rf.asset.assetPath);
|
||||
if (tex == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Rect drawR = r;
|
||||
drawR.x = drawR.x + drawR.width; // (groupDrawer.TreeNoScroll() ? 60f : 70f) ;
|
||||
drawR.width = 40f;
|
||||
drawR.y += 1;
|
||||
drawR.height -= 2;
|
||||
|
||||
if (GUI.Button(drawR, "Use", EditorStyles.miniButton))
|
||||
{
|
||||
if (FR2_Export.IsMergeProcessing)
|
||||
{
|
||||
Debug.LogWarning("Previous merge is processing");
|
||||
}
|
||||
else
|
||||
{
|
||||
//AssetDatabase.SaveAssets();
|
||||
//EditorGUIUtility.systemCopyBuffer = rf.asset.guid;
|
||||
//EditorGUIUtility.systemCopyBuffer = rf.asset.guid;
|
||||
// Debug.Log("guid: " + rf.asset.guid + " systemCopyBuffer " + EditorGUIUtility.systemCopyBuffer);
|
||||
int index = rf.index;
|
||||
Selection.objects = list.Where(x => x.index == index)
|
||||
.Select(x => FR2_Unity.LoadAssetAtPath<Object>(x.asset.assetPath)).ToArray();
|
||||
FR2_Export.MergeDuplicate(rf.asset.guid);
|
||||
}
|
||||
}
|
||||
|
||||
if (rf.asset.UsageCount() > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
drawR.x -= 25;
|
||||
drawR.width = 20;
|
||||
if (wasPreDelete(guid))
|
||||
{
|
||||
Color col = GUI.color;
|
||||
GUI.color = Color.red;
|
||||
if (GUI.Button(drawR, "X", EditorStyles.miniButton))
|
||||
{
|
||||
guidPressDelete = null;
|
||||
AssetDatabase.DeleteAsset(rf.asset.assetPath);
|
||||
}
|
||||
|
||||
GUI.color = col;
|
||||
window.WillRepaint = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GUI.Button(drawR, "X", EditorStyles.miniButton))
|
||||
{
|
||||
guidPressDelete = guid;
|
||||
TimePressDelete = Time.realtimeSinceStartup;
|
||||
window.WillRepaint = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool wasPreDelete(string guid)
|
||||
{
|
||||
if (guidPressDelete == null || guid != guidPressDelete)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Time.realtimeSinceStartup - TimePressDelete < TimeDelayDelete)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
guidPressDelete = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
private void DrawGroup(Rect r, string label, int childCount)
|
||||
{
|
||||
// GUI.Label(r, label + " (" + childCount + ")", EditorStyles.boldLabel);
|
||||
FR2_Asset asset = dicIndex[label][0].asset;
|
||||
|
||||
Texture tex = AssetDatabase.GetCachedIcon(asset.assetPath);
|
||||
Rect rect = r;
|
||||
|
||||
if (tex != null)
|
||||
{
|
||||
rect.width = 16f;
|
||||
GUI.DrawTexture(rect, tex);
|
||||
}
|
||||
|
||||
rect = r;
|
||||
rect.xMin += 16f;
|
||||
GUI.Label(rect, asset.assetName, EditorStyles.boldLabel);
|
||||
|
||||
rect = r;
|
||||
rect.xMin += rect.width - 50f;
|
||||
GUI.Label(rect, FR2_Helper.GetfileSizeString(asset.fileSize), EditorStyles.miniLabel);
|
||||
|
||||
rect = r;
|
||||
rect.xMin += rect.width - 70f;
|
||||
GUI.Label(rect, childCount.ToString(), EditorStyles.miniLabel);
|
||||
|
||||
rect = r;
|
||||
rect.xMin += rect.width - 70f;
|
||||
}
|
||||
|
||||
|
||||
// private List<FR2_DuplicateFolder> duplicated;
|
||||
|
||||
public void Reset(CBParams assetList)
|
||||
{
|
||||
fc.Reset(assetList, OnUpdateView, RefreshView);
|
||||
}
|
||||
|
||||
private void OnUpdateView(CBParams assetList) { }
|
||||
|
||||
public bool isExclueAnyItem()
|
||||
{
|
||||
return excludeCount > 0 || scanExcludeByTypeCount > 0;
|
||||
}
|
||||
|
||||
public bool isExclueAnyItemByIgnoreFolder()
|
||||
{
|
||||
return scanExcludeByIgnoreCount > 0;
|
||||
}
|
||||
|
||||
// void OnActive
|
||||
private void RefreshView(CBParams assetList)
|
||||
{
|
||||
cacheAssetList = assetList;
|
||||
dirty = false;
|
||||
list = new List<FR2_Ref>();
|
||||
refs = new Dictionary<string, FR2_Ref>();
|
||||
dicIndex = new Dictionary<string, List<FR2_Ref>>();
|
||||
if (assetList == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int minScore = searchTerm.Length;
|
||||
string term1 = searchTerm;
|
||||
if (!caseSensitive)
|
||||
{
|
||||
term1 = term1.ToLower();
|
||||
}
|
||||
|
||||
string term2 = term1.Replace(" ", string.Empty);
|
||||
excludeCount = 0;
|
||||
|
||||
for (var i = 0; i < assetList.Count; i++)
|
||||
{
|
||||
var lst = new List<FR2_Ref>();
|
||||
for (var j = 0; j < assetList[i].Count; j++)
|
||||
{
|
||||
var path = assetList[i][j];
|
||||
if (!path.StartsWith("Assets/"))
|
||||
{
|
||||
Debug.LogWarning("Ignore asset: " + path);
|
||||
continue;
|
||||
}
|
||||
|
||||
string guid = AssetDatabase.AssetPathToGUID(path);
|
||||
if (string.IsNullOrEmpty(guid))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (refs.ContainsKey(guid))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
FR2_Asset asset = FR2_Cache.Api.Get(guid);
|
||||
if (asset == null) continue;
|
||||
if (!asset.assetPath.StartsWith("Assets/")) continue; // ignore builtin, packages, ...
|
||||
|
||||
var fr2 = new FR2_Ref(i, 0, asset, null);
|
||||
|
||||
if (FR2_Setting.IsTypeExcluded(fr2.type))
|
||||
{
|
||||
excludeCount++;
|
||||
continue; //skip this one
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(searchTerm))
|
||||
{
|
||||
fr2.matchingScore = 0;
|
||||
list.Add(fr2);
|
||||
lst.Add(fr2);
|
||||
refs.Add(guid, fr2);
|
||||
continue;
|
||||
}
|
||||
|
||||
//calculate matching score
|
||||
string name1 = fr2.asset.assetName;
|
||||
if (!caseSensitive)
|
||||
{
|
||||
name1 = name1.ToLower();
|
||||
}
|
||||
|
||||
string name2 = name1.Replace(" ", string.Empty);
|
||||
|
||||
int score1 = FR2_Unity.StringMatch(term1, name1);
|
||||
int score2 = FR2_Unity.StringMatch(term2, name2);
|
||||
|
||||
fr2.matchingScore = Mathf.Max(score1, score2);
|
||||
if (fr2.matchingScore > minScore)
|
||||
{
|
||||
list.Add(fr2);
|
||||
lst.Add(fr2);
|
||||
refs.Add(guid, fr2);
|
||||
}
|
||||
}
|
||||
|
||||
dicIndex.Add(i.ToString(), lst);
|
||||
}
|
||||
|
||||
ResetGroup();
|
||||
}
|
||||
|
||||
private void ResetGroup()
|
||||
{
|
||||
groupDrawer.Reset(list,
|
||||
rf => rf.asset.guid
|
||||
, GetGroup, SortGroup);
|
||||
if (window != null)
|
||||
{
|
||||
window.Repaint();
|
||||
}
|
||||
}
|
||||
|
||||
private string GetGroup(FR2_Ref rf)
|
||||
{
|
||||
return rf.index.ToString();
|
||||
}
|
||||
|
||||
private void SortGroup(List<string> groups)
|
||||
{
|
||||
// groups.Sort( (item1, item2) =>
|
||||
// {
|
||||
// if (item1 == "Others" || item2 == "Selection") return 1;
|
||||
// if (item2 == "Others" || item1 == "Selection") return -1;
|
||||
// return item1.CompareTo(item2);
|
||||
// });
|
||||
}
|
||||
|
||||
public void SetDirty()
|
||||
{
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
public void RefreshSort() { }
|
||||
|
||||
private void DrawHeader()
|
||||
{
|
||||
var text = groupDrawer.hasValidTree ? "Rescan" : "Scan";
|
||||
|
||||
if (GUILayout.Button(text))
|
||||
{
|
||||
// if (FR2_Cache)
|
||||
{
|
||||
OnCacheReady();
|
||||
return;
|
||||
}
|
||||
|
||||
// FR2_Cache.onReady -= OnCacheReady;
|
||||
// FR2_Cache.onReady += OnCacheReady;
|
||||
// FR2_Cache.Api.Check4Changes(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnCacheReady()
|
||||
{
|
||||
scanExcludeByTypeCount = 0;
|
||||
Reset(FR2_Cache.Api.ScanSimilar(IgnoreTypeWhenScan, IgnoreFolderWhenScan));
|
||||
FR2_Cache.onReady -= OnCacheReady;
|
||||
}
|
||||
|
||||
private void IgnoreTypeWhenScan()
|
||||
{
|
||||
scanExcludeByTypeCount++;
|
||||
}
|
||||
|
||||
private void IgnoreFolderWhenScan()
|
||||
{
|
||||
scanExcludeByIgnoreCount++;
|
||||
}
|
||||
}
|
||||
|
||||
internal class FR2_FileCompare
|
||||
{
|
||||
public static HashSet<FR2_Chunk> HashChunksNotComplete;
|
||||
internal static int streamClosedCount;
|
||||
private CBParams cacheList;
|
||||
public List<FR2_Head> deads = new List<FR2_Head>();
|
||||
public List<FR2_Head> heads = new List<FR2_Head>();
|
||||
|
||||
public int nChunks;
|
||||
public int nChunks2;
|
||||
public int nScaned;
|
||||
public Action<CBParams> OnCompareComplete;
|
||||
public Action<CBParams> OnCompareUpdate;
|
||||
// private int streamCount;
|
||||
|
||||
public void Reset(CBParams list, Action<CBParams> onUpdate, Action<CBParams> onComplete)
|
||||
{
|
||||
nChunks = 0;
|
||||
nScaned = 0;
|
||||
nChunks2 = 0;
|
||||
// streamCount = streamClosedCount = 0;
|
||||
HashChunksNotComplete = new HashSet<FR2_Chunk>();
|
||||
|
||||
if (heads.Count > 0)
|
||||
{
|
||||
for (var i = 0; i < heads.Count; i++)
|
||||
{
|
||||
heads[i].CloseChunk();
|
||||
}
|
||||
}
|
||||
|
||||
deads.Clear();
|
||||
heads.Clear();
|
||||
|
||||
OnCompareUpdate = onUpdate;
|
||||
OnCompareComplete = onComplete;
|
||||
if (list.Count <= 0)
|
||||
{
|
||||
OnCompareComplete(new CBParams());
|
||||
return;
|
||||
}
|
||||
|
||||
cacheList = list;
|
||||
for (var i = 0; i < list.Count; i++)
|
||||
{
|
||||
var file = new FileInfo(list[i][0]);
|
||||
int nChunk = Mathf.CeilToInt(file.Length / (float)FR2_Head.chunkSize);
|
||||
nChunks2 += nChunk;
|
||||
}
|
||||
|
||||
// for(int i =0;i< list.Count;i++)
|
||||
// {
|
||||
// AddHead(list[i]);
|
||||
// }
|
||||
AddHead(cacheList[cacheList.Count - 1]);
|
||||
cacheList.RemoveAt(cacheList.Count - 1);
|
||||
|
||||
EditorApplication.update -= ReadChunkAsync;
|
||||
EditorApplication.update += ReadChunkAsync;
|
||||
}
|
||||
|
||||
public FR2_FileCompare AddHead(List<string> files)
|
||||
{
|
||||
if (files.Count < 2)
|
||||
{
|
||||
Debug.LogWarning("Something wrong ! head should not contains < 2 elements");
|
||||
}
|
||||
|
||||
var chunkList = new List<FR2_Chunk>();
|
||||
for (var i = 0; i < files.Count; i++)
|
||||
{
|
||||
// streamCount++;
|
||||
|
||||
// try
|
||||
// {
|
||||
// Debug.Log("new stream ");
|
||||
// stream = new FileStream(files[i], FileMode.Open, FileAccess.Read);
|
||||
// }
|
||||
// catch (Exception e)
|
||||
// {
|
||||
// Debug.LogWarning(e + "\nCan not open file: " + files[i]);
|
||||
// if (stream != null) stream.Close();
|
||||
// continue;
|
||||
// }
|
||||
|
||||
chunkList.Add(new FR2_Chunk
|
||||
{
|
||||
file = files[i],
|
||||
buffer = new byte[FR2_Head.chunkSize]
|
||||
});
|
||||
}
|
||||
|
||||
var file = new FileInfo(files[0]);
|
||||
int nChunk = Mathf.CeilToInt(file.Length / (float)FR2_Head.chunkSize);
|
||||
|
||||
heads.Add(new FR2_Head
|
||||
{
|
||||
fileSize = file.Length,
|
||||
currentChunk = 0,
|
||||
nChunk = nChunk,
|
||||
chunkList = chunkList
|
||||
});
|
||||
|
||||
nChunks += nChunk;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
// private bool checkCompleteAllCurFile()
|
||||
// {
|
||||
// return streamClosedCount + HashChunksNotComplete.Count >= streamCount; //-1 for safe
|
||||
// }
|
||||
|
||||
private void ReadChunkAsync()
|
||||
{
|
||||
bool alive = ReadChunk();
|
||||
if (alive)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (cacheList.Count > 0)
|
||||
{
|
||||
AddHead(cacheList[cacheList.Count - 1]);
|
||||
cacheList.RemoveAt(cacheList.Count - 1);
|
||||
}
|
||||
|
||||
var update = false;
|
||||
for (int i = heads.Count - 1; i >= 0; i--)
|
||||
{
|
||||
FR2_Head h = heads[i];
|
||||
if (!h.isDead) continue;
|
||||
|
||||
h.CloseChunk();
|
||||
heads.RemoveAt(i);
|
||||
if (h.chunkList.Count > 1)
|
||||
{
|
||||
update = true;
|
||||
deads.Add(h);
|
||||
}
|
||||
}
|
||||
|
||||
if (update)
|
||||
{
|
||||
Trigger(OnCompareUpdate);
|
||||
}
|
||||
|
||||
if (!alive && cacheList.Count <= 0) //&& cacheList.Count <= 0 complete all chunk and cache list empty
|
||||
{
|
||||
foreach (FR2_Chunk item in HashChunksNotComplete)
|
||||
{
|
||||
if (item.stream != null && item.stream.CanRead)
|
||||
{
|
||||
Debug.Log("Close Stream!");
|
||||
|
||||
item.stream.Close();
|
||||
item.stream = null;
|
||||
}
|
||||
}
|
||||
|
||||
HashChunksNotComplete.Clear();
|
||||
// Debug.Log("complete ");
|
||||
nScaned = nChunks;
|
||||
EditorApplication.update -= ReadChunkAsync;
|
||||
Trigger(OnCompareComplete);
|
||||
}
|
||||
}
|
||||
|
||||
private void Trigger(Action<CBParams> cb)
|
||||
{
|
||||
if (cb == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CBParams list = deads.Select(item => item.GetFiles()).ToList();
|
||||
|
||||
//#if FR2_DEBUG
|
||||
// Debug.Log("Callback ! " + deads.Count + ":" + heads.Count);
|
||||
//#endif
|
||||
cb(list);
|
||||
}
|
||||
|
||||
private bool ReadChunk()
|
||||
{
|
||||
var alive = false;
|
||||
|
||||
for (var i = 0; i < heads.Count; i++)
|
||||
{
|
||||
FR2_Head h = heads[i];
|
||||
if (h.isDead)
|
||||
{
|
||||
//Debug.LogWarning("Should never be here : " + h.chunkList[0].file);
|
||||
continue;
|
||||
}
|
||||
|
||||
nScaned++;
|
||||
alive = true;
|
||||
h.ReadChunk();
|
||||
h.CompareChunk(heads);
|
||||
break;
|
||||
}
|
||||
|
||||
//if (!alive) return false;
|
||||
|
||||
//alive = false;
|
||||
//for (var i = 0; i < heads.Count; i++)
|
||||
//{
|
||||
// var h = heads[i];
|
||||
// if (h.isDead) continue;
|
||||
|
||||
// h.CompareChunk(heads);
|
||||
// alive |= !h.isDead;
|
||||
//}
|
||||
|
||||
return alive;
|
||||
}
|
||||
}
|
||||
|
||||
internal class FR2_Head
|
||||
{
|
||||
public const int chunkSize = 10240;
|
||||
|
||||
public List<FR2_Chunk> chunkList;
|
||||
public int currentChunk;
|
||||
|
||||
public long fileSize;
|
||||
|
||||
public int nChunk;
|
||||
public int size; //last stream read size
|
||||
|
||||
public bool isDead
|
||||
{
|
||||
get { return currentChunk == nChunk || chunkList.Count == 1; }
|
||||
}
|
||||
|
||||
public List<string> GetFiles()
|
||||
{
|
||||
return chunkList.Select(item => item.file).ToList();
|
||||
}
|
||||
|
||||
public void AddToDict(byte b, FR2_Chunk chunk, Dictionary<byte, List<FR2_Chunk>> dict)
|
||||
{
|
||||
List<FR2_Chunk> list;
|
||||
if (!dict.TryGetValue(b, out list))
|
||||
{
|
||||
list = new List<FR2_Chunk>();
|
||||
dict.Add(b, list);
|
||||
}
|
||||
|
||||
list.Add(chunk);
|
||||
}
|
||||
|
||||
public void CloseChunk()
|
||||
{
|
||||
for (var i = 0; i < chunkList.Count; i++)
|
||||
{
|
||||
FR2_FileCompare.streamClosedCount++;
|
||||
|
||||
if (chunkList[i].stream != null)
|
||||
{
|
||||
#if FR2_DEBUG
|
||||
Debug.Log("stream close: " + chunkList[i].file);
|
||||
#endif
|
||||
|
||||
chunkList[i].stream.Close();
|
||||
chunkList[i].stream = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ReadChunk()
|
||||
{
|
||||
#if FR2_DEBUG
|
||||
if (currentChunk == 0) Debug.LogWarning("Read <" + chunkList[0].file + "> " + currentChunk + ":" + nChunk);
|
||||
#endif
|
||||
if (currentChunk == nChunk)
|
||||
{
|
||||
Debug.LogWarning("Something wrong, should dead <" + isDead + ">");
|
||||
return;
|
||||
}
|
||||
|
||||
int from = currentChunk * chunkSize;
|
||||
size = (int)Mathf.Min(fileSize - from, chunkSize);
|
||||
|
||||
for (var i = 0; i < chunkList.Count; i++)
|
||||
{
|
||||
FR2_Chunk chunk = chunkList[i];
|
||||
if (chunk.streamError) continue;
|
||||
chunk.size = size;
|
||||
|
||||
if (chunk.streamInited == false)
|
||||
{
|
||||
chunk.streamInited = true;
|
||||
|
||||
try
|
||||
{
|
||||
#if FR2_DEBUG
|
||||
Debug.Log("New chunk: " + chunk.file);
|
||||
#endif
|
||||
chunk.stream = new FileStream(chunk.file, FileMode.Open, FileAccess.Read);
|
||||
}
|
||||
#if FR2_DEBUG
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
Debug.LogWarning("Exception: " + e + "\n" + chunk.file + "\n" + chunk.stream);
|
||||
#else
|
||||
catch {
|
||||
#endif
|
||||
|
||||
chunk.streamError = true;
|
||||
if (chunk.stream != null) // just to make sure we close the stream
|
||||
{
|
||||
chunk.stream.Close();
|
||||
chunk.stream = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (chunk.stream == null)
|
||||
{
|
||||
chunk.streamError = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
chunk.stream.Read(chunk.buffer, 0, size);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogWarning(e + "\n" + chunk.file);
|
||||
|
||||
chunk.streamError = true;
|
||||
chunk.stream.Close();
|
||||
}
|
||||
}
|
||||
|
||||
// clean up dead chunks
|
||||
for (var i = chunkList.Count-1; i>=0; i--)
|
||||
{
|
||||
if (chunkList[i].streamError) chunkList.RemoveAt(i);
|
||||
}
|
||||
|
||||
if (chunkList.Count == 1)
|
||||
{
|
||||
Debug.LogWarning("No more chunk in list");
|
||||
}
|
||||
|
||||
currentChunk++;
|
||||
}
|
||||
|
||||
public void CompareChunk(List<FR2_Head> heads)
|
||||
{
|
||||
int idx = chunkList.Count;
|
||||
byte[] buffer = chunkList[idx - 1].buffer;
|
||||
|
||||
while (--idx >= 0)
|
||||
{
|
||||
FR2_Chunk chunk = chunkList[idx];
|
||||
int diff = FirstDifferentIndex(buffer, chunk.buffer, size);
|
||||
if (diff == -1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
#if FR2_DEBUG
|
||||
Debug.Log(string.Format(
|
||||
" --> Different found at : idx={0} diff={1} size={2} chunk={3}",
|
||||
idx, diff, size, currentChunk));
|
||||
#endif
|
||||
|
||||
byte v = buffer[diff];
|
||||
var d = new Dictionary<byte, List<FR2_Chunk>>(); //new heads
|
||||
chunkList.RemoveAt(idx);
|
||||
FR2_FileCompare.HashChunksNotComplete.Add(chunk);
|
||||
|
||||
AddToDict(chunk.buffer[diff], chunk, d);
|
||||
|
||||
for (int j = idx - 1; j >= 0; j--)
|
||||
{
|
||||
FR2_Chunk tChunk = chunkList[j];
|
||||
byte tValue = tChunk.buffer[diff];
|
||||
if (tValue == v)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
idx--;
|
||||
FR2_FileCompare.HashChunksNotComplete.Add(tChunk);
|
||||
chunkList.RemoveAt(j);
|
||||
AddToDict(tChunk.buffer[diff], tChunk, d);
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<byte, List<FR2_Chunk>> item in d)
|
||||
{
|
||||
List<FR2_Chunk> list = item.Value;
|
||||
if (list.Count == 1)
|
||||
{
|
||||
#if FR2_DEBUG
|
||||
Debug.Log(" --> Dead head found for : " + list[0].file);
|
||||
#endif
|
||||
if (list[0].stream != null) list[0].stream.Close();
|
||||
}
|
||||
else if (list.Count > 1) // 1 : dead head
|
||||
{
|
||||
#if FR2_DEBUG
|
||||
Debug.Log(" --> NEW HEAD : " + list[0].file);
|
||||
#endif
|
||||
heads.Add(new FR2_Head
|
||||
{
|
||||
nChunk = nChunk,
|
||||
fileSize = fileSize,
|
||||
currentChunk = currentChunk - 1,
|
||||
chunkList = list
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static int FirstDifferentIndex(byte[] arr1, byte[] arr2, int maxIndex)
|
||||
{
|
||||
for (var i = 0; i < maxIndex; i++)
|
||||
{
|
||||
if (arr1[i] != arr2[i])
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
internal class FR2_Chunk
|
||||
{
|
||||
public byte[] buffer;
|
||||
public string file;
|
||||
public long size;
|
||||
|
||||
public bool streamInited = false;
|
||||
public bool streamError = false;
|
||||
public FileStream stream;
|
||||
}
|
||||
}
|
||||
10
Assets/FindReference2/Editor/Script/FR2_Duplicate.cs.meta
Normal file
10
Assets/FindReference2/Editor/Script/FR2_Duplicate.cs.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d5c2f1d0a3c6acc4a9cf0d8f013f14d3
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
643
Assets/FindReference2/Editor/Script/FR2_Export.cs
Normal file
643
Assets/FindReference2/Editor/Script/FR2_Export.cs
Normal file
@@ -0,0 +1,643 @@
|
||||
//#define REPLACE_SAME_TYPE
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
using Debug = UnityEngine.Debug;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace vietlabs.fr2
|
||||
{
|
||||
public class FR2_Export
|
||||
{
|
||||
// private static int processIndex;
|
||||
private const int maxThread = 5;
|
||||
|
||||
//[MenuItem("Assets/FR2/Tools/Merge Duplicates")]
|
||||
|
||||
private static Dictionary<string, ProcessReplaceData> listReplace;
|
||||
private static HashSet<string> cacheSelection;
|
||||
|
||||
|
||||
private static List<Thread> lstThreads;
|
||||
public static bool IsMergeProcessing { get; private set; }
|
||||
|
||||
|
||||
public static void ExportCSV(FR2_Ref[] csvSource)
|
||||
{
|
||||
var result = FR2_CSV.GetCSVRows(csvSource);
|
||||
if (result.Length > 0)
|
||||
{
|
||||
EditorGUIUtility.systemCopyBuffer = result;
|
||||
Debug.Log("[FR2] CSV file content (" + csvSource.Length + " assets) copied to clipboard!");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("[FR2] Nothing to export!");
|
||||
}
|
||||
}
|
||||
|
||||
[MenuItem("Assets/FR2/Toggle Ignore", false, 19)]
|
||||
private static void Ignore()
|
||||
{
|
||||
if (!FR2_Cache.isReady)
|
||||
{
|
||||
Debug.LogWarning("FR2 cache not yet ready, please open Window > FR2_Window and hit scan project!");
|
||||
return;
|
||||
}
|
||||
|
||||
Object[] actives = Selection.objects;
|
||||
for (var i = 0; i < actives.Length; i++)
|
||||
{
|
||||
string path = AssetDatabase.GetAssetPath(actives[i]);
|
||||
if (path.Equals(FR2_Cache.DEFAULT_CACHE_PATH))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (FR2_Setting.IgnoreAsset.Contains(path))
|
||||
{
|
||||
FR2_Setting.RemoveIgnore(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
FR2_Setting.AddIgnore(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[MenuItem("Assets/FR2/Copy GUID", false, 20)]
|
||||
private static void CopyGUID()
|
||||
{
|
||||
EditorGUIUtility.systemCopyBuffer = AssetDatabase.AssetPathToGUID(
|
||||
AssetDatabase.GetAssetPath(Selection.activeObject)
|
||||
);
|
||||
}
|
||||
|
||||
[MenuItem("Assets/FR2/Export Selection", false, 21)]
|
||||
private static void ExportSelection()
|
||||
{
|
||||
if (!FR2_Cache.isReady)
|
||||
{
|
||||
Debug.LogWarning("FR2 cache not yet ready, please open Window > FR2_Window and hit scan project!");
|
||||
return;
|
||||
}
|
||||
|
||||
FR2_Unity.ExportSelection();
|
||||
}
|
||||
|
||||
[MenuItem("Assets/FR2/Select Dependencies (assets I use)", false, 22)]
|
||||
private static void SelectDependencies_wtme()
|
||||
{
|
||||
if (!FR2_Cache.isReady)
|
||||
{
|
||||
Debug.LogWarning("FR2 cache not yet ready, please open Window > FR2_Window and hit scan project!");
|
||||
return;
|
||||
}
|
||||
|
||||
SelectDependencies(false);
|
||||
}
|
||||
|
||||
[MenuItem("Assets/FR2/Refresh")]
|
||||
public static void ForceRefreshSelection()
|
||||
{
|
||||
var guids = Selection.assetGUIDs;
|
||||
if (!FR2_Cache.isReady) return; // cache not ready!
|
||||
|
||||
for (var i = 0; i < guids.Length; i++)
|
||||
{
|
||||
string guid = guids[i];
|
||||
if (guid == FR2_Cache.CachePath)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!FR2_Asset.IsValidGUID(guid))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (FR2_Cache.Api.AssetMap.ContainsKey(guid))
|
||||
{
|
||||
FR2_Cache.Api.RefreshAsset(guid, true);
|
||||
#if FR2_DEBUG
|
||||
UnityEngine.Debug.Log("Changed : " + guids[i]);
|
||||
#endif
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
FR2_Cache.Api.AddAsset(guid);
|
||||
}
|
||||
|
||||
FR2_Cache.Api.Check4Work();
|
||||
}
|
||||
|
||||
[MenuItem("Assets/FR2/Select Dependencies included me", false, 23)]
|
||||
private static void SelectDependencies_wme()
|
||||
{
|
||||
if (!FR2_Cache.isReady)
|
||||
{
|
||||
Debug.LogWarning("FR2 cache not yet ready, please open Window > FR2_Window and hit scan project!");
|
||||
return;
|
||||
}
|
||||
|
||||
SelectDependencies(true);
|
||||
}
|
||||
|
||||
//[MenuItem("Assets/FR2/Select")]
|
||||
[MenuItem("Assets/FR2/Select Used (assets used me)", false, 24)]
|
||||
private static void SelectUsed_wtme()
|
||||
{
|
||||
if (!FR2_Cache.isReady)
|
||||
{
|
||||
Debug.LogWarning("FR2 cache not yet ready, please open Window > FR2_Window and hit scan project!");
|
||||
return;
|
||||
}
|
||||
|
||||
SelectUsed(false);
|
||||
}
|
||||
|
||||
[MenuItem("Assets/FR2/Select Used included me", false, 25)]
|
||||
private static void SelectUsed_wme()
|
||||
{
|
||||
if (!FR2_Cache.isReady)
|
||||
{
|
||||
Debug.LogWarning("FR2 cache not yet ready, please open Window > FR2_Window and hit scan project!");
|
||||
return;
|
||||
}
|
||||
|
||||
SelectUsed(true);
|
||||
}
|
||||
|
||||
[MenuItem("Assets/FR2/Export Dependencies", false, 40)]
|
||||
private static void ExportDependencies()
|
||||
{
|
||||
if (!FR2_Cache.isReady)
|
||||
{
|
||||
Debug.LogWarning("FR2 cache not yet ready, please open Window > FR2_Window and hit scan project!");
|
||||
return;
|
||||
}
|
||||
|
||||
var deps = GetSelectionDependencies();
|
||||
if (deps == null) return;
|
||||
|
||||
Selection.objects = deps.ToArray();
|
||||
FR2_Unity.ExportSelection();
|
||||
}
|
||||
|
||||
[MenuItem("Assets/FR2/Export Assets (no scripts)", false, 41)]
|
||||
private static void ExportAsset()
|
||||
{
|
||||
if (!FR2_Cache.isReady)
|
||||
{
|
||||
Debug.LogWarning("FR2 cache not yet ready, please open Window > FR2_Window and hit scan project!");
|
||||
return;
|
||||
}
|
||||
|
||||
List<Object> list = GetSelectionDependencies();
|
||||
|
||||
for (int i = list.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (list[i] is MonoScript)
|
||||
{
|
||||
list.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
//Debug.Log(i + ":" + list[i] + ":" + list[i].GetType());
|
||||
Selection.objects = list.ToArray();
|
||||
FR2_Unity.ExportSelection();
|
||||
}
|
||||
|
||||
public static void MergeDuplicate(string guid_file)
|
||||
{
|
||||
// for (int i = 0; i < Selection.objects.Length; i++)
|
||||
// {
|
||||
// Object item = Selection.objects[i];
|
||||
// Debug.Log(item.name);
|
||||
// }
|
||||
//string guid_file = EditorGUIUtility.systemCopyBuffer;
|
||||
long toFileId = 0;
|
||||
var string_arr = guid_file.Split('/');
|
||||
if (string_arr.Length > 1)
|
||||
{
|
||||
toFileId = long.Parse(string_arr[1]);
|
||||
}
|
||||
string guid = string_arr[0];
|
||||
// var wat = new System.Diagnostics.Stopwatch();
|
||||
// wat.Start();
|
||||
//validate clipboard guid
|
||||
|
||||
string gPath = AssetDatabase.GUIDToAssetPath(guid);
|
||||
if (string.IsNullOrEmpty(gPath) || !gPath.StartsWith("Assets/"))
|
||||
{
|
||||
Debug.LogWarning("Invalid guid <" + guid + "> in clipboard, can not replace !");
|
||||
return;
|
||||
}
|
||||
|
||||
var temp = FR2_Unity.Selection_AssetGUIDs;//cheat refresh selection, DO NOT delete
|
||||
HashSet<string> guids_files = FR2_Unity._Selection_AssetGUIDs;
|
||||
|
||||
var realKey = "";
|
||||
foreach (var item in guids_files)
|
||||
{
|
||||
if (item.StartsWith(guid_file, System.StringComparison.Ordinal))
|
||||
{
|
||||
realKey = item;
|
||||
}
|
||||
}
|
||||
if (string.IsNullOrEmpty(realKey))
|
||||
{
|
||||
Debug.LogWarning("Clipboard guid <" + guid +
|
||||
"> not found in Selection, you may not intentionally replace selection assets by clipboard guid");
|
||||
// foreach (var item in guids_files) {
|
||||
// Debug.Log ("item: " + item);
|
||||
// }
|
||||
return;
|
||||
}
|
||||
guids_files.Remove(realKey);
|
||||
cacheSelection = new HashSet<string>();
|
||||
foreach (var item in cacheSelection)
|
||||
{
|
||||
cacheSelection.Add(item);
|
||||
}
|
||||
if (guids_files.Count == 0)
|
||||
{
|
||||
Debug.LogWarning("No new asset selected to replace, must select all duplications to replace");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//check asset type, only replace same type
|
||||
#if REPLACE_SAME_TYPE
|
||||
var type1 = AssetDatabase.GetMainAssetTypeAtPath(gPath);
|
||||
var importType1 = AssetImporter.GetAtPath(gPath);
|
||||
#endif
|
||||
|
||||
|
||||
List<FR2_Asset> assetList = new List<FR2_Asset>();
|
||||
var lstFind = new List<string>();
|
||||
foreach (var item in guids_files)
|
||||
{
|
||||
var arr = item.Split('/');
|
||||
|
||||
string g = arr[0];
|
||||
|
||||
#if REPLACE_SAME_TYPE
|
||||
var p2 = AssetDatabase.GUIDToAssetPath(g);
|
||||
var type2 = AssetDatabase.GetMainAssetTypeAtPath(p2);
|
||||
|
||||
if(type1 != type2)
|
||||
{
|
||||
Debug.LogWarning("Cannot replace asset: " + p2 + " becase difference type");
|
||||
continue;
|
||||
}
|
||||
if(type1 == typeof(UnityEngine.Texture2D))
|
||||
{
|
||||
var importType2 = AssetImporter.GetAtPath(p2) as TextureImporter;
|
||||
var textureImportType1 = importType1 as TextureImporter;
|
||||
if (importType2 == null || textureImportType1 == null)
|
||||
{
|
||||
Debug.LogWarning("Cannot replace asset: " + p2 + " becase difference type");
|
||||
continue;
|
||||
}
|
||||
if(textureImportType1.textureType != importType2.textureType)
|
||||
{
|
||||
Debug.LogWarning("Cannot replace asset: " + p2 + " becase difference type");
|
||||
continue;
|
||||
}
|
||||
if (textureImportType1.textureType == TextureImporterType.Sprite)
|
||||
{
|
||||
if (textureImportType1.spriteImportMode != importType2.spriteImportMode)
|
||||
{
|
||||
Debug.LogWarning("Cannot replace asset: " + p2 + " becase difference type");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
//Debug.Log("import type " + mainImportType);
|
||||
}
|
||||
//Debug.Log("type: " + mainType);
|
||||
#endif
|
||||
lstFind.Add(g);
|
||||
|
||||
// if (arr.Length > 1)
|
||||
// {
|
||||
// long file = long.Parse(arr[1]);
|
||||
//
|
||||
// }
|
||||
}
|
||||
if (lstFind.Count == 0)
|
||||
{
|
||||
Debug.LogWarning("No new asset selected to replace, must select all duplications to replace");
|
||||
return;
|
||||
}
|
||||
|
||||
assetList = FR2_Cache.Api.FindAssets(lstFind.ToArray(), false);
|
||||
|
||||
//replace one by one
|
||||
listReplace = new Dictionary<string, ProcessReplaceData>();
|
||||
lstThreads = new List<Thread>();
|
||||
for (int i = assetList.Count - 1; i >= 0; i--)
|
||||
{
|
||||
//Debug.Log("FR2 Replace GUID : " + assetList[i].guid + " ---> " + guid + " : " + assetList[i].UsedByMap.Count + " assets updated");
|
||||
string fromId = assetList[i].guid;
|
||||
|
||||
List<FR2_Asset> arr = assetList[i].UsedByMap.Values.ToList();
|
||||
for (var j = 0; j < arr.Count; j++)
|
||||
{
|
||||
FR2_Asset a = arr[j];
|
||||
if (!listReplace.ContainsKey(a.assetPath))
|
||||
{
|
||||
listReplace.Add(a.assetPath, new ProcessReplaceData());
|
||||
}
|
||||
|
||||
listReplace[a.assetPath].datas.Add(new ReplaceData
|
||||
{
|
||||
from = fromId,
|
||||
to = guid,
|
||||
asset = a,
|
||||
|
||||
toFileId = toFileId
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<string, ProcessReplaceData> item in listReplace)
|
||||
{
|
||||
item.Value.processIndex = item.Value.datas.Count - 1;
|
||||
}
|
||||
|
||||
IsMergeProcessing = true;
|
||||
EditorApplication.update -= ApplicationUpdate;
|
||||
EditorApplication.update += ApplicationUpdate;
|
||||
|
||||
// for (var i = assetList.Count - 1; i >= 0; i--)
|
||||
// {
|
||||
// // Debug.Log("FR2 Replace GUID : " + assetList[i].guid + " ---> " + guid + " : " + assetList[i].UsedByMap.Count + " assets updated");
|
||||
// var from = assetList[i].guid;
|
||||
|
||||
// var arr = assetList[i].UsedByMap.Values.ToList();
|
||||
// for (var j = 0; j < arr.Count; j ++)
|
||||
// {
|
||||
// var a = arr[j];
|
||||
// var result = a.ReplaceReference(from, guid);
|
||||
|
||||
// if (result && !dictAsset.ContainsKey(a.guid))
|
||||
// {
|
||||
// dictAsset.Add(a.guid, 1);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// Debug.Log("Time replace guid " + wat.ElapsedMilliseconds);
|
||||
// wat = new System.Diagnostics.Stopwatch();
|
||||
// wat.Start();
|
||||
// var listRefresh = dictAsset.Keys.ToList();
|
||||
// for (var i = 0; i < listRefresh.Count; i++)
|
||||
// {
|
||||
// FR2_Cache.Api.RefreshAsset(listRefresh[i], true);
|
||||
// }
|
||||
|
||||
// FR2_Cache.Api.RefreshSelection();
|
||||
// FR2_Cache.Api.Check4Usage();
|
||||
// AssetDatabase.Refresh();
|
||||
// Debug.Log("Time replace guid " + wat.ElapsedMilliseconds);
|
||||
}
|
||||
|
||||
private static void ApplicationUpdate()
|
||||
{
|
||||
bool notComplete = listReplace.Where(x => x.Value.processIndex >= 0).Count() > 0;
|
||||
if (lstThreads.Count <= 0 && notComplete)
|
||||
{
|
||||
foreach (KeyValuePair<string, ProcessReplaceData> item in listReplace)
|
||||
{
|
||||
if (item.Value.processIndex >= 0)
|
||||
{
|
||||
ReplaceData a = item.Value.datas[item.Value.processIndex--];
|
||||
a.isTerrian = a.asset.type == FR2_AssetType.TERRAIN;
|
||||
if (a.isTerrian)
|
||||
{
|
||||
a.terrainData =
|
||||
AssetDatabase.LoadAssetAtPath(a.asset.assetPath, typeof(Object)) as TerrainData;
|
||||
}
|
||||
|
||||
a.isSucess = a.asset.ReplaceReference(a.from, a.to, a.toFileId, a.terrainData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = lstThreads.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (!lstThreads[i].IsAlive)
|
||||
{
|
||||
lstThreads.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
//if (lstThreads.Count <= 0 && !notComplete) //complete
|
||||
{
|
||||
|
||||
foreach (KeyValuePair<string, ProcessReplaceData> item in listReplace)
|
||||
{
|
||||
List<ReplaceData> lst = item.Value.datas;
|
||||
for (var i = 0; i < lst.Count; i++)
|
||||
{
|
||||
ReplaceData data = lst[i];
|
||||
if (!data.isUpdated && data.isSucess)
|
||||
{
|
||||
data.isUpdated = true;
|
||||
if (data.isTerrian)
|
||||
{
|
||||
EditorUtility.SetDirty(data.terrainData);
|
||||
AssetDatabase.SaveAssets();
|
||||
data.terrainData = null;
|
||||
FR2_Unity.UnloadUnusedAssets();
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
AssetDatabase.ImportAsset(data.asset.assetPath, ImportAssetOptions.Default);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogWarning(data.asset.assetPath + "\n" + e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var guidsRefreshed = new HashSet<string>();
|
||||
EditorApplication.update -= ApplicationUpdate;
|
||||
foreach (KeyValuePair<string, ProcessReplaceData> item in listReplace)
|
||||
{
|
||||
List<ReplaceData> lst = item.Value.datas;
|
||||
for (var i = 0; i < lst.Count; i++)
|
||||
{
|
||||
ReplaceData data = lst[i];
|
||||
if (data.isSucess && !guidsRefreshed.Contains(data.asset.guid))
|
||||
{
|
||||
guidsRefreshed.Add(data.asset.guid);
|
||||
FR2_Cache.Api.RefreshAsset(data.asset.guid, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lstThreads = null;
|
||||
listReplace = null;
|
||||
FR2_Cache.Api.RefreshSelection();
|
||||
FR2_Cache.Api.Check4Work();
|
||||
|
||||
AssetDatabase.Refresh();
|
||||
IsMergeProcessing = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//[MenuItem("Assets/FR2/Tools/Fix Model Import Material")]
|
||||
//public static void FixModelImportMaterial(){
|
||||
// if (Selection.activeObject == null) return;
|
||||
// CreatePrefabReplaceModel((GameObject)Selection.activeObject);
|
||||
//}
|
||||
|
||||
//[MenuItem("GameObject/FR2/Paste Materials", false, 10)]
|
||||
//public static void PasteMaterials(){
|
||||
// if (Selection.activeObject == null) return;
|
||||
|
||||
// var r = Selection.activeGameObject.GetComponent<Renderer>();
|
||||
// Undo.RecordObject(r, "Replace Materials");
|
||||
// r.materials = model_materials;
|
||||
// EditorUtility.SetDirty(r);
|
||||
//}
|
||||
|
||||
//[MenuItem("GameObject/FR2/Copy Materials", false, 10)]
|
||||
//public static void CopyMaterials(){
|
||||
// if (Selection.activeObject == null) return;
|
||||
// var r = Selection.activeGameObject.GetComponent<Renderer>();
|
||||
// if (r == null) return;
|
||||
// model_materials = r.sharedMaterials;
|
||||
//}
|
||||
|
||||
//-------------------------- APIs ----------------------
|
||||
|
||||
private static void SelectDependencies(bool includeMe)
|
||||
{
|
||||
List<FR2_Asset> list = FR2_Cache.Api.FindAssets(FR2_Unity.Selection_AssetGUIDs, false);
|
||||
var dict = new Dictionary<string, Object>();
|
||||
|
||||
if (includeMe)
|
||||
{
|
||||
AddToDict(dict, list.ToArray());
|
||||
}
|
||||
|
||||
for (var i = 0; i < list.Count; i++)
|
||||
{
|
||||
AddToDict(dict, FR2_Asset.FindUsage(list[i]).ToArray());
|
||||
}
|
||||
|
||||
Selection.objects = dict.Values.ToArray();
|
||||
}
|
||||
|
||||
private static void SelectUsed(bool includeMe)
|
||||
{
|
||||
List<FR2_Asset> list = FR2_Cache.Api.FindAssets(FR2_Unity.Selection_AssetGUIDs, false);
|
||||
var dict = new Dictionary<string, Object>();
|
||||
|
||||
if (includeMe)
|
||||
{
|
||||
AddToDict(dict, list.ToArray());
|
||||
}
|
||||
|
||||
for (var i = 0; i < list.Count; i++)
|
||||
{
|
||||
AddToDict(dict, list[i].UsedByMap.Values.ToArray());
|
||||
}
|
||||
|
||||
Selection.objects = dict.Values.ToArray();
|
||||
}
|
||||
|
||||
|
||||
//-------------------------- UTILS ---------------------
|
||||
|
||||
internal static void AddToDict(Dictionary<string, Object> dict, params FR2_Asset[] list)
|
||||
{
|
||||
for (var j = 0; j < list.Length; j++)
|
||||
{
|
||||
string guid = list[j].guid;
|
||||
if (!dict.ContainsKey(guid))
|
||||
{
|
||||
string assetPath = AssetDatabase.GUIDToAssetPath(guid);
|
||||
dict.Add(guid, FR2_Unity.LoadAssetAtPath<Object>(assetPath));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Object> GetSelectionDependencies()
|
||||
{
|
||||
if (!FR2_Cache.isReady)
|
||||
{
|
||||
Debug.LogWarning("FR2 cache not yet ready, please open Window > FR2_Window and hit scan project!");
|
||||
return null;
|
||||
}
|
||||
|
||||
return FR2_Cache.FindUsage(FR2_Unity.Selection_AssetGUIDs).Select(
|
||||
guid =>
|
||||
{
|
||||
string assetPath = AssetDatabase.GUIDToAssetPath(guid);
|
||||
return FR2_Unity.LoadAssetAtPath<Object>(assetPath);
|
||||
}
|
||||
).ToList();
|
||||
}
|
||||
|
||||
private class ProcessReplaceData
|
||||
{
|
||||
public readonly List<ReplaceData> datas = new List<ReplaceData>();
|
||||
public int processIndex;
|
||||
}
|
||||
|
||||
private class ReplaceData
|
||||
{
|
||||
public FR2_Asset asset;
|
||||
public string from;
|
||||
public bool isSucess;
|
||||
public bool isTerrian;
|
||||
public bool isUpdated;
|
||||
public TerrainData terrainData;
|
||||
public string to;
|
||||
|
||||
public long toFileId;
|
||||
}
|
||||
|
||||
// AssetDatabase.ImportAsset(oAssetPath, ImportAssetOptions.Default);
|
||||
// importer.importMaterials = false;
|
||||
// var importer = AssetImporter.GetAtPath(oAssetPath) as ModelImporter;
|
||||
// var nModel = AssetDatabase.LoadAssetAtPath<GameObject>(oAssetPath);
|
||||
|
||||
// // Reimport model with importMaterial = false
|
||||
// var extension = Path.GetExtension(oAssetPath);
|
||||
|
||||
// model_materials = model.GetComponent<Renderer>().sharedMaterials;
|
||||
// var oGUID = AssetDatabase.AssetPathToGUID(oAssetPath);
|
||||
|
||||
// var oAssetPath = AssetDatabase.GetAssetPath(model);
|
||||
// if (model == null) return;
|
||||
//{
|
||||
//static void CreatePrefabReplaceModel(GameObject model)
|
||||
|
||||
//static Material[] model_materials;
|
||||
|
||||
// //create prefab from new model
|
||||
// var prefabPath = oAssetPath.Replace(extension, ".prefab");
|
||||
// var clone = (GameObject)Object.Instantiate(nModel);
|
||||
// clone.GetComponent<Renderer>().sharedMaterials = model_materials;
|
||||
// PrefabUtility.CreatePrefab(prefabPath, clone, ReplacePrefabOptions.ReplaceNameBased);
|
||||
// AssetDatabase.SaveAssets();
|
||||
// GameObject.DestroyImmediate(clone);
|
||||
//}
|
||||
}
|
||||
}
|
||||
10
Assets/FindReference2/Editor/Script/FR2_Export.cs.meta
Normal file
10
Assets/FindReference2/Editor/Script/FR2_Export.cs.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b543c2ce7dc56c2418505cbb6cb7852d
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
211
Assets/FindReference2/Editor/Script/FR2_Helper.cs
Normal file
211
Assets/FindReference2/Editor/Script/FR2_Helper.cs
Normal file
@@ -0,0 +1,211 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
namespace vietlabs.fr2
|
||||
{
|
||||
public class FR2_Helper
|
||||
{
|
||||
internal static readonly AssetType[] FILTERS =
|
||||
{
|
||||
new AssetType("Scene", ".unity"),
|
||||
new AssetType("Prefab", ".prefab"),
|
||||
new AssetType("Model", ".3df", ".3dm", ".3dmf", ".3dv", ".3dx", ".c5d", ".lwo", ".lws", ".ma", ".mb",
|
||||
".mesh", ".vrl", ".wrl", ".wrz", ".fbx", ".dae", ".3ds", ".dxf", ".obj", ".skp", ".max", ".blend"),
|
||||
new AssetType("Material", ".mat", ".cubemap", ".physicsmaterial"),
|
||||
new AssetType("Texture", ".ai", ".apng", ".png", ".bmp", ".cdr", ".dib", ".eps", ".exif", ".ico", ".icon",
|
||||
".j", ".j2c", ".j2k", ".jas", ".jiff", ".jng", ".jp2", ".jpc", ".jpe", ".jpeg", ".jpf", ".jpg", "jpw",
|
||||
"jpx", "jtf", ".mac", ".omf", ".qif", ".qti", "qtif", ".tex", ".tfw", ".tga", ".tif", ".tiff", ".wmf",
|
||||
".psd", ".exr", ".rendertexture"),
|
||||
new AssetType("Video", ".asf", ".asx", ".avi", ".dat", ".divx", ".dvx", ".mlv", ".m2l", ".m2t", ".m2ts",
|
||||
".m2v", ".m4e", ".m4v", "mjp", ".mov", ".movie", ".mp21", ".mp4", ".mpe", ".mpeg", ".mpg", ".mpv2",
|
||||
".ogm", ".qt", ".rm", ".rmvb", ".wmv", ".xvid", ".flv"),
|
||||
new AssetType("Audio", ".mp3", ".wav", ".ogg", ".aif", ".aiff", ".mod", ".it", ".s3m", ".xm"),
|
||||
new AssetType("Script", ".cs", ".js", ".boo"),
|
||||
new AssetType("Text", ".txt", ".json", ".xml", ".bytes", ".sql"),
|
||||
new AssetType("Shader", ".shader", ".cginc"),
|
||||
new AssetType("Animation", ".anim", ".controller", ".overridecontroller", ".mask"),
|
||||
new AssetType("Unity Asset", ".asset", ".guiskin", ".flare", ".fontsettings", ".prefs"),
|
||||
new AssetType("Others") //
|
||||
};
|
||||
|
||||
public static IEnumerable<GameObject> getAllObjsInCurScene()
|
||||
{
|
||||
// foreach (GameObject obj in Object.FindObjectsOfType(typeof(GameObject)))
|
||||
// {
|
||||
// yield return obj;
|
||||
// }
|
||||
|
||||
|
||||
for (var j = 0; j < SceneManager.sceneCount; j++)
|
||||
{
|
||||
Scene scene = SceneManager.GetSceneAt(j);
|
||||
foreach (GameObject item in GetGameObjectsInScene(scene))
|
||||
{
|
||||
yield return item;
|
||||
}
|
||||
}
|
||||
|
||||
if (EditorApplication.isPlaying)
|
||||
{
|
||||
//dont destroy scene
|
||||
GameObject temp = null;
|
||||
try
|
||||
{
|
||||
temp = new GameObject();
|
||||
Object.DontDestroyOnLoad(temp);
|
||||
Scene dontDestroyOnLoad = temp.scene;
|
||||
Object.DestroyImmediate(temp);
|
||||
temp = null;
|
||||
|
||||
foreach (GameObject item in GetGameObjectsInScene(dontDestroyOnLoad))
|
||||
{
|
||||
yield return item;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (temp != null)
|
||||
{
|
||||
Object.DestroyImmediate(temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static IEnumerable<GameObject> GetGameObjectsInScene(Scene scene)
|
||||
{
|
||||
var rootObjects = new List<GameObject>();
|
||||
scene.GetRootGameObjects(rootObjects);
|
||||
|
||||
// iterate root objects and do something
|
||||
for (var i = 0; i < rootObjects.Count; ++i)
|
||||
{
|
||||
GameObject gameObject = rootObjects[i];
|
||||
|
||||
foreach (GameObject item in getAllChild(gameObject))
|
||||
{
|
||||
yield return item;
|
||||
}
|
||||
|
||||
yield return gameObject;
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<GameObject> getAllChild(GameObject target)
|
||||
{
|
||||
if (target.transform.childCount > 0)
|
||||
{
|
||||
for (var i = 0; i < target.transform.childCount; i++)
|
||||
{
|
||||
yield return target.transform.GetChild(i).gameObject;
|
||||
foreach (GameObject item in getAllChild(target.transform.GetChild(i).gameObject))
|
||||
{
|
||||
yield return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<Object> GetAllRefObjects(GameObject obj)
|
||||
{
|
||||
Component[] components = obj.GetComponents<Component>();
|
||||
foreach (Component com in components)
|
||||
{
|
||||
if (com == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var serialized = new SerializedObject(com);
|
||||
SerializedProperty it = serialized.GetIterator().Copy();
|
||||
while (it.NextVisible(true))
|
||||
{
|
||||
if (it.propertyType != SerializedPropertyType.ObjectReference)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (it.objectReferenceValue == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
yield return it.objectReferenceValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static int StringMatch(string pattern, string input)
|
||||
{
|
||||
if (input == pattern)
|
||||
{
|
||||
return int.MaxValue;
|
||||
}
|
||||
|
||||
if (input.Contains(pattern))
|
||||
{
|
||||
return int.MaxValue - 1;
|
||||
}
|
||||
|
||||
var pidx = 0;
|
||||
var score = 0;
|
||||
var tokenScore = 0;
|
||||
|
||||
for (var i = 0; i < input.Length; i++)
|
||||
{
|
||||
char ch = input[i];
|
||||
if (ch == pattern[pidx])
|
||||
{
|
||||
tokenScore += tokenScore + 1; //increasing score for continuos token
|
||||
pidx++;
|
||||
if (pidx >= pattern.Length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tokenScore = 0;
|
||||
}
|
||||
|
||||
score += tokenScore;
|
||||
}
|
||||
|
||||
return score;
|
||||
}
|
||||
|
||||
public static int GetIndex(string ext)
|
||||
{
|
||||
for (var i = 0; i < FILTERS.Length - 1; i++)
|
||||
{
|
||||
if (FILTERS[i].extension.Contains(ext))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return FILTERS.Length - 1; //Others
|
||||
}
|
||||
|
||||
public static void GuiLine(int i_height = 1)
|
||||
|
||||
{
|
||||
Rect rect = EditorGUILayout.GetControlRect(false, i_height);
|
||||
|
||||
rect.height = i_height;
|
||||
|
||||
EditorGUI.DrawRect(rect, new Color(0.5f, 0.5f, 0.5f, 1));
|
||||
}
|
||||
|
||||
public static string GetfileSizeString(long fileSize)
|
||||
{
|
||||
return fileSize <= 1024
|
||||
? fileSize + " B"
|
||||
: fileSize <= 1024 * 1024
|
||||
? Mathf.RoundToInt(fileSize / 1024f) + " KB"
|
||||
: Mathf.RoundToInt(fileSize / 1024f / 1024f) + " MB";
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/FindReference2/Editor/Script/FR2_Helper.cs.meta
Normal file
11
Assets/FindReference2/Editor/Script/FR2_Helper.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d3ba0d9bfe79ff94ca52a3bd6b6870d4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
1612
Assets/FindReference2/Editor/Script/FR2_Ref.cs
Normal file
1612
Assets/FindReference2/Editor/Script/FR2_Ref.cs
Normal file
File diff suppressed because it is too large
Load Diff
10
Assets/FindReference2/Editor/Script/FR2_Ref.cs.meta
Normal file
10
Assets/FindReference2/Editor/Script/FR2_Ref.cs.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6db5b6c2e2bbb4f2093a7cd892ececca
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
389
Assets/FindReference2/Editor/Script/FR2_SceneCache.cs
Normal file
389
Assets/FindReference2/Editor/Script/FR2_SceneCache.cs
Normal file
@@ -0,0 +1,389 @@
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
#define SUPPORT_NESTED_PREFAB
|
||||
#endif
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
#if UNITY_2017_1_OR_NEWER
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine.SceneManagement;
|
||||
#endif
|
||||
#if SUPPORT_NESTED_PREFAB
|
||||
using UnityEditor.Experimental.SceneManagement;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
namespace vietlabs.fr2
|
||||
{
|
||||
public class FR2_SceneCache
|
||||
{
|
||||
private static FR2_SceneCache _api;
|
||||
public static Action onReady;
|
||||
public static bool ready = true;
|
||||
private Dictionary<Component, HashSet<HashValue>> _cache = new Dictionary<Component, HashSet<HashValue>>();
|
||||
public int current;
|
||||
public Dictionary<string, HashSet<Component>> folderCache = new Dictionary<string, HashSet<Component>>();
|
||||
|
||||
private List<GameObject> listGO;
|
||||
|
||||
//public HashSet<string> prefabDependencies = new HashSet<string>();
|
||||
public Dictionary<GameObject, HashSet<string>> prefabDependencies =
|
||||
new Dictionary<GameObject, HashSet<string>>();
|
||||
|
||||
public int total;
|
||||
private IWindow window;
|
||||
|
||||
public FR2_SceneCache()
|
||||
{
|
||||
#if UNITY_2018_1_OR_NEWER
|
||||
EditorApplication.hierarchyChanged -= OnSceneChanged;
|
||||
EditorApplication.hierarchyChanged += OnSceneChanged;
|
||||
#else
|
||||
EditorApplication.hierarchyWindowChanged -= OnSceneChanged;
|
||||
EditorApplication.hierarchyWindowChanged += OnSceneChanged;
|
||||
#endif
|
||||
|
||||
#if UNITY_2018_2_OR_NEWER
|
||||
EditorSceneManager.activeSceneChangedInEditMode -= OnSceneChanged;
|
||||
EditorSceneManager.activeSceneChangedInEditMode += OnSceneChanged;
|
||||
#endif
|
||||
|
||||
#if UNITY_2017_1_OR_NEWER
|
||||
SceneManager.activeSceneChanged -= OnSceneChanged;
|
||||
SceneManager.activeSceneChanged += OnSceneChanged;
|
||||
|
||||
SceneManager.sceneLoaded -= OnSceneChanged;
|
||||
SceneManager.sceneLoaded += OnSceneChanged;
|
||||
|
||||
Undo.postprocessModifications -= OnModify;
|
||||
Undo.postprocessModifications += OnModify;
|
||||
#endif
|
||||
|
||||
#if SUPPORT_NESTED_PREFAB
|
||||
PrefabStage.prefabStageOpened -= prefabOnpen;
|
||||
PrefabStage.prefabStageClosing += prefabClose;
|
||||
PrefabStage.prefabStageOpened -= prefabOnpen;
|
||||
PrefabStage.prefabStageClosing += prefabClose;
|
||||
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
public static FR2_SceneCache Api
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_api == null)
|
||||
{
|
||||
_api = new FR2_SceneCache();
|
||||
}
|
||||
|
||||
return _api;
|
||||
}
|
||||
}
|
||||
|
||||
private bool _dirty = true;
|
||||
public bool Dirty
|
||||
{
|
||||
get { return _dirty; }
|
||||
set { _dirty = value; }
|
||||
}
|
||||
|
||||
public Dictionary<Component, HashSet<HashValue>> cache
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_cache == null)
|
||||
{
|
||||
refreshCache(window);
|
||||
}
|
||||
|
||||
return _cache;
|
||||
}
|
||||
}
|
||||
|
||||
public void refreshCache(IWindow window)
|
||||
{
|
||||
if (window == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// if(!ready) return;
|
||||
this.window = window;
|
||||
|
||||
_cache = new Dictionary<Component, HashSet<HashValue>>();
|
||||
folderCache = new Dictionary<string, HashSet<Component>>();
|
||||
prefabDependencies = new Dictionary<GameObject, HashSet<string>>();
|
||||
|
||||
ready = false;
|
||||
|
||||
List<GameObject> listRootGO = null;
|
||||
|
||||
#if SUPPORT_NESTED_PREFAB
|
||||
|
||||
if (PrefabStageUtility.GetCurrentPrefabStage() != null)
|
||||
{
|
||||
GameObject rootPrefab = PrefabStageUtility.GetCurrentPrefabStage().prefabContentsRoot;
|
||||
if (rootPrefab != null)
|
||||
{
|
||||
listRootGO = new List<GameObject> { rootPrefab };
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
#endif
|
||||
if (listRootGO == null)
|
||||
{
|
||||
listGO = FR2_Unity.getAllObjsInCurScene().ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
listGO = new List<GameObject>();
|
||||
foreach (GameObject item in listRootGO)
|
||||
{
|
||||
listGO.AddRange(FR2_Unity.getAllChild(item, true));
|
||||
}
|
||||
}
|
||||
|
||||
total = listGO.Count;
|
||||
current = 0;
|
||||
// Debug.Log("refresh cache total " + total);
|
||||
EditorApplication.update -= OnUpdate;
|
||||
EditorApplication.update += OnUpdate;
|
||||
|
||||
// foreach (var item in FR2_Helper.getAllObjsInCurScene())
|
||||
// {
|
||||
// // Debug.Log("object in scene: " + item.name);
|
||||
// Component[] components = item.GetComponents<Component>();
|
||||
// foreach (var com in components)
|
||||
// {
|
||||
// if(com == null) continue;
|
||||
// SerializedObject serialized = new SerializedObject(com);
|
||||
// SerializedProperty it = serialized.GetIterator().Copy();
|
||||
// while (it.NextVisible(true))
|
||||
// {
|
||||
|
||||
// if (it.propertyType != SerializedPropertyType.ObjectReference) continue;
|
||||
// if (it.objectReferenceValue == null) continue;
|
||||
|
||||
// if(!_cache.ContainsKey(com)) _cache.Add(com, new HashSet<SerializedProperty>());
|
||||
// if(!_cache[com].Contains(it))
|
||||
// _cache[com].Add(it.Copy());
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
Dirty = false;
|
||||
}
|
||||
|
||||
private void OnUpdate()
|
||||
{
|
||||
for (var i = 0; i < 5 * FR2_Cache.priority; i++)
|
||||
{
|
||||
if (listGO == null || listGO.Count <= 0)
|
||||
{
|
||||
//done
|
||||
// Debug.Log("done");
|
||||
EditorApplication.update -= OnUpdate;
|
||||
ready = true;
|
||||
Dirty = false;
|
||||
listGO = null;
|
||||
if (onReady != null)
|
||||
{
|
||||
onReady();
|
||||
}
|
||||
|
||||
if (window != null)
|
||||
{
|
||||
window.OnSelectionChange();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int index = listGO.Count - 1;
|
||||
|
||||
GameObject go = listGO[index];
|
||||
if (go == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
string prefabGUID = FR2_Unity.GetPrefabParent(go);
|
||||
if (!string.IsNullOrEmpty(prefabGUID))
|
||||
{
|
||||
Transform parent = go.transform.parent;
|
||||
while (parent != null)
|
||||
{
|
||||
GameObject g = parent.gameObject;
|
||||
if (!prefabDependencies.ContainsKey(g))
|
||||
{
|
||||
prefabDependencies.Add(g, new HashSet<string>());
|
||||
}
|
||||
|
||||
prefabDependencies[g].Add(prefabGUID);
|
||||
parent = parent.parent;
|
||||
}
|
||||
}
|
||||
|
||||
Component[] components = go.GetComponents<Component>();
|
||||
|
||||
foreach (Component com in components)
|
||||
{
|
||||
if (com == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var serialized = new SerializedObject(com);
|
||||
SerializedProperty it = serialized.GetIterator().Copy();
|
||||
while (it.NextVisible(true))
|
||||
{
|
||||
if (it.propertyType != SerializedPropertyType.ObjectReference)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (it.objectReferenceValue == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var isSceneObject = true;
|
||||
string path = AssetDatabase.GetAssetPath(it.objectReferenceValue);
|
||||
if (!string.IsNullOrEmpty(path))
|
||||
{
|
||||
string dir = Path.GetDirectoryName(path);
|
||||
if (!string.IsNullOrEmpty(dir))
|
||||
{
|
||||
isSceneObject = false;
|
||||
if (!folderCache.ContainsKey(dir))
|
||||
{
|
||||
folderCache.Add(dir, new HashSet<Component>());
|
||||
}
|
||||
|
||||
if (!folderCache[dir].Contains(com))
|
||||
{
|
||||
folderCache[dir].Add(com);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!_cache.ContainsKey(com))
|
||||
{
|
||||
_cache.Add(com, new HashSet<HashValue>());
|
||||
}
|
||||
|
||||
_cache[com].Add(new HashValue
|
||||
{ target = it.objectReferenceValue, isSceneObject = isSceneObject });
|
||||
|
||||
// if (!_cache.ContainsKey(com)) _cache.Add(com, new HashSet<SerializedProperty>());
|
||||
// if (!_cache[com].Contains(it))
|
||||
// _cache[com].Add(it.Copy());
|
||||
// string path = AssetDatabase.GetAssetPath(it.objectReferenceValue);
|
||||
|
||||
// if (string.IsNullOrEmpty(path)) continue;
|
||||
// string dir = System.IO.Path.GetDirectoryName(path);
|
||||
// if (string.IsNullOrEmpty(dir)) continue;
|
||||
// if (!folderCache.ContainsKey(dir)) folderCache.Add(dir, new HashSet<Component>());
|
||||
// if (!folderCache[dir].Contains(com))
|
||||
// folderCache[dir].Add(com);
|
||||
}
|
||||
}
|
||||
|
||||
listGO.RemoveAt(index);
|
||||
current++;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSceneChanged()
|
||||
{
|
||||
if (!Application.isPlaying)
|
||||
{
|
||||
Api.refreshCache(window);
|
||||
return;
|
||||
}
|
||||
|
||||
SetDirty();
|
||||
}
|
||||
|
||||
#if UNITY_2017_1_OR_NEWER
|
||||
private UndoPropertyModification[] OnModify(UndoPropertyModification[] modifications)
|
||||
{
|
||||
for (var i = 0; i < modifications.Length; i++)
|
||||
{
|
||||
if (modifications[i].currentValue.objectReference != null)
|
||||
{
|
||||
SetDirty();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return modifications;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
public void SetDirty()
|
||||
{
|
||||
Dirty = true;
|
||||
}
|
||||
|
||||
|
||||
public class HashValue
|
||||
{
|
||||
public bool isSceneObject;
|
||||
|
||||
public Object target;
|
||||
//public SerializedProperty pro;
|
||||
|
||||
// public HashValue(SerializedProperty pro, bool isSceneObject)
|
||||
// {
|
||||
// //this.pro = pro;
|
||||
// this.isSceneObject = isSceneObject;
|
||||
// }
|
||||
}
|
||||
#if SUPPORT_NESTED_PREFAB
|
||||
|
||||
private void prefabClose(PrefabStage obj)
|
||||
{
|
||||
if (!Application.isPlaying)
|
||||
{
|
||||
Api.refreshCache(window);
|
||||
return;
|
||||
}
|
||||
|
||||
SetDirty();
|
||||
}
|
||||
|
||||
private void prefabOnpen(PrefabStage obj)
|
||||
{
|
||||
if (!Application.isPlaying)
|
||||
{
|
||||
Api.refreshCache(window);
|
||||
return;
|
||||
}
|
||||
|
||||
SetDirty();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if UNITY_2017_1_OR_NEWER
|
||||
private void OnSceneChanged(Scene scene, LoadSceneMode mode)
|
||||
{
|
||||
OnSceneChanged();
|
||||
}
|
||||
|
||||
private void OnSceneChanged(Scene arg0, Scene arg1)
|
||||
{
|
||||
OnSceneChanged();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
10
Assets/FindReference2/Editor/Script/FR2_SceneCache.cs.meta
Normal file
10
Assets/FindReference2/Editor/Script/FR2_SceneCache.cs.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 658977c5b6e84344581803c8025947d3
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
215
Assets/FindReference2/Editor/Script/FR2_Selection.cs
Normal file
215
Assets/FindReference2/Editor/Script/FR2_Selection.cs
Normal file
@@ -0,0 +1,215 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityObject = UnityEngine.Object;
|
||||
|
||||
namespace vietlabs.fr2
|
||||
{
|
||||
public class FR2_Selection : IRefDraw
|
||||
{
|
||||
internal HashSet<string> guidSet = new HashSet<string>();
|
||||
internal HashSet<string> instSet = new HashSet<string>(); // Do not reference directly to SceneObject (which might be destroyed anytime)
|
||||
|
||||
public int Count
|
||||
{
|
||||
get { return guidSet.Count + instSet.Count; }
|
||||
}
|
||||
|
||||
public bool Contains(string guidOrInstID)
|
||||
{
|
||||
return guidSet.Contains(guidOrInstID) || instSet.Contains(guidOrInstID);
|
||||
}
|
||||
|
||||
public bool Contains(UnityObject sceneObject)
|
||||
{
|
||||
var id = sceneObject.GetInstanceID().ToString();
|
||||
return instSet.Contains(id);
|
||||
}
|
||||
|
||||
public void Add(UnityObject sceneObject)
|
||||
{
|
||||
if (sceneObject == null) return;
|
||||
var id = sceneObject.GetInstanceID().ToString();
|
||||
instSet.Add(id); // hashset does not need to check exist before add
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
public void AddRange(params UnityObject[] sceneObjects)
|
||||
{
|
||||
foreach (var go in sceneObjects)
|
||||
{
|
||||
var id = go.GetInstanceID().ToString();
|
||||
instSet.Add(id); // hashset does not need to check exist before add
|
||||
}
|
||||
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
public void Add(string guid)
|
||||
{
|
||||
if (guidSet.Contains(guid)) return;
|
||||
var assetPath = AssetDatabase.GUIDToAssetPath(guid);
|
||||
if (string.IsNullOrEmpty(assetPath))
|
||||
{
|
||||
Debug.LogWarning("Invalid GUID: " + guid);
|
||||
return;
|
||||
}
|
||||
|
||||
guidSet.Add(guid);
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
public void AddRange(params string[] guids)
|
||||
{
|
||||
foreach (var id in guids)
|
||||
{
|
||||
Add(id);
|
||||
}
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
public void Remove(UnityObject sceneObject)
|
||||
{
|
||||
if (sceneObject == null) return;
|
||||
var id = sceneObject.GetInstanceID().ToString();
|
||||
instSet.Remove(id);
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
public void Remove(string guidOrInstID)
|
||||
{
|
||||
guidSet.Remove(guidOrInstID);
|
||||
instSet.Remove(guidOrInstID);
|
||||
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
guidSet.Clear();
|
||||
instSet.Clear();
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
public bool isSelectingAsset
|
||||
{
|
||||
get { return instSet.Count == 0; }
|
||||
}
|
||||
|
||||
public void Add(FR2_Ref rf)
|
||||
{
|
||||
if (rf.isSceneRef)
|
||||
{
|
||||
Add(rf.component);
|
||||
}
|
||||
else
|
||||
{
|
||||
Add(rf.asset.guid);
|
||||
}
|
||||
}
|
||||
|
||||
public void Remove(FR2_Ref rf)
|
||||
{
|
||||
if (rf.isSceneRef)
|
||||
{
|
||||
Remove(rf.component);
|
||||
}
|
||||
else
|
||||
{
|
||||
Remove(rf.asset.guid);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------ instance
|
||||
|
||||
private bool dirty;
|
||||
private readonly FR2_RefDrawer drawer;
|
||||
internal Dictionary<string, FR2_Ref> refs;
|
||||
internal bool isLock;
|
||||
|
||||
public FR2_Selection(IWindow window)
|
||||
{
|
||||
this.window = window;
|
||||
drawer = new FR2_RefDrawer(window);
|
||||
drawer.groupDrawer.hideGroupIfPossible = true;
|
||||
drawer.forceHideDetails = true;
|
||||
drawer.level0Group = string.Empty;
|
||||
|
||||
dirty = true;
|
||||
drawer.SetDirty();
|
||||
}
|
||||
|
||||
public IWindow window { get; set; }
|
||||
|
||||
public int ElementCount()
|
||||
{
|
||||
return refs == null ? 0 : refs.Count;
|
||||
}
|
||||
|
||||
public bool DrawLayout()
|
||||
{
|
||||
if (dirty) RefreshView();
|
||||
return drawer.DrawLayout();
|
||||
}
|
||||
|
||||
public bool Draw(Rect rect)
|
||||
{
|
||||
if (dirty) RefreshView();
|
||||
if (refs == null) return false;
|
||||
|
||||
DrawLock(new Rect(rect.xMax - 12f, rect.yMin - 12f, 16f, 16f));
|
||||
|
||||
return drawer.Draw(rect);
|
||||
}
|
||||
|
||||
public void SetDirty()
|
||||
{
|
||||
drawer.SetDirty();
|
||||
}
|
||||
|
||||
private static readonly Color PRO = new Color(0.8f, 0.8f, 0.8f, 1f);
|
||||
private static readonly Color INDIE = new Color(0.1f, 0.1f, 0.1f, 1f);
|
||||
|
||||
public void DrawLock(Rect rect)
|
||||
{
|
||||
GUI2.ContentColor(() =>
|
||||
{
|
||||
var icon = isLock ? FR2_Icon.Lock : FR2_Icon.Unlock;
|
||||
if (GUI2.Toggle(rect, ref isLock, icon))
|
||||
{
|
||||
window.WillRepaint = true;
|
||||
window.OnSelectionChange();
|
||||
}
|
||||
}, GUI2.Theme(PRO, INDIE));
|
||||
}
|
||||
|
||||
public void RefreshView()
|
||||
{
|
||||
if (refs == null) refs = new Dictionary<string, FR2_Ref>();
|
||||
refs.Clear();
|
||||
|
||||
if (instSet.Count > 0)
|
||||
{
|
||||
foreach (var instId in instSet)
|
||||
{
|
||||
refs.Add(instId, new FR2_SceneRef(0, EditorUtility.InstanceIDToObject(int.Parse(instId))));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var guid in guidSet)
|
||||
{
|
||||
var asset = FR2_Cache.Api.Get(guid, false);
|
||||
refs.Add(guid, new FR2_Ref(0, 0, asset, null)
|
||||
{
|
||||
isSceneRef = false
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
drawer.SetRefs(refs);
|
||||
dirty = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/FindReference2/Editor/Script/FR2_Selection.cs.meta
Normal file
11
Assets/FindReference2/Editor/Script/FR2_Selection.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9a9a5bbf1fb9c4a1b9a0013057b1f59d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
417
Assets/FindReference2/Editor/Script/FR2_TreeUI2.cs
Normal file
417
Assets/FindReference2/Editor/Script/FR2_TreeUI2.cs
Normal file
@@ -0,0 +1,417 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace vietlabs.fr2
|
||||
{
|
||||
public class FR2_TreeUI2
|
||||
{
|
||||
internal Drawer drawer;
|
||||
private Vector2 position;
|
||||
private TreeItem rootItem;
|
||||
internal Rect visibleRect;
|
||||
public float itemPaddingRight = 0f;
|
||||
|
||||
public FR2_TreeUI2(Drawer drawer)
|
||||
{
|
||||
this.drawer = drawer;
|
||||
}
|
||||
|
||||
public void Reset(params string[] root)
|
||||
{
|
||||
position = Vector2.zero;
|
||||
|
||||
rootItem = new TreeItem
|
||||
{
|
||||
tree = this,
|
||||
id = "$root",
|
||||
height = 0,
|
||||
depth = -1,
|
||||
_isOpen = true,
|
||||
highlight = false,
|
||||
childCount = root.Length
|
||||
};
|
||||
|
||||
rootItem.RefreshChildren(root);
|
||||
rootItem.DeepOpen();
|
||||
}
|
||||
|
||||
public void Draw(Rect rect)
|
||||
{
|
||||
if (rect.width > 0)
|
||||
{
|
||||
visibleRect = rect;
|
||||
}
|
||||
|
||||
var contentRect = new Rect(0f, 0f, 1f, rootItem.childrenHeight);
|
||||
bool noScroll = contentRect.height < visibleRect.height;
|
||||
if (noScroll)
|
||||
{
|
||||
position = Vector2.zero;
|
||||
}
|
||||
|
||||
var minY = (int)position.y;
|
||||
var maxY = (int)(position.y + visibleRect.height);
|
||||
contentRect.x -= FR2_Setting.TreeIndent;
|
||||
|
||||
TreeItem.DrawCall = 0;
|
||||
TreeItem.DrawRender = 0;
|
||||
position = GUI.BeginScrollView(visibleRect, position, contentRect);
|
||||
{
|
||||
var r = new Rect(0, 0, rect.width - (noScroll ? 4f : 18f) - itemPaddingRight, 16f);
|
||||
var index = 0;
|
||||
rootItem.Draw(ref index, ref r, minY, maxY);
|
||||
}
|
||||
|
||||
GUI.EndScrollView();
|
||||
}
|
||||
|
||||
public void DrawLayout()
|
||||
{
|
||||
EventType evtType = Event.current.type;
|
||||
Rect r = GUILayoutUtility.GetRect(1f, Screen.width, 16f, Screen.height);
|
||||
|
||||
if (evtType != EventType.Layout)
|
||||
{
|
||||
visibleRect = r;
|
||||
}
|
||||
|
||||
Draw(visibleRect);
|
||||
}
|
||||
|
||||
public bool NoScroll()
|
||||
{
|
||||
return rootItem.childrenHeight < visibleRect.height;
|
||||
}
|
||||
|
||||
// ------------------------ DELEGATE --------------
|
||||
|
||||
public class Drawer
|
||||
{
|
||||
public virtual int GetHeight(string id)
|
||||
{
|
||||
return 16;
|
||||
}
|
||||
|
||||
public virtual int GetChildCount(string id)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public virtual string[] GetChildren(string id)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual void Draw(Rect r, TreeItem item)
|
||||
{
|
||||
GUI.Label(r, item.id);
|
||||
}
|
||||
}
|
||||
|
||||
public class GroupDrawer : Drawer
|
||||
{
|
||||
public Action<Rect, string, int> drawGroup;
|
||||
public Action<Rect, string> drawItem;
|
||||
private Dictionary<string, List<string>> groupDict;
|
||||
internal FR2_TreeUI2 tree;
|
||||
|
||||
public GroupDrawer(Action<Rect, string, int> drawGroup, Action<Rect, string> drawItem)
|
||||
{
|
||||
this.drawItem = drawItem;
|
||||
this.drawGroup = drawGroup;
|
||||
}
|
||||
|
||||
// ----------------- TREE WRAPPER ------------------
|
||||
public bool TreeNoScroll()
|
||||
{
|
||||
return tree.NoScroll();
|
||||
}
|
||||
|
||||
public bool hideGroupIfPossible;
|
||||
|
||||
|
||||
public void Reset<T>(List<T> items, Func<T, string> idFunc, Func<T, string> groupFunc,
|
||||
Action<List<string>> customGroupSort = null)
|
||||
{
|
||||
groupDict = new Dictionary<string, List<string>>();
|
||||
|
||||
for (var i = 0; i < items.Count; i++)
|
||||
{
|
||||
List<string> list;
|
||||
|
||||
string groupName = groupFunc(items[i]);
|
||||
if (groupName == null) continue; // do not exclude groupName string.Empty
|
||||
|
||||
string itemId = idFunc(items[i]);
|
||||
if (string.IsNullOrEmpty(itemId)) continue; // ignore items without id
|
||||
|
||||
if (!groupDict.TryGetValue(groupName, out list))
|
||||
{
|
||||
list = new List<string>();
|
||||
groupDict.Add(groupName, list);
|
||||
}
|
||||
|
||||
list.Add(itemId);
|
||||
}
|
||||
|
||||
if (tree == null)
|
||||
{
|
||||
tree = new FR2_TreeUI2(this);
|
||||
}
|
||||
|
||||
List<string> groups = groupDict.Keys.ToList();
|
||||
|
||||
if (hideGroupIfPossible && groups.Count == 1) //single group : Flat list
|
||||
{
|
||||
var v = groupDict[groups[0]];
|
||||
tree.Reset(v.ToArray());
|
||||
groupDict.Clear();
|
||||
}
|
||||
else
|
||||
{ //multiple groups
|
||||
if (customGroupSort != null)
|
||||
{
|
||||
customGroupSort(groups);
|
||||
}
|
||||
else
|
||||
{
|
||||
groups.Sort();
|
||||
}
|
||||
|
||||
tree.Reset(groups.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
public void Draw(Rect r)
|
||||
{
|
||||
if (tree != null) tree.Draw(r);
|
||||
}
|
||||
|
||||
public bool hasChildren
|
||||
{
|
||||
get
|
||||
{
|
||||
return tree != null && tree.rootItem.childCount > 0;
|
||||
}
|
||||
}
|
||||
|
||||
public bool hasValidTree
|
||||
{
|
||||
get { return groupDict != null && tree != null; }
|
||||
}
|
||||
|
||||
public void DrawLayout()
|
||||
{
|
||||
if (tree != null) tree.DrawLayout();
|
||||
}
|
||||
|
||||
// ----------------- DRAWER WRAPPER ------------------
|
||||
|
||||
public override int GetChildCount(string id)
|
||||
{
|
||||
if (string.IsNullOrEmpty(id)) return 0;
|
||||
|
||||
List<string> group;
|
||||
if (groupDict.TryGetValue(id, out group))
|
||||
{
|
||||
return group.Count;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override string[] GetChildren(string id)
|
||||
{
|
||||
List<string> group;
|
||||
if (groupDict.TryGetValue(id, out group))
|
||||
{
|
||||
return group.ToArray();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public override void Draw(Rect r, TreeItem item)
|
||||
{
|
||||
List<string> group;
|
||||
if (groupDict.TryGetValue(item.id, out group))
|
||||
{
|
||||
drawGroup(r, item.id, item.childCount);
|
||||
return;
|
||||
}
|
||||
|
||||
drawItem(r, item.id);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------ TreeItem2 --------------
|
||||
|
||||
public class TreeItem
|
||||
{
|
||||
public static int DrawCall;
|
||||
public static int DrawRender;
|
||||
|
||||
internal bool _isOpen;
|
||||
|
||||
public int childCount;
|
||||
public List<TreeItem> children;
|
||||
public int childrenHeight;
|
||||
public int depth; // item depth
|
||||
|
||||
public int height;
|
||||
public bool highlight;
|
||||
|
||||
public string id; // item id
|
||||
|
||||
internal TreeItem parent;
|
||||
//static Color COLOR = new Color(0f, 0f, 0f, 0.05f);
|
||||
|
||||
internal FR2_TreeUI2 tree;
|
||||
|
||||
public bool IsOpen
|
||||
{
|
||||
get { return _isOpen; }
|
||||
set
|
||||
{
|
||||
if (_isOpen == value || childCount == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_isOpen = value;
|
||||
|
||||
if (_isOpen)
|
||||
{
|
||||
if (children == null)
|
||||
{
|
||||
RefreshChildren(tree.drawer.GetChildren(id));
|
||||
}
|
||||
|
||||
//Update height for all parents
|
||||
TreeItem p = parent;
|
||||
while (p != null)
|
||||
{
|
||||
p.childrenHeight += childrenHeight;
|
||||
p = p.parent;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Update height for all parents
|
||||
TreeItem p = parent;
|
||||
while (p != null)
|
||||
{
|
||||
p.childrenHeight -= childrenHeight;
|
||||
p = p.parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void DeepOpen()
|
||||
{
|
||||
IsOpen = true;
|
||||
if (children == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0; i < children.Count; i++)
|
||||
{
|
||||
children[i].DeepOpen();
|
||||
}
|
||||
}
|
||||
|
||||
internal void Draw(ref int index, ref Rect rect, int minY, int maxY)
|
||||
{
|
||||
DrawCall++;
|
||||
|
||||
// if (DrawCall < 10)
|
||||
// {
|
||||
// Debug.Log(index + ":" + rect + ":" + minY + ":" + maxY + ":" + height + ":" + childrenHeight);
|
||||
// }
|
||||
|
||||
//var skipDraw = (rect.y >= maxY) || (height <=0);
|
||||
float min = rect.y;
|
||||
float max = rect.y + height;
|
||||
bool interMin = min >= minY && min <= maxY;
|
||||
bool interMax = max >= minY && max <= maxY;
|
||||
|
||||
if (height > 0 && (interMin || interMax))
|
||||
{
|
||||
DrawRender++;
|
||||
rect.height = height;
|
||||
|
||||
if (index % 2 == 1 && FR2_Setting.AlternateRowColor)
|
||||
{
|
||||
Color o = GUI.color;
|
||||
GUI.color = FR2_Setting.RowColor;
|
||||
// GUI.DrawTexture(rect, EditorGUIUtility.whiteTexture);
|
||||
GUI.DrawTexture(new Rect(rect.x - FR2_Setting.TreeIndent, rect.y, rect.width, rect.height),
|
||||
EditorGUIUtility.whiteTexture);
|
||||
GUI.color = o;
|
||||
}
|
||||
|
||||
float x = (depth + 1) * 16f;
|
||||
tree.drawer.Draw(new Rect(x, rect.y, rect.width - x, rect.height), this);
|
||||
|
||||
if (childCount > 0)
|
||||
{
|
||||
IsOpen = GUI.Toggle(new Rect(rect.x + x - 16f, rect.y, 16f, 16f), IsOpen, string.Empty,
|
||||
EditorStyles.foldout);
|
||||
}
|
||||
|
||||
index++;
|
||||
rect.y += height;
|
||||
}
|
||||
else
|
||||
{
|
||||
rect.y += height;
|
||||
}
|
||||
|
||||
if (_isOpen && rect.y <= maxY) //draw children
|
||||
{
|
||||
for (var i = 0; i < children.Count; i++)
|
||||
{
|
||||
children[i].Draw(ref index, ref rect, minY, maxY);
|
||||
if (rect.y > maxY)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void RefreshChildren(string[] childrenIDs)
|
||||
{
|
||||
childCount = childrenIDs.Length;
|
||||
childrenHeight = 0;
|
||||
children = new List<TreeItem>();
|
||||
|
||||
for (var i = 0; i < childCount; i++)
|
||||
{
|
||||
string itemId = childrenIDs[i];
|
||||
|
||||
var item = new TreeItem
|
||||
{
|
||||
tree = tree,
|
||||
parent = this,
|
||||
|
||||
id = itemId,
|
||||
depth = depth + 1,
|
||||
highlight = false,
|
||||
|
||||
height = tree.drawer.GetHeight(itemId),
|
||||
childCount = tree.drawer.GetChildCount(itemId)
|
||||
};
|
||||
|
||||
childrenHeight += item.height;
|
||||
children.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/FindReference2/Editor/Script/FR2_TreeUI2.cs.meta
Normal file
12
Assets/FindReference2/Editor/Script/FR2_TreeUI2.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c0367155479c84189ad956f35f707b7c
|
||||
timeCreated: 1493613697
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
1085
Assets/FindReference2/Editor/Script/FR2_Unity.cs
Normal file
1085
Assets/FindReference2/Editor/Script/FR2_Unity.cs
Normal file
File diff suppressed because it is too large
Load Diff
10
Assets/FindReference2/Editor/Script/FR2_Unity.cs.meta
Normal file
10
Assets/FindReference2/Editor/Script/FR2_Unity.cs.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7d62736a417e747e481e3aa85951cd18
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
144
Assets/FindReference2/Editor/Script/FR2_UsedInBuild.cs
Normal file
144
Assets/FindReference2/Editor/Script/FR2_UsedInBuild.cs
Normal file
@@ -0,0 +1,144 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace vietlabs.fr2
|
||||
{
|
||||
public class FR2_UsedInBuild : IRefDraw
|
||||
{
|
||||
private readonly FR2_TreeUI2.GroupDrawer groupDrawer;
|
||||
|
||||
private bool dirty;
|
||||
private readonly FR2_RefDrawer drawer;
|
||||
internal Dictionary<string, FR2_Ref> refs;
|
||||
|
||||
public FR2_UsedInBuild(IWindow window)
|
||||
{
|
||||
this.window = window;
|
||||
drawer = new FR2_RefDrawer(window);
|
||||
dirty = true;
|
||||
drawer.SetDirty();
|
||||
}
|
||||
|
||||
public IWindow window { get; set; }
|
||||
|
||||
|
||||
public int ElementCount()
|
||||
{
|
||||
return refs == null ? 0 : refs.Count;
|
||||
}
|
||||
|
||||
public bool Draw(Rect rect)
|
||||
{
|
||||
if (dirty)
|
||||
{
|
||||
RefreshView();
|
||||
}
|
||||
|
||||
return drawer.Draw(rect);
|
||||
}
|
||||
|
||||
public bool DrawLayout()
|
||||
{
|
||||
//Debug.Log("draw");
|
||||
if (dirty)
|
||||
{
|
||||
RefreshView();
|
||||
}
|
||||
|
||||
return drawer.DrawLayout();
|
||||
}
|
||||
|
||||
public void SetDirty()
|
||||
{
|
||||
dirty = true;
|
||||
drawer.SetDirty();
|
||||
}
|
||||
|
||||
public void RefreshView()
|
||||
{
|
||||
var scenes = new HashSet<string>();
|
||||
// string[] scenes = new string[sceneCount];
|
||||
foreach (EditorBuildSettingsScene scene in EditorBuildSettings.scenes)
|
||||
{
|
||||
if (scene == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (scene.enabled == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
string sce = AssetDatabase.AssetPathToGUID(scene.path);
|
||||
|
||||
if (scenes.Contains(sce))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
scenes.Add(sce);
|
||||
}
|
||||
|
||||
refs = FR2_Ref.FindUsage(scenes.ToArray());
|
||||
|
||||
foreach (string VARIABLE in scenes)
|
||||
{
|
||||
FR2_Ref asset = null;
|
||||
if (!refs.TryGetValue(VARIABLE, out asset))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
asset.depth = 1;
|
||||
}
|
||||
|
||||
List<FR2_Asset> list = FR2_Cache.Api.AssetList;
|
||||
int count = list.Count;
|
||||
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
FR2_Asset item = list[i];
|
||||
if (item.inEditor) continue;
|
||||
if (item.inPlugins)
|
||||
{
|
||||
if (item.type == FR2_AssetType.SCENE) continue;
|
||||
}
|
||||
|
||||
if (item.inResources || item.inStreamingAsset || item.inPlugins)
|
||||
{
|
||||
if (refs.ContainsKey(item.guid))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
refs.Add(item.guid, new FR2_Ref(0, 1, item, null));
|
||||
}
|
||||
}
|
||||
|
||||
// remove ignored items
|
||||
var vals = refs.Values.ToArray();
|
||||
foreach (var item in vals)
|
||||
{
|
||||
foreach (var ig in FR2_Setting.s.listIgnore)
|
||||
{
|
||||
if (!item.asset.assetPath.StartsWith(ig)) continue;
|
||||
refs.Remove(item.asset.guid);
|
||||
//Debug.Log("Remove: " + item.asset.assetPath + "\n" + ig);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
drawer.SetRefs(refs);
|
||||
dirty = false;
|
||||
}
|
||||
|
||||
internal void RefreshSort()
|
||||
{
|
||||
drawer.RefreshSort();
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/FindReference2/Editor/Script/FR2_UsedInBuild.cs.meta
Normal file
11
Assets/FindReference2/Editor/Script/FR2_UsedInBuild.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e0eebac9e6cbe431ca16d9cb27500785
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
947
Assets/FindReference2/Editor/Script/FR2_WindowAll.cs
Normal file
947
Assets/FindReference2/Editor/Script/FR2_WindowAll.cs
Normal file
@@ -0,0 +1,947 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
#if UNITY_5_3_OR_NEWER
|
||||
#endif
|
||||
|
||||
namespace vietlabs.fr2
|
||||
{
|
||||
// filter, ignore anh huong ket qua thi hien mau do
|
||||
// optimize lag duplicate khi use
|
||||
public class FR2_WindowAll : FR2_WindowBase, IHasCustomMenu
|
||||
{
|
||||
|
||||
[MenuItem("Window/Find Reference 2")]
|
||||
private static void ShowWindow()
|
||||
{
|
||||
var _window = CreateInstance<FR2_WindowAll>();
|
||||
_window.InitIfNeeded();
|
||||
FR2_Unity.SetWindowTitle(_window, "FR2");
|
||||
_window.Show();
|
||||
}
|
||||
|
||||
[NonSerialized] internal FR2_Bookmark bookmark;
|
||||
[NonSerialized] internal FR2_Selection selection;
|
||||
[NonSerialized] internal FR2_UsedInBuild UsedInBuild;
|
||||
[NonSerialized] internal FR2_DuplicateTree2 Duplicated;
|
||||
[NonSerialized] internal FR2_RefDrawer RefUnUse;
|
||||
|
||||
[NonSerialized] internal FR2_RefDrawer UsesDrawer; // [Selected Assets] are [USING] (depends on / contains reference to) ---> those assets
|
||||
[NonSerialized] internal FR2_RefDrawer UsedByDrawer; // [Selected Assets] are [USED BY] <---- those assets
|
||||
[NonSerialized] internal FR2_RefDrawer SceneToAssetDrawer; // [Selected GameObjects in current Scene] are [USING] ---> those assets
|
||||
|
||||
[NonSerialized] internal FR2_RefDrawer RefInScene; // [Selected Assets] are [USED BY] <---- those components in current Scene
|
||||
[NonSerialized] internal FR2_RefDrawer SceneUsesDrawer; // [Selected GameObjects] are [USING] ---> those components / GameObjects in current scene
|
||||
[NonSerialized] internal FR2_RefDrawer RefSceneInScene; // [Selected GameObjects] are [USED BY] <---- those components / GameObjects in current scene
|
||||
|
||||
|
||||
internal int level;
|
||||
private Vector2 scrollPos;
|
||||
private string tempGUID;
|
||||
private Object tempObject;
|
||||
|
||||
protected bool lockSelection
|
||||
{
|
||||
get { return selection != null && selection.isLock; }
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
Repaint();
|
||||
}
|
||||
|
||||
protected void InitIfNeeded()
|
||||
{
|
||||
if (UsesDrawer != null) return;
|
||||
|
||||
UsesDrawer = new FR2_RefDrawer(this)
|
||||
{
|
||||
messageEmpty = "[Selected Assets] are not [USING] (depends on / contains reference to) any other assets!"
|
||||
};
|
||||
|
||||
UsedByDrawer = new FR2_RefDrawer(this)
|
||||
{
|
||||
messageEmpty = "[Selected Assets] are not [USED BY] any other assets!"
|
||||
};
|
||||
|
||||
Duplicated = new FR2_DuplicateTree2(this);
|
||||
SceneToAssetDrawer = new FR2_RefDrawer(this)
|
||||
{
|
||||
messageEmpty = "[Selected GameObjects] (in current open scenes) are not [USING] any assets!"
|
||||
};
|
||||
|
||||
RefUnUse = new FR2_RefDrawer(this);
|
||||
RefUnUse.groupDrawer.hideGroupIfPossible = true;
|
||||
|
||||
UsedInBuild = new FR2_UsedInBuild(this);
|
||||
bookmark = new FR2_Bookmark(this);
|
||||
selection = new FR2_Selection(this);
|
||||
|
||||
SceneUsesDrawer = new FR2_RefDrawer(this)
|
||||
{
|
||||
messageEmpty = "[Selected GameObjects] are not [USING] any other GameObjects in scenes"
|
||||
};
|
||||
|
||||
RefInScene = new FR2_RefDrawer(this)
|
||||
{
|
||||
messageEmpty = "[Selected Assets] are not [USED BY] any GameObjects in opening scenes!"
|
||||
};
|
||||
|
||||
RefSceneInScene = new FR2_RefDrawer(this)
|
||||
{
|
||||
messageEmpty = "[Selected GameObjects] are not [USED BY] by any GameObjects in opening scenes!"
|
||||
};
|
||||
|
||||
#if UNITY_2018_OR_NEWER
|
||||
UnityEditor.SceneManagement.EditorSceneManager.activeSceneChangedInEditMode -= OnSceneChanged;
|
||||
UnityEditor.SceneManagement.EditorSceneManager.activeSceneChangedInEditMode += OnSceneChanged;
|
||||
#elif UNITY_2017_OR_NEWER
|
||||
UnityEditor.SceneManagement.EditorSceneManager.activeSceneChanged -= OnSceneChanged;
|
||||
UnityEditor.SceneManagement.EditorSceneManager.activeSceneChanged += OnSceneChanged;
|
||||
#endif
|
||||
|
||||
FR2_Cache.onReady -= OnReady;
|
||||
FR2_Cache.onReady += OnReady;
|
||||
|
||||
FR2_Setting.OnIgnoreChange -= OnIgnoreChanged;
|
||||
FR2_Setting.OnIgnoreChange += OnIgnoreChanged;
|
||||
|
||||
Repaint();
|
||||
}
|
||||
|
||||
#if UNITY_2018_OR_NEWER
|
||||
private void OnSceneChanged(Scene arg0, Scene arg1)
|
||||
{
|
||||
if (IsFocusingFindInScene || IsFocusingSceneToAsset || IsFocusingSceneInScene)
|
||||
{
|
||||
OnSelectionChange();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
protected void OnIgnoreChanged()
|
||||
{
|
||||
RefUnUse.ResetUnusedAsset();
|
||||
UsedInBuild.SetDirty();
|
||||
|
||||
OnSelectionChange();
|
||||
}
|
||||
protected void OnCSVClick()
|
||||
{
|
||||
FR2_Ref[] csvSource = null;
|
||||
var drawer = GetAssetDrawer();
|
||||
|
||||
if (drawer != null) csvSource = drawer.source;
|
||||
|
||||
if (IsFocusingUnused && csvSource == null)
|
||||
{
|
||||
csvSource = RefUnUse.source;
|
||||
//if (csvSource != null) Debug.Log("d : " + csvSource.Length);
|
||||
}
|
||||
|
||||
if (IsFocusingUsedInBuild && csvSource == null)
|
||||
{
|
||||
csvSource = FR2_Ref.FromDict(UsedInBuild.refs);
|
||||
//if (csvSource != null) Debug.Log("e : " + csvSource.Length);
|
||||
}
|
||||
|
||||
if (IsFocusingDuplicate && csvSource == null)
|
||||
{
|
||||
csvSource = FR2_Ref.FromList(Duplicated.list);
|
||||
//if (csvSource != null) Debug.Log("f : " + csvSource.Length);
|
||||
}
|
||||
|
||||
FR2_Export.ExportCSV(csvSource);
|
||||
}
|
||||
|
||||
protected void OnReady()
|
||||
{
|
||||
OnSelectionChange();
|
||||
}
|
||||
|
||||
public override void OnSelectionChange()
|
||||
{
|
||||
Repaint();
|
||||
|
||||
isNoticeIgnore = false;
|
||||
if (!FR2_Cache.isReady)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (focusedWindow == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (SceneUsesDrawer == null)
|
||||
{
|
||||
InitIfNeeded();
|
||||
}
|
||||
|
||||
if (UsesDrawer == null)
|
||||
{
|
||||
InitIfNeeded();
|
||||
}
|
||||
|
||||
if (!lockSelection)
|
||||
{
|
||||
ids = FR2_Unity.Selection_AssetGUIDs;
|
||||
selection.Clear();
|
||||
|
||||
//ignore selection on asset when selected any object in scene
|
||||
if (Selection.gameObjects.Length > 0 && !FR2_Unity.IsInAsset(Selection.gameObjects[0]))
|
||||
{
|
||||
ids = new string[0];
|
||||
selection.AddRange(Selection.gameObjects);
|
||||
}
|
||||
else
|
||||
{
|
||||
selection.AddRange(ids);
|
||||
}
|
||||
|
||||
level = 0;
|
||||
|
||||
if (selection.isSelectingAsset)
|
||||
{
|
||||
UsesDrawer.Reset(ids, true);
|
||||
UsedByDrawer.Reset(ids, false);
|
||||
RefInScene.Reset(ids, this as IWindow);
|
||||
}
|
||||
else
|
||||
{
|
||||
RefSceneInScene.ResetSceneInScene(Selection.gameObjects);
|
||||
SceneToAssetDrawer.Reset(Selection.gameObjects, true, true);
|
||||
SceneUsesDrawer.ResetSceneUseSceneObjects(Selection.gameObjects);
|
||||
}
|
||||
|
||||
// auto disable enable scene / asset
|
||||
if (IsFocusingUses)
|
||||
{
|
||||
sp2.splits[0].visible = !selection.isSelectingAsset;
|
||||
sp2.splits[1].visible = true;
|
||||
sp2.CalculateWeight();
|
||||
}
|
||||
|
||||
if (IsFocusingUsedBy)
|
||||
{
|
||||
sp2.splits[0].visible = true;
|
||||
sp2.splits[1].visible = selection.isSelectingAsset;
|
||||
sp2.CalculateWeight();
|
||||
}
|
||||
}
|
||||
|
||||
if (IsFocusingGUIDs)
|
||||
{
|
||||
//objs = new Object[ids.Length];
|
||||
objs = new Dictionary<string, Object>();
|
||||
var objects = Selection.objects;
|
||||
for (var i = 0; i < objects.Length; i++)
|
||||
{
|
||||
var item = objects[i];
|
||||
|
||||
#if UNITY_2018_1_OR_NEWER
|
||||
{
|
||||
var guid = "";
|
||||
long fileid = -1;
|
||||
try
|
||||
{
|
||||
if (AssetDatabase.TryGetGUIDAndLocalFileIdentifier(item, out guid, out fileid))
|
||||
{
|
||||
objs.Add(guid + "/" + fileid, objects[i]);
|
||||
//Debug.Log("guid: " + guid + " fileID: " + fileid);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
#else
|
||||
{
|
||||
var path = AssetDatabase.GetAssetPath(item);
|
||||
if (string.IsNullOrEmpty(path)) continue;
|
||||
var guid = AssetDatabase.AssetPathToGUID(path);
|
||||
System.Reflection.PropertyInfo inspectorModeInfo =
|
||||
typeof(SerializedObject).GetProperty("inspectorMode", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
|
||||
SerializedObject serializedObject = new SerializedObject(item);
|
||||
inspectorModeInfo.SetValue(serializedObject, InspectorMode.Debug, null);
|
||||
|
||||
SerializedProperty localIdProp =
|
||||
serializedObject.FindProperty("m_LocalIdentfierInFile"); //note the misspelling!
|
||||
|
||||
var localId = localIdProp.longValue;
|
||||
if (localId <= 0)
|
||||
{
|
||||
localId = localIdProp.intValue;
|
||||
}
|
||||
if (localId <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(guid)) objs.Add(guid + "/" + localId, objects[i]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (IsFocusingUnused)
|
||||
{
|
||||
RefUnUse.ResetUnusedAsset();
|
||||
}
|
||||
|
||||
if (FR2_SceneCache.Api.Dirty && !Application.isPlaying)
|
||||
{
|
||||
FR2_SceneCache.Api.refreshCache(this);
|
||||
}
|
||||
|
||||
EditorApplication.delayCall -= Repaint;
|
||||
EditorApplication.delayCall += Repaint;
|
||||
}
|
||||
|
||||
|
||||
public FR2_SplitView sp1; // container : Selection / sp2 / Bookmark
|
||||
public FR2_SplitView sp2; // Scene / Assets
|
||||
|
||||
void InitPanes()
|
||||
{
|
||||
sp2 = new FR2_SplitView(this)
|
||||
{
|
||||
isHorz = false,
|
||||
splits = new List<FR2_SplitView.Info>()
|
||||
{
|
||||
new FR2_SplitView.Info(){ title = new GUIContent("Scene", FR2_Icon.Scene.image), draw = DrawScene },
|
||||
new FR2_SplitView.Info(){ title = new GUIContent("Assets", FR2_Icon.Asset.image), draw = DrawAsset },
|
||||
}
|
||||
};
|
||||
|
||||
sp2.CalculateWeight();
|
||||
|
||||
sp1 = new FR2_SplitView(this)
|
||||
{
|
||||
isHorz = true,
|
||||
splits = new List<FR2_SplitView.Info>()
|
||||
{
|
||||
new FR2_SplitView.Info(){ title = new GUIContent("Selection", FR2_Icon.Selection.image), weight = 0.4f, visible = false, draw = (rect) => selection.Draw(rect) },
|
||||
new FR2_SplitView.Info(){ draw = (r) =>
|
||||
{
|
||||
if (IsFocusingUses || IsFocusingUsedBy)
|
||||
{
|
||||
sp2.Draw(r);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawTools(r);
|
||||
}
|
||||
} },
|
||||
new FR2_SplitView.Info(){ title = new GUIContent("Details", FR2_Icon.Details.image), weight = 0.4f, visible = true, draw = (rect) =>
|
||||
{
|
||||
var assetDrawer = GetAssetDrawer();
|
||||
if (assetDrawer != null)
|
||||
{
|
||||
assetDrawer.DrawDetails(rect);
|
||||
}
|
||||
}},
|
||||
new FR2_SplitView.Info(){ title = new GUIContent("Bookmark", FR2_Icon.Favorite.image), weight = 0.4f, visible = false, draw = (rect) => bookmark.Draw(rect) }
|
||||
}
|
||||
};
|
||||
|
||||
sp1.CalculateWeight();
|
||||
}
|
||||
|
||||
private FR2_TabView tabs;
|
||||
private FR2_TabView bottomTabs;
|
||||
private FR2_SearchView search;
|
||||
|
||||
void DrawScene(Rect rect)
|
||||
{
|
||||
FR2_RefDrawer drawer = IsFocusingUses
|
||||
? (selection.isSelectingAsset ? null : SceneUsesDrawer)
|
||||
: (selection.isSelectingAsset ? RefInScene : RefSceneInScene);
|
||||
if (drawer == null) return;
|
||||
|
||||
if (!FR2_SceneCache.ready)
|
||||
{
|
||||
var rr = rect;
|
||||
rr.height = 16f;
|
||||
|
||||
int cur = FR2_SceneCache.Api.current, total = FR2_SceneCache.Api.total;
|
||||
EditorGUI.ProgressBar(rr, cur * 1f / total, string.Format("{0} / {1}", cur, total));
|
||||
WillRepaint = true;
|
||||
return;
|
||||
}
|
||||
|
||||
drawer.Draw(rect);
|
||||
|
||||
var refreshRect = new Rect(rect.xMax - 16f, rect.yMin - 14f, 18f, 18f);
|
||||
if (GUI2.ColorIconButton(refreshRect, FR2_Icon.Refresh.image,
|
||||
FR2_SceneCache.Api.Dirty ? (Color?)GUI2.lightRed : null))
|
||||
{
|
||||
FR2_SceneCache.Api.refreshCache(drawer.window);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
FR2_RefDrawer GetAssetDrawer()
|
||||
{
|
||||
if (IsFocusingUses)
|
||||
{
|
||||
return selection.isSelectingAsset ? UsesDrawer : SceneToAssetDrawer;
|
||||
}
|
||||
|
||||
if (IsFocusingUsedBy)
|
||||
{
|
||||
return selection.isSelectingAsset ? UsedByDrawer : null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
void DrawAsset(Rect rect)
|
||||
{
|
||||
var drawer = GetAssetDrawer();
|
||||
if (drawer != null) drawer.Draw(rect);
|
||||
}
|
||||
|
||||
void DrawSearch()
|
||||
{
|
||||
if (search == null) search = new FR2_SearchView();
|
||||
search.DrawLayout();
|
||||
}
|
||||
|
||||
protected override void OnGUI()
|
||||
{
|
||||
OnGUI2();
|
||||
}
|
||||
|
||||
protected bool CheckDrawImport()
|
||||
{
|
||||
if (EditorApplication.isCompiling)
|
||||
{
|
||||
EditorGUILayout.HelpBox("Compiling scripts, please wait!", MessageType.Warning);
|
||||
Repaint();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (EditorApplication.isUpdating)
|
||||
{
|
||||
EditorGUILayout.HelpBox("Importing assets, please wait!", MessageType.Warning);
|
||||
Repaint();
|
||||
return false;
|
||||
}
|
||||
|
||||
InitIfNeeded();
|
||||
|
||||
if (EditorSettings.serializationMode != SerializationMode.ForceText)
|
||||
{
|
||||
EditorGUILayout.HelpBox("FR2 requires serialization mode set to FORCE TEXT!", MessageType.Warning);
|
||||
if (GUILayout.Button("FORCE TEXT"))
|
||||
{
|
||||
EditorSettings.serializationMode = SerializationMode.ForceText;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (FR2_Cache.hasCache && !FR2_Cache.CheckSameVersion())
|
||||
{
|
||||
EditorGUILayout.HelpBox("Incompatible cache version found!!!\nFR2 will need a full refresh and this may take quite some time to finish but you would be able to work normally while the scan works in background!",
|
||||
MessageType.Warning);
|
||||
FR2_Cache.DrawPriorityGUI();
|
||||
if (GUILayout.Button("Scan project"))
|
||||
{
|
||||
FR2_Cache.DeleteCache();
|
||||
FR2_Cache.CreateCache();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!FR2_Cache.isReady)
|
||||
{
|
||||
if (!FR2_Cache.hasCache)
|
||||
{
|
||||
EditorGUILayout.HelpBox(
|
||||
"FR2 cache not found!\nFirst scan may takes quite some time to finish but you would be able to work normally while the scan works in background...",
|
||||
MessageType.Warning);
|
||||
|
||||
FR2_Cache.DrawPriorityGUI();
|
||||
|
||||
if (GUILayout.Button("Scan project"))
|
||||
{
|
||||
FR2_Cache.CreateCache();
|
||||
Repaint();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
FR2_Cache.DrawPriorityGUI();
|
||||
}
|
||||
|
||||
if (!DrawEnable())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
FR2_Cache api = FR2_Cache.Api;
|
||||
string text = "Refreshing ... " + (int)(api.progress * api.workCount) + " / " + api.workCount;
|
||||
Rect rect = GUILayoutUtility.GetRect(1f, Screen.width, 18f, 18f);
|
||||
EditorGUI.ProgressBar(rect, api.progress, text);
|
||||
Repaint();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!DrawEnable())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected bool IsFocusingUses { get { return tabs != null && tabs.current == 0; } }
|
||||
protected bool IsFocusingUsedBy { get { return tabs != null && tabs.current == 1; } }
|
||||
protected bool IsFocusingDuplicate { get { return tabs != null && tabs.current == 2; } }
|
||||
protected bool IsFocusingGUIDs { get { return tabs != null && tabs.current == 3; } }
|
||||
protected bool IsFocusingUnused { get { return tabs != null && tabs.current == 4; } }
|
||||
protected bool IsFocusingUsedInBuild { get { return tabs != null && tabs.current == 5; } }
|
||||
|
||||
void OnTabChange()
|
||||
{
|
||||
if (deleteUnused != null) deleteUnused.hasConfirm = false;
|
||||
if (UsedInBuild != null) UsedInBuild.SetDirty();
|
||||
}
|
||||
|
||||
void InitTabs()
|
||||
{
|
||||
tabs = FR2_TabView.Create(this, false,
|
||||
"Uses", "Used By", "Duplicate", "GUIDs", "Unused Assets", "Uses in Build"
|
||||
);
|
||||
tabs.onTabChange = OnTabChange;
|
||||
tabs.callback = new DrawCallback()
|
||||
{
|
||||
BeforeDraw = () =>
|
||||
{
|
||||
if (GUI2.ToolbarToggle(ref selection.isLock,
|
||||
selection.isLock ? FR2_Icon.Lock.image : FR2_Icon.Unlock.image,
|
||||
new Vector2(-1, 2), "Lock Selection"))
|
||||
{
|
||||
WillRepaint = true;
|
||||
}
|
||||
},
|
||||
|
||||
AfterDraw = () =>
|
||||
{
|
||||
//GUILayout.Space(16f);
|
||||
|
||||
if (GUI2.ToolbarToggle(ref sp1.isHorz, FR2_Icon.Panel.image, Vector2.zero, "Layout"))
|
||||
{
|
||||
sp1.CalculateWeight();
|
||||
Repaint();
|
||||
}
|
||||
|
||||
if (GUI2.ToolbarToggle(ref sp1.splits[0].visible, FR2_Icon.Selection.image, Vector2.zero, "Show / Hide Selection"))
|
||||
{
|
||||
sp1.CalculateWeight();
|
||||
Repaint();
|
||||
}
|
||||
|
||||
if (GUI2.ToolbarToggle(ref sp2.splits[0].visible, FR2_Icon.Scene.image, Vector2.zero, "Show / Hide Scene References"))
|
||||
{
|
||||
sp2.CalculateWeight();
|
||||
Repaint();
|
||||
}
|
||||
|
||||
if (GUI2.ToolbarToggle(ref sp2.splits[1].visible, FR2_Icon.Asset.image, Vector2.zero, "Show / Hide Asset References"))
|
||||
{
|
||||
sp2.CalculateWeight();
|
||||
Repaint();
|
||||
}
|
||||
|
||||
if (GUI2.ToolbarToggle(ref sp1.splits[2].visible, FR2_Icon.Details.image, Vector2.zero, "Show / Hide Details"))
|
||||
{
|
||||
sp1.CalculateWeight();
|
||||
Repaint();
|
||||
}
|
||||
|
||||
if (GUI2.ToolbarToggle(ref sp1.splits[3].visible, FR2_Icon.Favorite.image, Vector2.zero, "Show / Hide Bookmarks"))
|
||||
{
|
||||
sp1.CalculateWeight();
|
||||
Repaint();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected bool DrawHeader()
|
||||
{
|
||||
if (tabs == null) InitTabs();
|
||||
if (bottomTabs == null)
|
||||
{
|
||||
bottomTabs = FR2_TabView.Create(this, true,
|
||||
new GUIContent(FR2_Icon.Setting.image, "Settings"),
|
||||
new GUIContent(FR2_Icon.Ignore.image, "Ignore"),
|
||||
new GUIContent(FR2_Icon.Filter.image, "Filter by Type")
|
||||
);
|
||||
bottomTabs.current = -1;
|
||||
}
|
||||
|
||||
tabs.DrawLayout();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
protected bool DrawFooter()
|
||||
{
|
||||
GUILayout.BeginHorizontal(EditorStyles.toolbar);
|
||||
{
|
||||
bottomTabs.DrawLayout();
|
||||
GUILayout.FlexibleSpace();
|
||||
DrawAssetViewSettings();
|
||||
GUILayout.FlexibleSpace();
|
||||
DrawViewModes();
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
return false;
|
||||
}
|
||||
|
||||
void DrawAssetViewSettings()
|
||||
{
|
||||
var isDisable = !sp2.splits[1].visible;
|
||||
EditorGUI.BeginDisabledGroup(isDisable);
|
||||
{
|
||||
GUI2.ToolbarToggle(ref FR2_Setting.s.displayAssetBundleName, FR2_Icon.AssetBundle.image, Vector2.zero, "Show / Hide Assetbundle Names");
|
||||
#if UNITY_2017_1_OR_NEWER
|
||||
GUI2.ToolbarToggle(ref FR2_Setting.s.displayAtlasName, FR2_Icon.Atlas.image, Vector2.zero, "Show / Hide Atlas packing tags");
|
||||
#endif
|
||||
GUI2.ToolbarToggle(ref FR2_Setting.s.showUsedByClassed, FR2_Icon.Material.image, Vector2.zero, "Show / Hide usage icons");
|
||||
GUI2.ToolbarToggle(ref FR2_Setting.s.displayFileSize, FR2_Icon.Filesize.image, Vector2.zero, "Show / Hide file size");
|
||||
|
||||
if (GUILayout.Button("CSV", EditorStyles.toolbarButton))
|
||||
{
|
||||
OnCSVClick();
|
||||
}
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
|
||||
void DrawViewModes()
|
||||
{
|
||||
var gMode = FR2_Setting.GroupMode;
|
||||
if (GUI2.EnumPopup(ref gMode, new GUIContent(FR2_Icon.Group.image, "Group by"), EditorStyles.toolbarPopup, GUILayout.Width(80f)))
|
||||
{
|
||||
FR2_Setting.GroupMode = gMode;
|
||||
markDirty();
|
||||
}
|
||||
|
||||
GUILayout.Space(16f);
|
||||
|
||||
var sMode = FR2_Setting.SortMode;
|
||||
if (GUI2.EnumPopup(ref sMode, new GUIContent(FR2_Icon.Sort.image, "Sort by"), EditorStyles.toolbarPopup, GUILayout.Width(50f)))
|
||||
{
|
||||
FR2_Setting.SortMode = sMode;
|
||||
RefreshSort();
|
||||
}
|
||||
}
|
||||
|
||||
protected void OnGUI2()
|
||||
{
|
||||
if (!CheckDrawImport())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (sp1 == null) InitPanes();
|
||||
|
||||
DrawHeader();
|
||||
sp1.DrawLayout();
|
||||
DrawSettings();
|
||||
DrawFooter();
|
||||
|
||||
if (WillRepaint)
|
||||
{
|
||||
Repaint();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private FR2_DeleteButton deleteUnused;
|
||||
|
||||
|
||||
|
||||
void DrawTools(Rect rect)
|
||||
{
|
||||
if (IsFocusingDuplicate)
|
||||
{
|
||||
rect = GUI2.Padding(rect, 2f, 2f);
|
||||
|
||||
GUILayout.BeginArea(rect);
|
||||
Duplicated.DrawLayout();
|
||||
GUILayout.EndArea();
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsFocusingUnused)
|
||||
{
|
||||
rect = GUI2.Padding(rect, 2f, 2f);
|
||||
|
||||
if ((RefUnUse.refs != null && RefUnUse.refs.Count == 0))
|
||||
{
|
||||
GUILayout.BeginArea(rect);
|
||||
{
|
||||
EditorGUILayout.HelpBox("Wow! So clean!?", MessageType.Info);
|
||||
EditorGUILayout.HelpBox("Your project does not has have any unused assets, or have you just hit DELETE ALL?", MessageType.Info);
|
||||
EditorGUILayout.HelpBox("Your backups are placed at Library/FR2/ just in case you want your assets back!", MessageType.Info);
|
||||
}
|
||||
GUILayout.EndArea();
|
||||
}
|
||||
else
|
||||
{
|
||||
rect.yMax -= 40f;
|
||||
GUILayout.BeginArea(rect);
|
||||
RefUnUse.DrawLayout();
|
||||
GUILayout.EndArea();
|
||||
|
||||
var toolRect = rect;
|
||||
toolRect.yMin = toolRect.yMax;
|
||||
|
||||
var lineRect = toolRect;
|
||||
lineRect.height = 1f;
|
||||
|
||||
GUI2.Rect(lineRect, Color.black, 0.5f);
|
||||
|
||||
toolRect.xMin += 2f;
|
||||
toolRect.xMax -= 2f;
|
||||
toolRect.height = 40f;
|
||||
|
||||
if (deleteUnused == null)
|
||||
{
|
||||
deleteUnused = new FR2_DeleteButton()
|
||||
{
|
||||
warningMessage = "It's absolutely safe to delete them all!\nA backup (.unitypackage) will be created so you can import it back later!",
|
||||
deleteLabel = new GUIContent("DELETE ASSETS", FR2_Icon.Delete.image),
|
||||
confirmMessage = "Create backup at Library/FR2/"
|
||||
};
|
||||
}
|
||||
|
||||
GUILayout.BeginArea(toolRect);
|
||||
deleteUnused.Draw(() => { FR2_Unity.BackupAndDeleteAssets(RefUnUse.source); });
|
||||
GUILayout.EndArea();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsFocusingUsedInBuild)
|
||||
{
|
||||
UsedInBuild.Draw(rect);
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsFocusingGUIDs)
|
||||
{
|
||||
rect = GUI2.Padding(rect, 2f, 2f);
|
||||
|
||||
GUILayout.BeginArea(rect);
|
||||
DrawGUIDs();
|
||||
GUILayout.EndArea();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void DrawSettings()
|
||||
{
|
||||
if (bottomTabs.current == -1) return;
|
||||
|
||||
GUILayout.BeginVertical(GUILayout.Height(100f));
|
||||
{
|
||||
GUILayout.Space(2f);
|
||||
switch (bottomTabs.current)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
FR2_Setting.s.DrawSettings();
|
||||
break;
|
||||
}
|
||||
|
||||
case 1:
|
||||
{
|
||||
if (AssetType.DrawIgnoreFolder())
|
||||
{
|
||||
markDirty();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
if (AssetType.DrawSearchFilter())
|
||||
{
|
||||
markDirty();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
GUILayout.EndVertical();
|
||||
|
||||
var rect = GUILayoutUtility.GetLastRect();
|
||||
rect.height = 1f;
|
||||
GUI2.Rect(rect, Color.black, 0.4f);
|
||||
}
|
||||
|
||||
protected void markDirty()
|
||||
{
|
||||
UsedByDrawer.SetDirty();
|
||||
UsesDrawer.SetDirty();
|
||||
Duplicated.SetDirty();
|
||||
SceneToAssetDrawer.SetDirty();
|
||||
RefUnUse.SetDirty();
|
||||
|
||||
RefInScene.SetDirty();
|
||||
RefSceneInScene.SetDirty();
|
||||
SceneUsesDrawer.SetDirty();
|
||||
UsedInBuild.SetDirty();
|
||||
WillRepaint = true;
|
||||
}
|
||||
|
||||
protected void RefreshSort()
|
||||
{
|
||||
UsedByDrawer.RefreshSort();
|
||||
UsesDrawer.RefreshSort();
|
||||
Duplicated.RefreshSort();
|
||||
SceneToAssetDrawer.RefreshSort();
|
||||
RefUnUse.RefreshSort();
|
||||
|
||||
UsedInBuild.RefreshSort();
|
||||
}
|
||||
// public bool isExcludeByFilter;
|
||||
|
||||
protected bool checkNoticeFilter()
|
||||
{
|
||||
var rsl = false;
|
||||
|
||||
if (IsFocusingUsedBy && !rsl)
|
||||
{
|
||||
rsl = UsedByDrawer.isExclueAnyItem();
|
||||
}
|
||||
|
||||
if (IsFocusingDuplicate)
|
||||
{
|
||||
return Duplicated.isExclueAnyItem();
|
||||
}
|
||||
|
||||
if (IsFocusingUses && rsl == false)
|
||||
{
|
||||
rsl = UsesDrawer.isExclueAnyItem();
|
||||
}
|
||||
|
||||
//tab use by
|
||||
return rsl;
|
||||
}
|
||||
|
||||
protected bool checkNoticeIgnore()
|
||||
{
|
||||
bool rsl = isNoticeIgnore;
|
||||
return rsl;
|
||||
}
|
||||
|
||||
|
||||
private Dictionary<string, Object> objs;
|
||||
private string[] ids;
|
||||
|
||||
private void DrawGUIDs()
|
||||
{
|
||||
GUILayout.Label("GUID to Object", EditorStyles.boldLabel);
|
||||
GUILayout.BeginHorizontal();
|
||||
{
|
||||
string guid = EditorGUILayout.TextField(tempGUID ?? string.Empty);
|
||||
EditorGUILayout.ObjectField(tempObject, typeof(Object), false, GUILayout.Width(120f));
|
||||
|
||||
if (GUILayout.Button("Paste", EditorStyles.miniButton, GUILayout.Width(70f)))
|
||||
{
|
||||
guid = EditorGUIUtility.systemCopyBuffer;
|
||||
}
|
||||
|
||||
if (guid != tempGUID && !string.IsNullOrEmpty(guid))
|
||||
{
|
||||
tempGUID = guid;
|
||||
|
||||
tempObject = FR2_Unity.LoadAssetAtPath<Object>
|
||||
(
|
||||
AssetDatabase.GUIDToAssetPath(tempGUID)
|
||||
);
|
||||
}
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.Space(10f);
|
||||
if (objs == null)// || ids == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//GUILayout.Label("Selection", EditorStyles.boldLabel);
|
||||
//if (ids.Length == objs.Count)
|
||||
{
|
||||
scrollPos = GUILayout.BeginScrollView(scrollPos);
|
||||
{
|
||||
|
||||
|
||||
//for (var i = 0; i < ids.Length; i++)
|
||||
foreach (var item in objs)
|
||||
{
|
||||
//if (!objs.ContainsKey(ids[i])) continue;
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
{
|
||||
//var obj = objs[ids[i]];
|
||||
var obj = item.Value;
|
||||
|
||||
EditorGUILayout.ObjectField(obj, typeof(Object), false, GUILayout.Width(150));
|
||||
string idi = item.Key;
|
||||
GUILayout.TextField(idi, GUILayout.Width(240f));
|
||||
if (GUILayout.Button("Copy", EditorStyles.miniButton, GUILayout.Width(50f)))
|
||||
{
|
||||
tempObject = obj;
|
||||
//EditorGUIUtility.systemCopyBuffer = tempGUID = item.Key;
|
||||
tempGUID = item.Key;
|
||||
|
||||
//string guid = "";
|
||||
//long file = -1;
|
||||
//if (AssetDatabase.TryGetGUIDAndLocalFileIdentifier(obj, out guid, out file))
|
||||
//{
|
||||
// EditorGUIUtility.systemCopyBuffer = tempGUID = idi + "/" + file;
|
||||
|
||||
// if (!string.IsNullOrEmpty(tempGUID))
|
||||
// {
|
||||
// tempObject = obj;
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
GUILayout.EndScrollView();
|
||||
}
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("Merge Selection To"))
|
||||
{
|
||||
FR2_Export.MergeDuplicate(tempGUID);
|
||||
}
|
||||
|
||||
EditorGUILayout.ObjectField(tempObject, typeof(Object), false, GUILayout.Width(120f));
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/FindReference2/Editor/Script/FR2_WindowAll.cs.meta
Normal file
11
Assets/FindReference2/Editor/Script/FR2_WindowAll.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 59de5c9b86a054d2bba67e3b35d00a6d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
100
Assets/FindReference2/Editor/Script/FR2_WindowBase.cs
Normal file
100
Assets/FindReference2/Editor/Script/FR2_WindowBase.cs
Normal file
@@ -0,0 +1,100 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace vietlabs.fr2
|
||||
{
|
||||
public interface IWindow
|
||||
{
|
||||
bool WillRepaint { get; set; }
|
||||
void Repaint();
|
||||
void OnSelectionChange();
|
||||
}
|
||||
|
||||
internal interface IRefDraw
|
||||
{
|
||||
IWindow window { get; }
|
||||
int ElementCount();
|
||||
bool DrawLayout();
|
||||
bool Draw(Rect rect);
|
||||
}
|
||||
|
||||
public abstract class FR2_WindowBase : EditorWindow, IWindow
|
||||
{
|
||||
public bool WillRepaint { get; set; }
|
||||
protected bool showFilter, showIgnore;
|
||||
|
||||
//[NonSerialized] protected bool lockSelection;
|
||||
//[NonSerialized] internal List<FR2_Asset> Selected;
|
||||
|
||||
public static bool isNoticeIgnore;
|
||||
|
||||
public void AddItemsToMenu(GenericMenu menu)
|
||||
{
|
||||
FR2_Cache api = FR2_Cache.Api;
|
||||
if (api == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
menu.AddDisabledItem(new GUIContent("FR2 - v2.5.2"));
|
||||
menu.AddSeparator(string.Empty);
|
||||
|
||||
menu.AddItem(new GUIContent("Enable"), !api.disabled, () => { api.disabled = !api.disabled; });
|
||||
menu.AddItem(new GUIContent("Refresh"), false, () =>
|
||||
{
|
||||
//FR2_Asset.lastRefreshTS = Time.realtimeSinceStartup;
|
||||
Resources.UnloadUnusedAssets();
|
||||
EditorUtility.UnloadUnusedAssetsImmediate();
|
||||
FR2_Cache.Api.Check4Changes(true);
|
||||
FR2_SceneCache.Api.SetDirty();
|
||||
});
|
||||
|
||||
#if FR2_DEV
|
||||
menu.AddItem(new GUIContent("Refresh Usage"), false, () => FR2_Cache.Api.Check4Usage());
|
||||
menu.AddItem(new GUIContent("Refresh Selected"), false, ()=> FR2_Cache.Api.RefreshSelection());
|
||||
menu.AddItem(new GUIContent("Clear Cache"), false, () => FR2_Cache.Api.Clear());
|
||||
#endif
|
||||
}
|
||||
|
||||
public abstract void OnSelectionChange();
|
||||
protected abstract void OnGUI();
|
||||
|
||||
#if UNITY_2018_OR_NEWER
|
||||
protected void OnSceneChanged(Scene arg0, Scene arg1)
|
||||
{
|
||||
if (IsFocusingFindInScene || IsFocusingSceneToAsset || IsFocusingSceneInScene)
|
||||
{
|
||||
OnSelectionChange();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
protected bool DrawEnable()
|
||||
{
|
||||
FR2_Cache api = FR2_Cache.Api;
|
||||
if (api == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool v = api.disabled;
|
||||
if (v)
|
||||
{
|
||||
EditorGUILayout.HelpBox("Find References 2 is disabled!", MessageType.Warning);
|
||||
|
||||
if (GUILayout.Button("Enable"))
|
||||
{
|
||||
api.disabled = !api.disabled;
|
||||
Repaint();
|
||||
}
|
||||
|
||||
return !api.disabled;
|
||||
}
|
||||
|
||||
return !api.disabled;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
11
Assets/FindReference2/Editor/Script/FR2_WindowBase.cs.meta
Normal file
11
Assets/FindReference2/Editor/Script/FR2_WindowBase.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 846de4aca6426f74c8cacda9de44511f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/FindReference2/Editor/Script/UI.meta
Normal file
8
Assets/FindReference2/Editor/Script/UI.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ecd25f71eac2146a58139581a59c8ad1
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
41
Assets/FindReference2/Editor/Script/UI/FR2_DeleteButton.cs
Normal file
41
Assets/FindReference2/Editor/Script/UI/FR2_DeleteButton.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using vietlabs.fr2;
|
||||
|
||||
public class FR2_DeleteButton
|
||||
{
|
||||
public string warningMessage;
|
||||
public string confirmMessage;
|
||||
public GUIContent deleteLabel;
|
||||
public bool hasConfirm;
|
||||
|
||||
public bool Draw(Action onConfirmDelete)
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.HelpBox(warningMessage, MessageType.Warning);
|
||||
GUILayout.BeginVertical();
|
||||
{
|
||||
GUILayout.Space(2f);
|
||||
hasConfirm = GUILayout.Toggle(hasConfirm, confirmMessage);
|
||||
EditorGUI.BeginDisabledGroup(!hasConfirm);
|
||||
{
|
||||
GUI2.BackgroundColor(() =>
|
||||
{
|
||||
if (GUILayout.Button(deleteLabel, EditorStyles.miniButton))
|
||||
{
|
||||
hasConfirm = false;
|
||||
onConfirmDelete();
|
||||
GUIUtility.ExitGUI();
|
||||
}
|
||||
}, GUI2.darkRed, 0.8f);
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6f0672714ae60486a8fa4a6c0bf5a614
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
68
Assets/FindReference2/Editor/Script/UI/FR2_Icon.cs
Normal file
68
Assets/FindReference2/Editor/Script/UI/FR2_Icon.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
public static class FR2_Icon
|
||||
{
|
||||
public static GUIContent Lock { get { return TryGet("LockIcon-On"); } }
|
||||
public static GUIContent Unlock { get { return TryGet("LockIcon"); } }
|
||||
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
public static GUIContent Refresh { get { return TryGet("d_Refresh@2x"); } }
|
||||
#else
|
||||
public static GUIContent Refresh { get { return TryGet("LookDevResetEnv"); } }
|
||||
#endif
|
||||
|
||||
public static GUIContent Selection { get { return TryGet("d_RectTransformBlueprint"); } }
|
||||
public static GUIContent Details { get { return TryGet("d_UnityEditor.SceneHierarchyWindow"); } }
|
||||
public static GUIContent Favorite { get { return TryGet("d_Favorite"); } }
|
||||
public static GUIContent Setting { get { return TryGet("d_SettingsIcon"); } }
|
||||
public static GUIContent Ignore { get { return TryGet("ShurikenCheckMarkMixed"); } }
|
||||
public static GUIContent Plus
|
||||
{
|
||||
get { return TryGet("ShurikenPlus"); }
|
||||
}
|
||||
|
||||
public static GUIContent Visibility { get { return TryGet("ClothInspector.ViewValue"); } }
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
public static GUIContent Panel { get { return TryGet("VerticalSplit"); } }
|
||||
#else
|
||||
public static GUIContent Panel { get { return TryGet("d_LookDevSideBySide"); } }
|
||||
#endif
|
||||
public static GUIContent Layout { get { return TryGet("FreeformLayoutGroup Icon"); } }
|
||||
public static GUIContent Sort { get { return TryGet("AlphabeticalSorting"); } } //d_DefaultSorting
|
||||
|
||||
#if UNITY_2019_3_OR_NEWER
|
||||
public static GUIContent Filter { get { return TryGet("d_ToggleUVOverlay@2x"); } }
|
||||
#else
|
||||
public static GUIContent Filter { get { return TryGet("LookDevSplit"); } }
|
||||
#endif
|
||||
|
||||
public static GUIContent Group { get { return TryGet("EditCollider"); } }
|
||||
public static GUIContent Delete { get { return TryGet("d_TreeEditor.Trash"); } }
|
||||
public static GUIContent Split { get { return TryGet("VerticalSplit"); } }
|
||||
public static GUIContent Close { get { return TryGet("LookDevClose"); } }
|
||||
public static GUIContent Prefab { get { return TryGet("d_Prefab Icon"); } }
|
||||
public static GUIContent Asset { get { return TryGet("Folder Icon"); } }
|
||||
public static GUIContent Filesize { get { return TryGet("SavePassive"); } }
|
||||
public static GUIContent AssetBundle { get { return TryGet("CloudConnect"); } }
|
||||
public static GUIContent Script { get { return TryGet("dll Script Icon"); } }
|
||||
public static GUIContent Material { get { return TryGet("d_TreeEditor.Material"); } }
|
||||
public static GUIContent Scene { get { return TryGet("SceneAsset Icon"); } }
|
||||
#if UNITY_2017_1_OR_NEWER
|
||||
public static GUIContent Atlas { get { return TryGet("SpriteAtlas Icon"); } }
|
||||
#endif
|
||||
public static GUIContent Folder { get { return TryGet("Project"); } }
|
||||
public static GUIContent Hierarchy { get { return TryGet("UnityEditor.HierarchyWindow"); } }
|
||||
|
||||
private static readonly Dictionary<string, GUIContent> _cache = new Dictionary<string, GUIContent>();
|
||||
static GUIContent TryGet(string id)
|
||||
{
|
||||
GUIContent result;
|
||||
if (_cache.TryGetValue(id, out result)) return result ?? GUIContent.none;
|
||||
var icon = EditorGUIUtility.IconContent(id) ?? new GUIContent(Texture2D.whiteTexture);
|
||||
_cache.Add(id, icon);
|
||||
return icon;
|
||||
}
|
||||
}
|
||||
11
Assets/FindReference2/Editor/Script/UI/FR2_Icon.cs.meta
Normal file
11
Assets/FindReference2/Editor/Script/UI/FR2_Icon.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cac8d1a32d8a04fa3a1fe89aed0f5e56
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
62
Assets/FindReference2/Editor/Script/UI/FR2_SearchView.cs
Normal file
62
Assets/FindReference2/Editor/Script/UI/FR2_SearchView.cs
Normal file
@@ -0,0 +1,62 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace vietlabs.fr2
|
||||
{
|
||||
public class FR2_SearchView
|
||||
{
|
||||
private bool caseSensitive;
|
||||
private string searchTerm = string.Empty;
|
||||
|
||||
public static GUIStyle toolbarSearchField;
|
||||
public static GUIStyle toolbarSearchFieldCancelButton;
|
||||
public static GUIStyle toolbarSearchFieldCancelButtonEmpty;
|
||||
|
||||
public static void InitSearchStyle()
|
||||
{
|
||||
toolbarSearchField = "ToolbarSeachTextFieldPopup";
|
||||
toolbarSearchFieldCancelButton = "ToolbarSeachCancelButton";
|
||||
toolbarSearchFieldCancelButtonEmpty = "ToolbarSeachCancelButtonEmpty";
|
||||
}
|
||||
|
||||
public bool DrawLayout()
|
||||
{
|
||||
bool dirty = false;
|
||||
|
||||
if (toolbarSearchField == null)
|
||||
{
|
||||
InitSearchStyle();
|
||||
}
|
||||
|
||||
GUILayout.BeginHorizontal(EditorStyles.toolbar);
|
||||
{
|
||||
bool v = GUILayout.Toggle(caseSensitive, "Aa", EditorStyles.toolbarButton, GUILayout.Width(24f));
|
||||
if (v != caseSensitive)
|
||||
{
|
||||
caseSensitive = v;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
GUILayout.Space(2f);
|
||||
string value = GUILayout.TextField(searchTerm, toolbarSearchField, GUILayout.Width(140f));
|
||||
if (searchTerm != value)
|
||||
{
|
||||
searchTerm = value;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
GUIStyle style = string.IsNullOrEmpty(searchTerm)
|
||||
? toolbarSearchFieldCancelButtonEmpty
|
||||
: toolbarSearchFieldCancelButton;
|
||||
if (GUILayout.Button("Cancel", style))
|
||||
{
|
||||
searchTerm = string.Empty;
|
||||
dirty = true;
|
||||
}
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
return dirty;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c5c27d8e961e4de6ab683161c6d53584
|
||||
timeCreated: 1579769248
|
||||
252
Assets/FindReference2/Editor/Script/UI/FR2_SplitView.cs
Normal file
252
Assets/FindReference2/Editor/Script/UI/FR2_SplitView.cs
Normal file
@@ -0,0 +1,252 @@
|
||||
//#define FR2_DEBUG
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEngine.Experimental.Rendering;
|
||||
|
||||
namespace vietlabs.fr2
|
||||
{
|
||||
|
||||
public class FR2_SplitView
|
||||
{
|
||||
private const float SPLIT_SIZE = 2f;
|
||||
|
||||
|
||||
private IWindow window;
|
||||
private bool dirty;
|
||||
|
||||
public FR2_SplitView(IWindow w)
|
||||
{
|
||||
this.window = w;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class Info
|
||||
{
|
||||
public GUIContent title;
|
||||
|
||||
#if FR2_DEBUG
|
||||
public Color color;
|
||||
#endif
|
||||
|
||||
public Rect rect;
|
||||
public float normWeight;
|
||||
public int stIndex;
|
||||
|
||||
public bool visible = true;
|
||||
public float weight = 1f;
|
||||
public Action<Rect> draw;
|
||||
|
||||
public void DoDraw()
|
||||
{
|
||||
#if FR2_DEBUG
|
||||
GUI2.Rect(rect, Color.white, 0.1f);
|
||||
#endif
|
||||
var drawRect = rect;
|
||||
if (title != null)
|
||||
{
|
||||
var titleRect = new Rect(rect.x, rect.y, rect.width, 16f);
|
||||
GUI2.Rect(titleRect, Color.black, 0.2f);
|
||||
|
||||
titleRect.xMin += 4f;
|
||||
GUI.Label(titleRect, title, EditorStyles.boldLabel);
|
||||
drawRect.yMin += 16f;
|
||||
}
|
||||
|
||||
draw(drawRect);
|
||||
}
|
||||
}
|
||||
|
||||
public bool isHorz;
|
||||
public List<Info> splits = new List<Info>();
|
||||
|
||||
public bool isVisible
|
||||
{
|
||||
get { return _visibleCount > 0; }
|
||||
}
|
||||
|
||||
private int _visibleCount;
|
||||
private Rect _rect;
|
||||
|
||||
public void CalculateWeight()
|
||||
{
|
||||
_visibleCount = 0;
|
||||
var _totalWeight = 0f;
|
||||
|
||||
for (var i = 0; i < splits.Count; i++)
|
||||
{
|
||||
var info = splits[i];
|
||||
if (!info.visible) continue;
|
||||
|
||||
info.stIndex = _visibleCount;
|
||||
_totalWeight += info.weight;
|
||||
|
||||
_visibleCount++;
|
||||
}
|
||||
|
||||
if (_visibleCount == 0 || _totalWeight == 0)
|
||||
{
|
||||
//Debug.LogWarning("Nothing visible!");
|
||||
return;
|
||||
}
|
||||
|
||||
var cWeight = 0f;
|
||||
for (var i = 0; i < splits.Count; i++)
|
||||
{
|
||||
var info = splits[i];
|
||||
if (!info.visible) continue;
|
||||
|
||||
cWeight += info.weight;
|
||||
info.normWeight = info.weight / _totalWeight;
|
||||
}
|
||||
}
|
||||
|
||||
public void Draw(Rect rect)
|
||||
{
|
||||
if (rect.width > 0 || rect.height > 0)
|
||||
{
|
||||
_rect = rect;
|
||||
}
|
||||
|
||||
if (dirty)
|
||||
{
|
||||
dirty = false;
|
||||
CalculateWeight();
|
||||
}
|
||||
|
||||
var sz = (_visibleCount - 1) * SPLIT_SIZE;
|
||||
var dx = _rect.x;
|
||||
var dy = _rect.y;
|
||||
|
||||
for (var i = 0; i < splits.Count; i++)
|
||||
{
|
||||
var info = splits[i];
|
||||
if (!info.visible) continue;
|
||||
|
||||
var rr = new Rect
|
||||
(
|
||||
dx, dy,
|
||||
isHorz ? (_rect.width - sz) * info.normWeight : _rect.width,
|
||||
isHorz ? _rect.height : (_rect.height - sz) * info.normWeight
|
||||
);
|
||||
|
||||
if (rr.width > 0 && rr.height > 0)
|
||||
{
|
||||
info.rect = rr;
|
||||
}
|
||||
|
||||
if (info.draw != null) info.DoDraw();
|
||||
|
||||
if (info.stIndex < _visibleCount - 1)
|
||||
{
|
||||
DrawSpliter(i, isHorz ? info.rect.xMax : info.rect.yMax);
|
||||
}
|
||||
|
||||
if (isHorz)
|
||||
{
|
||||
dx += info.rect.width + SPLIT_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
dy += info.rect.height + SPLIT_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void DrawLayout()
|
||||
{
|
||||
var rect = StartLayout(isHorz);
|
||||
{
|
||||
Draw(rect);
|
||||
}
|
||||
EndLayout(isHorz);
|
||||
}
|
||||
|
||||
private int resizeIndex = -1;
|
||||
|
||||
|
||||
void RefreshSpliterPos(int index, float px)
|
||||
{
|
||||
var sp1 = splits[index];
|
||||
var sp2 = splits[index + 1];
|
||||
|
||||
var r1 = sp1.rect;
|
||||
var r2 = sp2.rect;
|
||||
|
||||
var w1 = sp1.weight;
|
||||
var w2 = sp2.weight;
|
||||
var tt = w1 + w2;
|
||||
|
||||
var dd = isHorz ? (r2.xMax - r1.xMin) : (r2.yMax - r1.yMin) - SPLIT_SIZE;
|
||||
var m = isHorz ? (Event.current.mousePosition.x - r1.x) : (Event.current.mousePosition.y - r1.y);
|
||||
var pct = Mathf.Min(0.9f, Mathf.Max(0.1f, m / dd));
|
||||
|
||||
sp1.weight = tt * pct;
|
||||
sp2.weight = tt * (1 - pct);
|
||||
|
||||
dirty = true;
|
||||
if (window != null) window.WillRepaint = true;
|
||||
}
|
||||
|
||||
void DrawSpliter(int index, float px)
|
||||
{
|
||||
var dRect = _rect;
|
||||
|
||||
if (isHorz)
|
||||
{
|
||||
dRect.x = px + SPLIT_SIZE;
|
||||
dRect.width = SPLIT_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
dRect.y = px;
|
||||
dRect.height = SPLIT_SIZE;
|
||||
}
|
||||
|
||||
if (Event.current.type == EventType.Repaint || Event.current.type == EventType.MouseMove)
|
||||
{
|
||||
GUI2.Rect(dRect, Color.black, 0.4f);
|
||||
}
|
||||
|
||||
var dRect2 = GUI2.Padding(dRect, -2f, -2f);
|
||||
|
||||
EditorGUIUtility.AddCursorRect(dRect2, isHorz ? MouseCursor.ResizeHorizontal : MouseCursor.ResizeVertical);
|
||||
if (Event.current.type == EventType.MouseDown && dRect2.Contains(Event.current.mousePosition))
|
||||
{
|
||||
resizeIndex = index;
|
||||
RefreshSpliterPos(index, px);
|
||||
}
|
||||
|
||||
if (resizeIndex == index)
|
||||
{
|
||||
RefreshSpliterPos(index, px);
|
||||
}
|
||||
|
||||
if (Event.current.type == EventType.MouseUp)
|
||||
{
|
||||
resizeIndex = -1;
|
||||
}
|
||||
}
|
||||
|
||||
Rect StartLayout(bool horz)
|
||||
{
|
||||
return horz
|
||||
? EditorGUILayout.BeginHorizontal(GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true))
|
||||
: EditorGUILayout.BeginVertical(GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));
|
||||
}
|
||||
|
||||
void EndLayout(bool horz)
|
||||
{
|
||||
if (horz)
|
||||
{
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/FindReference2/Editor/Script/UI/FR2_SplitView.cs.meta
Normal file
11
Assets/FindReference2/Editor/Script/UI/FR2_SplitView.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0f43fafd1663c45d1b2520859c66c6ee
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
95
Assets/FindReference2/Editor/Script/UI/FR2_TabView.cs
Normal file
95
Assets/FindReference2/Editor/Script/UI/FR2_TabView.cs
Normal file
@@ -0,0 +1,95 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace vietlabs.fr2
|
||||
{
|
||||
public class DrawCallback
|
||||
{
|
||||
public Action BeforeDraw;
|
||||
public Action AfterDraw;
|
||||
}
|
||||
|
||||
|
||||
public class FR2_TabView
|
||||
{
|
||||
public int current;
|
||||
public GUIContent[] labels;
|
||||
public IWindow window;
|
||||
public Action onTabChange;
|
||||
public DrawCallback callback;
|
||||
public bool canDeselectAll; // can there be no active tabs
|
||||
|
||||
public FR2_TabView(IWindow w, bool canDeselectAll)
|
||||
{
|
||||
this.window = w;
|
||||
this.canDeselectAll = canDeselectAll;
|
||||
}
|
||||
|
||||
public bool DrawLayout()
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
GUILayout.BeginHorizontal(EditorStyles.toolbar);
|
||||
{
|
||||
if (callback != null && callback.BeforeDraw != null) callback.BeforeDraw();
|
||||
|
||||
for (var i = 0; i < labels.Length; i++)
|
||||
{
|
||||
var isActive = (i == current);
|
||||
|
||||
var lb = labels[i];
|
||||
var clicked = (lb.image != null)
|
||||
? GUI2.ToolbarToggle(ref isActive, lb.image, Vector2.zero, lb.tooltip)
|
||||
: GUI2.Toggle(ref isActive, lb, EditorStyles.toolbarButton);
|
||||
|
||||
if (!clicked) continue;
|
||||
|
||||
current = (!isActive && canDeselectAll) ? -1 : i;
|
||||
result = true;
|
||||
|
||||
if (onTabChange != null) onTabChange();
|
||||
if (window == null) continue;
|
||||
window.OnSelectionChange(); // force refresh tabs
|
||||
window.WillRepaint = true;
|
||||
}
|
||||
|
||||
if (callback != null && callback.AfterDraw != null) callback.AfterDraw();
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static FR2_TabView FromEnum(Type enumType, IWindow w, bool canDeselectAll = false)
|
||||
{
|
||||
var values = Enum.GetValues(enumType);
|
||||
var labels = new List<GUIContent>();
|
||||
|
||||
foreach (var item in values)
|
||||
{
|
||||
labels.Add(new GUIContent(item.ToString()));
|
||||
}
|
||||
|
||||
return new FR2_TabView(w, canDeselectAll) { current = 0, labels = labels.ToArray() };
|
||||
}
|
||||
public static GUIContent GetGUIContent(object tex)
|
||||
{
|
||||
if (tex is GUIContent) return (GUIContent)tex;
|
||||
if (tex is Texture) return new GUIContent((Texture)tex);
|
||||
if (tex is string) return new GUIContent((string)tex);
|
||||
return GUIContent.none;
|
||||
}
|
||||
|
||||
public static FR2_TabView Create(IWindow w, bool canDeselectAll = false, params object[] titles)
|
||||
{
|
||||
var labels = new List<GUIContent>();
|
||||
foreach (var item in titles)
|
||||
{
|
||||
labels.Add(GetGUIContent(item));
|
||||
}
|
||||
return new FR2_TabView(w, canDeselectAll) { current = 0, labels = labels.ToArray() };
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ea85064796024a07b975d9ebf1ed2fcc
|
||||
timeCreated: 1579764674
|
||||
279
Assets/FindReference2/Editor/Script/UI/GUI2.cs
Normal file
279
Assets/FindReference2/Editor/Script/UI/GUI2.cs
Normal file
@@ -0,0 +1,279 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Vector2 = UnityEngine.Vector2;
|
||||
|
||||
namespace vietlabs.fr2
|
||||
{
|
||||
public interface IDrawer
|
||||
{
|
||||
bool Draw(Rect rect);
|
||||
bool DrawLayout();
|
||||
}
|
||||
|
||||
public static class GUI2
|
||||
{
|
||||
public static void Color(Action a, Color c, float? alpha = null)
|
||||
{
|
||||
if (a == null) return;
|
||||
|
||||
var cColor = GUI.color;
|
||||
if (alpha != null) c.a = alpha.Value;
|
||||
|
||||
GUI.color = c;
|
||||
a();
|
||||
GUI.color = cColor;
|
||||
}
|
||||
|
||||
public static void ContentColor(Action a, Color c, float? alpha = null)
|
||||
{
|
||||
if (a == null) return;
|
||||
|
||||
var cColor = GUI.contentColor;
|
||||
if (alpha != null) c.a = alpha.Value;
|
||||
|
||||
GUI.contentColor = c;
|
||||
a();
|
||||
GUI.contentColor = cColor;
|
||||
}
|
||||
|
||||
public static void BackgroundColor(Action a, Color c, float? alpha = null)
|
||||
{
|
||||
if (a == null) return;
|
||||
|
||||
var cColor = GUI.backgroundColor;
|
||||
if (alpha != null) c.a = alpha.Value;
|
||||
|
||||
GUI.backgroundColor = c;
|
||||
a();
|
||||
GUI.backgroundColor = cColor;
|
||||
}
|
||||
|
||||
public static Color Theme(Color proColor, Color indieColor)
|
||||
{
|
||||
return EditorGUIUtility.isProSkin ? proColor : indieColor;
|
||||
}
|
||||
|
||||
public static Color Alpha(Color c, float a)
|
||||
{
|
||||
c.a = a;
|
||||
return c;
|
||||
}
|
||||
|
||||
public static void Rect(Rect r, Color c, float? alpha = null)
|
||||
{
|
||||
var cColor = GUI.color;
|
||||
if (alpha != null) c.a = alpha.Value;
|
||||
|
||||
GUI.color = c;
|
||||
GUI.DrawTexture(r, Texture2D.whiteTexture);
|
||||
GUI.color = cColor;
|
||||
}
|
||||
|
||||
public static UnityEngine.Object[] DropZone(string title, float w, float h)
|
||||
{
|
||||
var rect = GUILayoutUtility.GetRect(w, h);
|
||||
GUI.Box(rect, GUIContent.none, EditorStyles.textArea);
|
||||
|
||||
var cx = rect.x + w / 2f;
|
||||
var cy = rect.y + h / 2f;
|
||||
var pz = w / 3f; // plus size
|
||||
|
||||
var plusRect = new Rect(cx - pz / 2f, (cy - pz / 2f), pz, pz);
|
||||
GUI2.Color(() => { GUI.DrawTexture(plusRect, FR2_Icon.Plus.image, ScaleMode.ScaleToFit); }, UnityEngine.Color.white, 0.1f);
|
||||
|
||||
GUI.Label(rect, title, EditorStyles.wordWrappedMiniLabel);
|
||||
|
||||
EventType eventType = Event.current.type;
|
||||
bool isAccepted = false;
|
||||
|
||||
if (eventType == EventType.DragUpdated || eventType == EventType.DragPerform)
|
||||
{
|
||||
DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
|
||||
|
||||
if (eventType == EventType.DragPerform)
|
||||
{
|
||||
DragAndDrop.AcceptDrag();
|
||||
isAccepted = true;
|
||||
}
|
||||
Event.current.Use();
|
||||
}
|
||||
|
||||
return isAccepted ? DragAndDrop.objectReferences : null;
|
||||
}
|
||||
|
||||
// public static bool ColorIconButton(Rect r, Texture icon, Vector2? iconOffset, Color? c)
|
||||
// {
|
||||
// if (c != null) Rect(r, c.Value);
|
||||
//
|
||||
// // align center
|
||||
// if (iconOffset != null)
|
||||
// {
|
||||
// r.x += iconOffset.Value.x;
|
||||
// r.y += iconOffset.Value.y;
|
||||
// }
|
||||
//
|
||||
// return GUI.Button(r, icon, GUIStyle.none);
|
||||
// }
|
||||
|
||||
public static bool ColorIconButton(Rect r, Texture icon, Color? c)
|
||||
{
|
||||
var oColor = GUI.color;
|
||||
if (c != null) GUI.color = c.Value;
|
||||
var result = GUI.Button(r, icon, GUIStyle.none);
|
||||
GUI.color = oColor;
|
||||
return result;
|
||||
}
|
||||
|
||||
public static bool Toggle(ref bool value, string label, GUIStyle style, params GUILayoutOption[] options)
|
||||
{
|
||||
var vv = GUILayout.Toggle(value, label, style, options);
|
||||
if (vv == value) return false;
|
||||
value = vv;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool Toggle(ref bool value, Texture2D tex, GUIStyle style, params GUILayoutOption[] options)
|
||||
{
|
||||
var vv = GUILayout.Toggle(value, tex, style, options);
|
||||
if (vv == value) return false;
|
||||
value = vv;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool Toggle(ref bool value, GUIContent tex, GUIStyle style, params GUILayoutOption[] options)
|
||||
{
|
||||
var vv = GUILayout.Toggle(value, tex, style, options);
|
||||
if (vv == value) return false;
|
||||
value = vv;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool Toggle(Rect rect, ref bool value, GUIContent tex)
|
||||
{
|
||||
var vv = GUI.Toggle(rect, value, tex, GUIStyle.none);
|
||||
if (vv == value) return false;
|
||||
value = vv;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool Toggle(Rect rect, ref bool value)
|
||||
{
|
||||
var vv = GUI.Toggle(rect, value, GUIContent.none);
|
||||
if (vv == value) return false;
|
||||
value = vv;
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static bool Toggle(bool v, string label, Action<bool> setter)
|
||||
{
|
||||
var v1 = GUILayout.Toggle(v, label);
|
||||
if (v1 == v) return false;
|
||||
if (setter != null) setter(v1);
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static Dictionary<string, GUIContent> tooltipCache = new Dictionary<string, GUIContent>();
|
||||
internal static GUIContent GetTooltip(string tooltip)
|
||||
{
|
||||
if (string.IsNullOrEmpty(tooltip)) return GUIContent.none;
|
||||
|
||||
GUIContent result;
|
||||
if (tooltipCache.TryGetValue(tooltip, out result)) return result;
|
||||
result = new GUIContent(string.Empty, tooltip);
|
||||
tooltipCache.Add(tooltip, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static bool ToolbarToggle(ref bool value, Texture icon, Vector2 padding, string tooltip = null)
|
||||
{
|
||||
var vv = GUILayout.Toggle(value, GetTooltip(tooltip), EditorStyles.toolbarButton, GUILayout.Width(22f));
|
||||
|
||||
if (icon != null)
|
||||
{
|
||||
var rect = GUILayoutUtility.GetLastRect();
|
||||
rect = Padding(rect, padding.x, padding.y);
|
||||
GUI.DrawTexture(rect, icon, ScaleMode.ScaleToFit);
|
||||
}
|
||||
|
||||
if (vv == value) return false;
|
||||
value = vv;
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO : optimize for performance
|
||||
public static bool EnumPopup<T>(ref T mode, string label, float labelWidth, GUIStyle style, params GUILayoutOption[] options)
|
||||
{
|
||||
var sz = EditorGUIUtility.labelWidth;
|
||||
EditorGUIUtility.labelWidth = labelWidth;
|
||||
{
|
||||
var obj = (Enum)(object)mode;
|
||||
var vv = EditorGUILayout.EnumPopup(label, obj, style, options);
|
||||
if (Equals(vv, obj))
|
||||
{
|
||||
EditorGUIUtility.labelWidth = sz;
|
||||
return false;
|
||||
}
|
||||
|
||||
mode = (T)(object)vv;
|
||||
}
|
||||
EditorGUIUtility.labelWidth = sz;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool EnumPopup<T>(ref T mode, GUIContent icon, GUIStyle style, params GUILayoutOption[] options)
|
||||
{
|
||||
var obj = (Enum)(object)mode;
|
||||
var cRect = GUILayoutUtility.GetRect(16f, 16f);
|
||||
cRect.xMin -= 2f;
|
||||
cRect.yMin += 2f;
|
||||
GUI.Label(cRect, icon);
|
||||
|
||||
var vv = EditorGUILayout.EnumPopup(obj, style, options);
|
||||
if (Equals(vv, obj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
mode = (T)(object)vv;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static Rect Padding(Rect r, float x, float y)
|
||||
{
|
||||
return new Rect(r.x + x, r.y + y, r.width - 2 * x, r.height - 2 * y);
|
||||
}
|
||||
|
||||
public static Rect LeftRect(float w, ref Rect rect)
|
||||
{
|
||||
rect.x += w;
|
||||
rect.width -= w;
|
||||
return new Rect(rect.x - w, rect.y, w, rect.height);
|
||||
}
|
||||
|
||||
public static Rect RightRect(float w, ref Rect rect)
|
||||
{
|
||||
rect.width -= w;
|
||||
return new Rect(rect.x + rect.width, rect.y, w, rect.height);
|
||||
}
|
||||
|
||||
// -----------------------
|
||||
|
||||
private static GUIStyle _miniLabelAlignRight;
|
||||
public static GUIStyle miniLabelAlignRight
|
||||
{
|
||||
get
|
||||
{
|
||||
return _miniLabelAlignRight ?? (
|
||||
_miniLabelAlignRight = new GUIStyle(EditorStyles.miniLabel) { alignment = TextAnchor.MiddleRight }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public static Color darkRed = new Color(0.5f, .0f, 0f, 1f);
|
||||
public static Color darkGreen = new Color(0, .5f, 0f, 1f);
|
||||
public static Color darkBlue = new Color(0, .0f, 0.5f, 1f);
|
||||
public static Color lightRed = new Color(1f, 0.5f, 0.5f, 1f);
|
||||
}
|
||||
}
|
||||
11
Assets/FindReference2/Editor/Script/UI/GUI2.cs.meta
Normal file
11
Assets/FindReference2/Editor/Script/UI/GUI2.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9fa484b2aa858464fb8254e4bbf1f6ac
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user