资源整理,开始开发
This commit is contained in:
1 parent
b50318ad8b
commit
55707a3d08
315 files changed
+208668
-2358
No files matched your search
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c5eb396c4d3fe43b0aea04f76ac1a92f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a2f3bc86488cd4cc981968bec19d88a2
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c50949d305b8c42d7ab69e6a19b56a6a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "FR2",
|
||||
"references": [],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5b7149998ca7a4883aa8be7b868d2342
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9124b66e19b3c44bf999ad7566fa6450
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7f1ed5d1134de134a9e052ef368e3a84
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: af50e16ff6b530b4b808183a3ae0722b
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 83d267126bcce4c9495361e0502fd04c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ff73dd2521fff4f7d83012da98db1b89
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 933e0cc22e789714c87e348a699023d7
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f9b9c04ea6b703343b8aff08a26cf9aa
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d5c2f1d0a3c6acc4a9cf0d8f013f14d3
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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);
|
||||
//}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b543c2ce7dc56c2418505cbb6cb7852d
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d3ba0d9bfe79ff94ca52a3bd6b6870d4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6db5b6c2e2bbb4f2093a7cd892ececca
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 658977c5b6e84344581803c8025947d3
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9a9a5bbf1fb9c4a1b9a0013057b1f59d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c0367155479c84189ad956f35f707b7c
|
||||
timeCreated: 1493613697
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7d62736a417e747e481e3aa85951cd18
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e0eebac9e6cbe431ca16d9cb27500785
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 59de5c9b86a054d2bba67e3b35d00a6d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 846de4aca6426f74c8cacda9de44511f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ecd25f71eac2146a58139581a59c8ad1
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cac8d1a32d8a04fa3a1fe89aed0f5e56
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0f43fafd1663c45d1b2520859c66c6ee
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9fa484b2aa858464fb8254e4bbf1f6ac
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1c19ec545738c8b469ce7fbd881e84e6
|
||||
timeCreated: 1551969732
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f54d1bd14bd3ca042bd867b519fee8cc
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8e7e8f5a82a3a134e91c54efd2274ea9
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Binary file not shown.
+7
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1b8d251f9af63b746bf2f7ffe00ebb9b
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6ab70aee4d56447429c680537fbf93ed
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,46 @@
|
||||
Digitized data copyright (c) 2010 Google Corporation
|
||||
with Reserved Font Arimo, Tinos and Cousine.
|
||||
Copyright (c) 2012 Red Hat, Inc.
|
||||
with Reserved Font Name Liberation.
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6e59c59b81ab47f9b6ec5781fa725d2c
|
||||
timeCreated: 1484171296
|
||||
licenseType: Pro
|
||||
TextScriptImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Binary file not shown.
@@ -0,0 +1,19 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e3265ab4bf004d28a9537516768c1c75
|
||||
timeCreated: 1484171297
|
||||
licenseType: Pro
|
||||
TrueTypeFontImporter:
|
||||
serializedVersion: 2
|
||||
fontSize: 16
|
||||
forceTextureCase: -2
|
||||
characterSpacing: 1
|
||||
characterPadding: 0
|
||||
includeFontData: 1
|
||||
use2xBehaviour: 0
|
||||
fontNames: []
|
||||
fallbackFontReferences: []
|
||||
customCharacters:
|
||||
fontRenderingMode: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 243e06394e614e5d99fab26083b707fa
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 731f1baa9d144a9897cb1d341c2092b8
|
||||
folderAsset: yes
|
||||
timeCreated: 1442040525
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Executable
+106
@@ -0,0 +1,106 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: LiberationSans SDF - Drop Shadow
|
||||
m_Shader: {fileID: 4800000, guid: fe393ace9b354375a9cb14cdbbc28be4, type: 3}
|
||||
m_ShaderKeywords: OUTLINE_ON UNDERLAY_ON
|
||||
m_LightmapFlags: 5
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BumpMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _Cube:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _FaceTex:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 28684132378477856, guid: 8f586378b4e144a9851e7b34d9b748ee,
|
||||
type: 2}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _OutlineTex:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Floats:
|
||||
- _Ambient: 0.5
|
||||
- _Bevel: 0.5
|
||||
- _BevelClamp: 0
|
||||
- _BevelOffset: 0
|
||||
- _BevelRoundness: 0
|
||||
- _BevelWidth: 0
|
||||
- _BumpFace: 0
|
||||
- _BumpOutline: 0
|
||||
- _ColorMask: 15
|
||||
- _Diffuse: 0.5
|
||||
- _DiffusePower: 1
|
||||
- _FaceDilate: 0.1
|
||||
- _FaceUVSpeedX: 0
|
||||
- _FaceUVSpeedY: 0
|
||||
- _GlowInner: 0.05
|
||||
- _GlowOffset: 0
|
||||
- _GlowOuter: 0.05
|
||||
- _GlowPower: 0.75
|
||||
- _GradientScale: 10
|
||||
- _LightAngle: 3.1416
|
||||
- _MaskSoftnessX: 0
|
||||
- _MaskSoftnessY: 0
|
||||
- _OutlineSoftness: 0
|
||||
- _OutlineUVSpeedX: 0
|
||||
- _OutlineUVSpeedY: 0
|
||||
- _OutlineWidth: 0.1
|
||||
- _PerspectiveFilter: 0.875
|
||||
- _Reflectivity: 10
|
||||
- _ScaleRatioA: 0.9
|
||||
- _ScaleRatioB: 0.73125
|
||||
- _ScaleRatioC: 0.64125
|
||||
- _ScaleX: 1
|
||||
- _ScaleY: 1
|
||||
- _ShaderFlags: 0
|
||||
- _Sharpness: 0
|
||||
- _SpecularPower: 2
|
||||
- _Stencil: 0
|
||||
- _StencilComp: 8
|
||||
- _StencilOp: 0
|
||||
- _StencilReadMask: 255
|
||||
- _StencilWriteMask: 255
|
||||
- _TextureHeight: 1024
|
||||
- _TextureWidth: 1024
|
||||
- _UnderlayDilate: 0
|
||||
- _UnderlayOffsetX: 0.5
|
||||
- _UnderlayOffsetY: -0.5
|
||||
- _UnderlaySoftness: 0.05
|
||||
- _VertexOffsetX: 0
|
||||
- _VertexOffsetY: 0
|
||||
- _WeightBold: 0.75
|
||||
- _WeightNormal: 0
|
||||
m_Colors:
|
||||
- _ClipRect: {r: -32767, g: -32767, b: 32767, a: 32767}
|
||||
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _EnvMatrixRotation: {r: 0, g: 0, b: 0, a: 0}
|
||||
- _FaceColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _GlowColor: {r: 0, g: 1, b: 0, a: 0.5}
|
||||
- _MaskCoord: {r: 0, g: 0, b: 32767, a: 32767}
|
||||
- _OutlineColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _ReflectFaceColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _ReflectOutlineColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _SpecularColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _UnderlayColor: {r: 0, g: 0, b: 0, a: 0.5}
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e73a58f6e2794ae7b1b7e50b7fb811b0
|
||||
timeCreated: 1484172806
|
||||
licenseType: Pro
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+1084
File diff suppressed because it is too large.
Load diff
Executable
+8
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2e498d1c8094910479dc3e1b768306a4
|
||||
timeCreated: 1484171803
|
||||
licenseType: Pro
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Executable
+104
@@ -0,0 +1,104 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: LiberationSans SDF - Outline
|
||||
m_Shader: {fileID: 4800000, guid: fe393ace9b354375a9cb14cdbbc28be4, type: 3}
|
||||
m_ShaderKeywords: OUTLINE_ON
|
||||
m_LightmapFlags: 5
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BumpMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _Cube:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _FaceTex:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 28684132378477856, guid: 8f586378b4e144a9851e7b34d9b748ee,
|
||||
type: 2}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _OutlineTex:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Floats:
|
||||
- _Ambient: 0.5
|
||||
- _Bevel: 0.5
|
||||
- _BevelClamp: 0
|
||||
- _BevelOffset: 0
|
||||
- _BevelRoundness: 0
|
||||
- _BevelWidth: 0
|
||||
- _BumpFace: 0
|
||||
- _BumpOutline: 0
|
||||
- _ColorMask: 15
|
||||
- _Diffuse: 0.5
|
||||
- _FaceDilate: 0.1
|
||||
- _FaceUVSpeedX: 0
|
||||
- _FaceUVSpeedY: 0
|
||||
- _GlowInner: 0.05
|
||||
- _GlowOffset: 0
|
||||
- _GlowOuter: 0.05
|
||||
- _GlowPower: 0.75
|
||||
- _GradientScale: 10
|
||||
- _LightAngle: 3.1416
|
||||
- _MaskSoftnessX: 0
|
||||
- _MaskSoftnessY: 0
|
||||
- _OutlineSoftness: 0
|
||||
- _OutlineUVSpeedX: 0
|
||||
- _OutlineUVSpeedY: 0
|
||||
- _OutlineWidth: 0.1
|
||||
- _PerspectiveFilter: 0.875
|
||||
- _Reflectivity: 10
|
||||
- _ScaleRatioA: 0.9
|
||||
- _ScaleRatioB: 0.73125
|
||||
- _ScaleRatioC: 0.64125
|
||||
- _ScaleX: 1
|
||||
- _ScaleY: 1
|
||||
- _ShaderFlags: 0
|
||||
- _Sharpness: 0
|
||||
- _SpecularPower: 2
|
||||
- _Stencil: 0
|
||||
- _StencilComp: 8
|
||||
- _StencilOp: 0
|
||||
- _StencilReadMask: 255
|
||||
- _StencilWriteMask: 255
|
||||
- _TextureHeight: 1024
|
||||
- _TextureWidth: 1024
|
||||
- _UnderlayDilate: 0
|
||||
- _UnderlayOffsetX: 0
|
||||
- _UnderlayOffsetY: 0
|
||||
- _UnderlaySoftness: 0
|
||||
- _VertexOffsetX: 0
|
||||
- _VertexOffsetY: 0
|
||||
- _WeightBold: 0.75
|
||||
- _WeightNormal: 0
|
||||
m_Colors:
|
||||
- _ClipRect: {r: -32767, g: -32767, b: 32767, a: 32767}
|
||||
- _EnvMatrixRotation: {r: 0, g: 0, b: 0, a: 0}
|
||||
- _FaceColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _GlowColor: {r: 0, g: 1, b: 0, a: 0.5}
|
||||
- _MaskCoord: {r: 0, g: 0, b: 32767, a: 32767}
|
||||
- _OutlineColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _ReflectFaceColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _ReflectOutlineColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _SpecularColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _UnderlayColor: {r: 0, g: 0, b: 0, a: 0.5}
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 79459efec17a4d00a321bdcc27bbc385
|
||||
timeCreated: 1484172856
|
||||
licenseType: Pro
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+7821
File diff suppressed because it is too large.
Load diff
+8
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8f586378b4e144a9851e7b34d9b748ee
|
||||
timeCreated: 1484171803
|
||||
licenseType: Pro
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+1
@@ -0,0 +1 @@
|
||||
)]}〕〉》」』】〙〗〟’”⦆»ヽヾーァィゥェォッャュョヮヵヶぁぃぅぇぉっゃゅょゎゕゖㇰㇱㇲㇳㇴㇵㇶㇷㇸㇹㇺㇻㇼㇽㇾㇿ々〻‐゠–〜?!‼⁇⁈⁉・、%,.:;。!?]):;=}¢°"†‡℃〆%,.
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fade42e8bc714b018fac513c043d323b
|
||||
timeCreated: 1425440388
|
||||
licenseType: Store
|
||||
TextScriptImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1 @@
|
||||
([{〔〈《「『【〘〖〝‘“⦅«$—…‥〳〴〵\[({£¥"々〇$¥₩ #
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d82c1b31c7e74239bff1220585707d2b
|
||||
timeCreated: 1425440388
|
||||
licenseType: Store
|
||||
TextScriptImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 512a49d95c0c4332bdd98131869c23c9
|
||||
folderAsset: yes
|
||||
timeCreated: 1441876896
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,659 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2103686
|
||||
Material:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: TextMeshPro/Sprite
|
||||
m_Shader: {fileID: 4800000, guid: cf81c85f95fe47e1a27f6ae460cf182c, type: 3}
|
||||
m_ShaderKeywords: UNITY_UI_CLIP_RECT
|
||||
m_LightmapFlags: 5
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 2800000, guid: dffef66376be4fa480fb02b19edbe903, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Floats:
|
||||
- _ColorMask: 15
|
||||
- _CullMode: 0
|
||||
- _Stencil: 0
|
||||
- _StencilComp: 8
|
||||
- _StencilOp: 0
|
||||
- _StencilReadMask: 255
|
||||
- _StencilWriteMask: 255
|
||||
- _UseUIAlphaClip: 0
|
||||
m_Colors:
|
||||
- _ClipRect: {r: -32767, g: -32767, b: 32767, a: 32767}
|
||||
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 84a92b25f83d49b9bc132d206b370281, type: 3}
|
||||
m_Name: EmojiOne
|
||||
m_EditorClassIdentifier:
|
||||
hashCode: -1836805472
|
||||
material: {fileID: 2103686}
|
||||
materialHashCode: 0
|
||||
m_Version: 1.1.0
|
||||
m_FaceInfo:
|
||||
m_FamilyName:
|
||||
m_StyleName:
|
||||
m_PointSize: 0
|
||||
m_Scale: 0
|
||||
m_LineHeight: 0
|
||||
m_AscentLine: 0
|
||||
m_CapLine: 0
|
||||
m_MeanLine: 0
|
||||
m_Baseline: 0
|
||||
m_DescentLine: 0
|
||||
m_SuperscriptOffset: 0
|
||||
m_SuperscriptSize: 0
|
||||
m_SubscriptOffset: 0
|
||||
m_SubscriptSize: 0
|
||||
m_UnderlineOffset: 0
|
||||
m_UnderlineThickness: 0
|
||||
m_StrikethroughOffset: 0
|
||||
m_StrikethroughThickness: 0
|
||||
m_TabWidth: 0
|
||||
spriteSheet: {fileID: 2800000, guid: dffef66376be4fa480fb02b19edbe903, type: 3}
|
||||
m_SpriteCharacterTable:
|
||||
- m_ElementType: 2
|
||||
m_Unicode: 128522
|
||||
m_GlyphIndex: 0
|
||||
m_Scale: 1
|
||||
m_Name: Smiling face with smiling eyes
|
||||
m_HashCode: -1318250903
|
||||
- m_ElementType: 2
|
||||
m_Unicode: 128523
|
||||
m_GlyphIndex: 1
|
||||
m_Scale: 1
|
||||
m_Name: 1f60b
|
||||
m_HashCode: 57188339
|
||||
- m_ElementType: 2
|
||||
m_Unicode: 128525
|
||||
m_GlyphIndex: 2
|
||||
m_Scale: 1
|
||||
m_Name: 1f60d
|
||||
m_HashCode: 57188341
|
||||
- m_ElementType: 2
|
||||
m_Unicode: 128526
|
||||
m_GlyphIndex: 3
|
||||
m_Scale: 1
|
||||
m_Name: 1f60e
|
||||
m_HashCode: 57188340
|
||||
- m_ElementType: 2
|
||||
m_Unicode: 128512
|
||||
m_GlyphIndex: 4
|
||||
m_Scale: 1
|
||||
m_Name: Grinning face
|
||||
m_HashCode: -95541379
|
||||
- m_ElementType: 2
|
||||
m_Unicode: 128513
|
||||
m_GlyphIndex: 5
|
||||
m_Scale: 1
|
||||
m_Name: 1f601
|
||||
m_HashCode: 57188256
|
||||
- m_ElementType: 2
|
||||
m_Unicode: 128514
|
||||
m_GlyphIndex: 6
|
||||
m_Scale: 1
|
||||
m_Name: Face with tears of joy
|
||||
m_HashCode: 239522663
|
||||
- m_ElementType: 2
|
||||
m_Unicode: 128515
|
||||
m_GlyphIndex: 7
|
||||
m_Scale: 1
|
||||
m_Name: 1f603
|
||||
m_HashCode: 57188258
|
||||
- m_ElementType: 2
|
||||
m_Unicode: 128516
|
||||
m_GlyphIndex: 8
|
||||
m_Scale: 1
|
||||
m_Name: 1f604
|
||||
m_HashCode: 57188261
|
||||
- m_ElementType: 2
|
||||
m_Unicode: 128517
|
||||
m_GlyphIndex: 9
|
||||
m_Scale: 1
|
||||
m_Name: 1f605
|
||||
m_HashCode: 57188260
|
||||
- m_ElementType: 2
|
||||
m_Unicode: 128518
|
||||
m_GlyphIndex: 10
|
||||
m_Scale: 1
|
||||
m_Name: 1f606
|
||||
m_HashCode: 57188263
|
||||
- m_ElementType: 2
|
||||
m_Unicode: 128521
|
||||
m_GlyphIndex: 11
|
||||
m_Scale: 1
|
||||
m_Name: 1f609
|
||||
m_HashCode: 57188264
|
||||
- m_ElementType: 2
|
||||
m_Unicode: 0
|
||||
m_GlyphIndex: 12
|
||||
m_Scale: 1
|
||||
m_Name: .notdef
|
||||
m_HashCode: -600915428
|
||||
- m_ElementType: 2
|
||||
m_Unicode: 129315
|
||||
m_GlyphIndex: 13
|
||||
m_Scale: 1
|
||||
m_Name: 1f923
|
||||
m_HashCode: 57200239
|
||||
- m_ElementType: 2
|
||||
m_Unicode: 9786
|
||||
m_GlyphIndex: 14
|
||||
m_Scale: 1
|
||||
m_Name: 263a
|
||||
m_HashCode: 1748406
|
||||
- m_ElementType: 2
|
||||
m_Unicode: 9785
|
||||
m_GlyphIndex: 15
|
||||
m_Scale: 1
|
||||
m_Name: 2639
|
||||
m_HashCode: 1748462
|
||||
m_SpriteGlyphTable:
|
||||
- m_Index: 0
|
||||
m_Metrics:
|
||||
m_Width: 128
|
||||
m_Height: 128
|
||||
m_HorizontalBearingX: 0
|
||||
m_HorizontalBearingY: 115.6
|
||||
m_HorizontalAdvance: 128
|
||||
m_GlyphRect:
|
||||
m_X: 0
|
||||
m_Y: 384
|
||||
m_Width: 128
|
||||
m_Height: 128
|
||||
m_Scale: 1
|
||||
m_AtlasIndex: 0
|
||||
sprite: {fileID: 0}
|
||||
- m_Index: 1
|
||||
m_Metrics:
|
||||
m_Width: 128
|
||||
m_Height: 128
|
||||
m_HorizontalBearingX: 0
|
||||
m_HorizontalBearingY: 115.6
|
||||
m_HorizontalAdvance: 128
|
||||
m_GlyphRect:
|
||||
m_X: 128
|
||||
m_Y: 384
|
||||
m_Width: 128
|
||||
m_Height: 128
|
||||
m_Scale: 1
|
||||
m_AtlasIndex: 0
|
||||
sprite: {fileID: 0}
|
||||
- m_Index: 2
|
||||
m_Metrics:
|
||||
m_Width: 128
|
||||
m_Height: 128
|
||||
m_HorizontalBearingX: 0
|
||||
m_HorizontalBearingY: 115.6
|
||||
m_HorizontalAdvance: 128
|
||||
m_GlyphRect:
|
||||
m_X: 256
|
||||
m_Y: 384
|
||||
m_Width: 128
|
||||
m_Height: 128
|
||||
m_Scale: 1
|
||||
m_AtlasIndex: 0
|
||||
sprite: {fileID: 0}
|
||||
- m_Index: 3
|
||||
m_Metrics:
|
||||
m_Width: 128
|
||||
m_Height: 128
|
||||
m_HorizontalBearingX: 0
|
||||
m_HorizontalBearingY: 115.6
|
||||
m_HorizontalAdvance: 128
|
||||
m_GlyphRect:
|
||||
m_X: 384
|
||||
m_Y: 384
|
||||
m_Width: 128
|
||||
m_Height: 128
|
||||
m_Scale: 1
|
||||
m_AtlasIndex: 0
|
||||
sprite: {fileID: 0}
|
||||
- m_Index: 4
|
||||
m_Metrics:
|
||||
m_Width: 128
|
||||
m_Height: 128
|
||||
m_HorizontalBearingX: 0
|
||||
m_HorizontalBearingY: 115.6
|
||||
m_HorizontalAdvance: 128
|
||||
m_GlyphRect:
|
||||
m_X: 0
|
||||
m_Y: 256
|
||||
m_Width: 128
|
||||
m_Height: 128
|
||||
m_Scale: 1
|
||||
m_AtlasIndex: 0
|
||||
sprite: {fileID: 0}
|
||||
- m_Index: 5
|
||||
m_Metrics:
|
||||
m_Width: 128
|
||||
m_Height: 128
|
||||
m_HorizontalBearingX: 0
|
||||
m_HorizontalBearingY: 115.6
|
||||
m_HorizontalAdvance: 128
|
||||
m_GlyphRect:
|
||||
m_X: 128
|
||||
m_Y: 256
|
||||
m_Width: 128
|
||||
m_Height: 128
|
||||
m_Scale: 1
|
||||
m_AtlasIndex: 0
|
||||
sprite: {fileID: 0}
|
||||
- m_Index: 6
|
||||
m_Metrics:
|
||||
m_Width: 128
|
||||
m_Height: 128
|
||||
m_HorizontalBearingX: 0
|
||||
m_HorizontalBearingY: 115.6
|
||||
m_HorizontalAdvance: 128
|
||||
m_GlyphRect:
|
||||
m_X: 256
|
||||
m_Y: 256
|
||||
m_Width: 128
|
||||
m_Height: 128
|
||||
m_Scale: 1
|
||||
m_AtlasIndex: 0
|
||||
sprite: {fileID: 0}
|
||||
- m_Index: 7
|
||||
m_Metrics:
|
||||
m_Width: 128
|
||||
m_Height: 128
|
||||
m_HorizontalBearingX: 0
|
||||
m_HorizontalBearingY: 115.6
|
||||
m_HorizontalAdvance: 128
|
||||
m_GlyphRect:
|
||||
m_X: 384
|
||||
m_Y: 256
|
||||
m_Width: 128
|
||||
m_Height: 128
|
||||
m_Scale: 1
|
||||
m_AtlasIndex: 0
|
||||
sprite: {fileID: 0}
|
||||
- m_Index: 8
|
||||
m_Metrics:
|
||||
m_Width: 128
|
||||
m_Height: 128
|
||||
m_HorizontalBearingX: 0
|
||||
m_HorizontalBearingY: 115.6
|
||||
m_HorizontalAdvance: 128
|
||||
m_GlyphRect:
|
||||
m_X: 0
|
||||
m_Y: 128
|
||||
m_Width: 128
|
||||
m_Height: 128
|
||||
m_Scale: 1
|
||||
m_AtlasIndex: 0
|
||||
sprite: {fileID: 0}
|
||||
- m_Index: 9
|
||||
m_Metrics:
|
||||
m_Width: 128
|
||||
m_Height: 128
|
||||
m_HorizontalBearingX: 0
|
||||
m_HorizontalBearingY: 115.6
|
||||
m_HorizontalAdvance: 128
|
||||
m_GlyphRect:
|
||||
m_X: 128
|
||||
m_Y: 128
|
||||
m_Width: 128
|
||||
m_Height: 128
|
||||
m_Scale: 1
|
||||
m_AtlasIndex: 0
|
||||
sprite: {fileID: 0}
|
||||
- m_Index: 10
|
||||
m_Metrics:
|
||||
m_Width: 128
|
||||
m_Height: 128
|
||||
m_HorizontalBearingX: 0
|
||||
m_HorizontalBearingY: 115.6
|
||||
m_HorizontalAdvance: 128
|
||||
m_GlyphRect:
|
||||
m_X: 256
|
||||
m_Y: 128
|
||||
m_Width: 128
|
||||
m_Height: 128
|
||||
m_Scale: 1
|
||||
m_AtlasIndex: 0
|
||||
sprite: {fileID: 0}
|
||||
- m_Index: 11
|
||||
m_Metrics:
|
||||
m_Width: 128
|
||||
m_Height: 128
|
||||
m_HorizontalBearingX: 0
|
||||
m_HorizontalBearingY: 115.6
|
||||
m_HorizontalAdvance: 128
|
||||
m_GlyphRect:
|
||||
m_X: 384
|
||||
m_Y: 128
|
||||
m_Width: 128
|
||||
m_Height: 128
|
||||
m_Scale: 1
|
||||
m_AtlasIndex: 0
|
||||
sprite: {fileID: 0}
|
||||
- m_Index: 12
|
||||
m_Metrics:
|
||||
m_Width: 128
|
||||
m_Height: 128
|
||||
m_HorizontalBearingX: 0
|
||||
m_HorizontalBearingY: 115.6
|
||||
m_HorizontalAdvance: 128
|
||||
m_GlyphRect:
|
||||
m_X: 0
|
||||
m_Y: 0
|
||||
m_Width: 128
|
||||
m_Height: 128
|
||||
m_Scale: 1
|
||||
m_AtlasIndex: 0
|
||||
sprite: {fileID: 0}
|
||||
- m_Index: 13
|
||||
m_Metrics:
|
||||
m_Width: 128
|
||||
m_Height: 128
|
||||
m_HorizontalBearingX: 0
|
||||
m_HorizontalBearingY: 115.6
|
||||
m_HorizontalAdvance: 128
|
||||
m_GlyphRect:
|
||||
m_X: 128
|
||||
m_Y: 0
|
||||
m_Width: 128
|
||||
m_Height: 128
|
||||
m_Scale: 1
|
||||
m_AtlasIndex: 0
|
||||
sprite: {fileID: 0}
|
||||
- m_Index: 14
|
||||
m_Metrics:
|
||||
m_Width: 128
|
||||
m_Height: 128
|
||||
m_HorizontalBearingX: 0
|
||||
m_HorizontalBearingY: 115.6
|
||||
m_HorizontalAdvance: 128
|
||||
m_GlyphRect:
|
||||
m_X: 256
|
||||
m_Y: 0
|
||||
m_Width: 128
|
||||
m_Height: 128
|
||||
m_Scale: 1
|
||||
m_AtlasIndex: 0
|
||||
sprite: {fileID: 0}
|
||||
- m_Index: 15
|
||||
m_Metrics:
|
||||
m_Width: 128
|
||||
m_Height: 128
|
||||
m_HorizontalBearingX: 0
|
||||
m_HorizontalBearingY: 115.6
|
||||
m_HorizontalAdvance: 128
|
||||
m_GlyphRect:
|
||||
m_X: 384
|
||||
m_Y: 0
|
||||
m_Width: 128
|
||||
m_Height: 128
|
||||
m_Scale: 1
|
||||
m_AtlasIndex: 0
|
||||
sprite: {fileID: 0}
|
||||
spriteInfoList:
|
||||
- id: 0
|
||||
x: 0
|
||||
y: 384
|
||||
width: 128
|
||||
height: 128
|
||||
xOffset: 0
|
||||
yOffset: 115.6
|
||||
xAdvance: 128
|
||||
scale: 1
|
||||
name: Smiling face with smiling eyes
|
||||
hashCode: -1318250903
|
||||
unicode: 128522
|
||||
pivot: {x: 0.5, y: 0.5}
|
||||
sprite: {fileID: 0}
|
||||
- id: 1
|
||||
x: 128
|
||||
y: 384
|
||||
width: 128
|
||||
height: 128
|
||||
xOffset: 0
|
||||
yOffset: 115.6
|
||||
xAdvance: 128
|
||||
scale: 1
|
||||
name: 1f60b
|
||||
hashCode: 57188339
|
||||
unicode: 128523
|
||||
pivot: {x: 0.5, y: 0.5}
|
||||
sprite: {fileID: 0}
|
||||
- id: 2
|
||||
x: 256
|
||||
y: 384
|
||||
width: 128
|
||||
height: 128
|
||||
xOffset: 0
|
||||
yOffset: 115.6
|
||||
xAdvance: 128
|
||||
scale: 1
|
||||
name: 1f60d
|
||||
hashCode: 57188341
|
||||
unicode: 128525
|
||||
pivot: {x: 0.5, y: 0.5}
|
||||
sprite: {fileID: 0}
|
||||
- id: 3
|
||||
x: 384
|
||||
y: 384
|
||||
width: 128
|
||||
height: 128
|
||||
xOffset: 0
|
||||
yOffset: 115.6
|
||||
xAdvance: 128
|
||||
scale: 1
|
||||
name: 1f60e
|
||||
hashCode: 57188340
|
||||
unicode: 128526
|
||||
pivot: {x: 0.5, y: 0.5}
|
||||
sprite: {fileID: 0}
|
||||
- id: 4
|
||||
x: 0
|
||||
y: 256
|
||||
width: 128
|
||||
height: 128
|
||||
xOffset: 0
|
||||
yOffset: 115.6
|
||||
xAdvance: 128
|
||||
scale: 1
|
||||
name: Grinning face
|
||||
hashCode: -95541379
|
||||
unicode: 128512
|
||||
pivot: {x: 0.5, y: 0.5}
|
||||
sprite: {fileID: 0}
|
||||
- id: 5
|
||||
x: 128
|
||||
y: 256
|
||||
width: 128
|
||||
height: 128
|
||||
xOffset: 0
|
||||
yOffset: 115.6
|
||||
xAdvance: 128
|
||||
scale: 1
|
||||
name: 1f601
|
||||
hashCode: 57188256
|
||||
unicode: 128513
|
||||
pivot: {x: 0.5, y: 0.5}
|
||||
sprite: {fileID: 0}
|
||||
- id: 6
|
||||
x: 256
|
||||
y: 256
|
||||
width: 128
|
||||
height: 128
|
||||
xOffset: 0
|
||||
yOffset: 115.6
|
||||
xAdvance: 128
|
||||
scale: 1
|
||||
name: Face with tears of joy
|
||||
hashCode: 239522663
|
||||
unicode: 128514
|
||||
pivot: {x: 0.5, y: 0.5}
|
||||
sprite: {fileID: 0}
|
||||
- id: 7
|
||||
x: 384
|
||||
y: 256
|
||||
width: 128
|
||||
height: 128
|
||||
xOffset: 0
|
||||
yOffset: 115.6
|
||||
xAdvance: 128
|
||||
scale: 1
|
||||
name: 1f603
|
||||
hashCode: 57188258
|
||||
unicode: 128515
|
||||
pivot: {x: 0.5, y: 0.5}
|
||||
sprite: {fileID: 0}
|
||||
- id: 8
|
||||
x: 0
|
||||
y: 128
|
||||
width: 128
|
||||
height: 128
|
||||
xOffset: 0
|
||||
yOffset: 115.6
|
||||
xAdvance: 128
|
||||
scale: 1
|
||||
name: 1f604
|
||||
hashCode: 57188261
|
||||
unicode: 128516
|
||||
pivot: {x: 0.5, y: 0.5}
|
||||
sprite: {fileID: 0}
|
||||
- id: 9
|
||||
x: 128
|
||||
y: 128
|
||||
width: 128
|
||||
height: 128
|
||||
xOffset: 0
|
||||
yOffset: 115.6
|
||||
xAdvance: 128
|
||||
scale: 1
|
||||
name: 1f605
|
||||
hashCode: 57188260
|
||||
unicode: 128517
|
||||
pivot: {x: 0.5, y: 0.5}
|
||||
sprite: {fileID: 0}
|
||||
- id: 10
|
||||
x: 256
|
||||
y: 128
|
||||
width: 128
|
||||
height: 128
|
||||
xOffset: 0
|
||||
yOffset: 115.6
|
||||
xAdvance: 128
|
||||
scale: 1
|
||||
name: 1f606
|
||||
hashCode: 57188263
|
||||
unicode: 128518
|
||||
pivot: {x: 0.5, y: 0.5}
|
||||
sprite: {fileID: 0}
|
||||
- id: 11
|
||||
x: 384
|
||||
y: 128
|
||||
width: 128
|
||||
height: 128
|
||||
xOffset: 0
|
||||
yOffset: 115.6
|
||||
xAdvance: 128
|
||||
scale: 1
|
||||
name: 1f609
|
||||
hashCode: 57188264
|
||||
unicode: 128521
|
||||
pivot: {x: 0.5, y: 0.5}
|
||||
sprite: {fileID: 0}
|
||||
- id: 12
|
||||
x: 0
|
||||
y: 0
|
||||
width: 128
|
||||
height: 128
|
||||
xOffset: 0
|
||||
yOffset: 115.6
|
||||
xAdvance: 128
|
||||
scale: 1
|
||||
name: 1f618
|
||||
hashCode: 57188168
|
||||
unicode: 128536
|
||||
pivot: {x: 0.5, y: 0.5}
|
||||
sprite: {fileID: 0}
|
||||
- id: 13
|
||||
x: 128
|
||||
y: 0
|
||||
width: 128
|
||||
height: 128
|
||||
xOffset: 0
|
||||
yOffset: 115.6
|
||||
xAdvance: 128
|
||||
scale: 1
|
||||
name: 1f923
|
||||
hashCode: 57200239
|
||||
unicode: 129315
|
||||
pivot: {x: 0.5, y: 0.5}
|
||||
sprite: {fileID: 0}
|
||||
- id: 14
|
||||
x: 256
|
||||
y: 0
|
||||
width: 128
|
||||
height: 128
|
||||
xOffset: 0
|
||||
yOffset: 115.6
|
||||
xAdvance: 128
|
||||
scale: 1
|
||||
name: 263a
|
||||
hashCode: 1748406
|
||||
unicode: 9786
|
||||
pivot: {x: 0.5, y: 0.5}
|
||||
sprite: {fileID: 0}
|
||||
- id: 15
|
||||
x: 384
|
||||
y: 0
|
||||
width: 128
|
||||
height: 128
|
||||
xOffset: 0
|
||||
yOffset: 115.6
|
||||
xAdvance: 128
|
||||
scale: 1
|
||||
name: 2639
|
||||
hashCode: 1748462
|
||||
unicode: 9785
|
||||
pivot: {x: 0.5, y: 0.5}
|
||||
sprite: {fileID: 0}
|
||||
fallbackSpriteAssets: []
|
||||
--- !u!21 &1369835458
|
||||
Material:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: TextMeshPro/Sprite
|
||||
m_Shader: {fileID: 4800000, guid: cf81c85f95fe47e1a27f6ae460cf182c, type: 3}
|
||||
m_ShaderKeywords:
|
||||
m_LightmapFlags: 5
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs: []
|
||||
m_Floats: []
|
||||
m_Colors: []
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c41005c129ba4d66911b75229fd70b45
|
||||
timeCreated: 1480316912
|
||||
licenseType: Pro
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4aecb92fff08436c8303b10eab8da368
|
||||
folderAsset: yes
|
||||
timeCreated: 1441876950
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: ab2114bdc8544297b417dfefe9f1e410, type: 3}
|
||||
m_Name: Default Style Sheet
|
||||
m_EditorClassIdentifier:
|
||||
m_StyleList:
|
||||
- m_Name: Normal
|
||||
m_HashCode: -1183493901
|
||||
m_OpeningDefinition:
|
||||
m_ClosingDefinition:
|
||||
m_OpeningTagArray:
|
||||
m_ClosingTagArray:
|
||||
- m_Name: H1
|
||||
m_HashCode: 2425
|
||||
m_OpeningDefinition: <size=2em><b><#40ff80>*
|
||||
m_ClosingDefinition: '*</size></b></color>'
|
||||
m_OpeningTagArray: 3c00000073000000690000007a000000650000003d00000032000000650000006d0000003e0000003c000000620000003e0000003c000000230000003400000030000000660000006600000038000000300000003e0000002a000000
|
||||
m_ClosingTagArray: 2a0000003c0000002f00000073000000690000007a000000650000003e0000003c0000002f000000620000003e0000003c0000002f000000630000006f0000006c0000006f000000720000003e000000
|
||||
- m_Name: Quote
|
||||
m_HashCode: 93368250
|
||||
m_OpeningDefinition: <i><size=75%><margin=10%>
|
||||
m_ClosingDefinition: </i></size></width></margin>
|
||||
m_OpeningTagArray: 3c000000690000003e0000003c00000073000000690000007a000000650000003d0000003700000035000000250000003e0000003c0000006d000000610000007200000067000000690000006e0000003d0000003100000030000000250000003e000000
|
||||
m_ClosingTagArray: 3c0000002f000000690000003e0000003c0000002f00000073000000690000007a000000650000003e0000003c0000002f00000077000000690000006400000074000000680000003e0000003c0000002f0000006d000000610000007200000067000000690000006e0000003e000000
|
||||
- m_Name: A
|
||||
m_HashCode: 65
|
||||
m_OpeningDefinition: <color=#40a0ff><u>
|
||||
m_ClosingDefinition: </u></color>
|
||||
m_OpeningTagArray: 3c000000630000006f0000006c0000006f000000720000003d000000230000003400000030000000610000003000000066000000660000003e0000003c000000750000003e000000
|
||||
m_ClosingTagArray: 3c0000002f000000750000003e0000003c0000002f000000630000006f0000006c0000006f000000720000003e000000
|
||||
- m_Name: Link
|
||||
m_HashCode: 2656128
|
||||
m_OpeningDefinition: <u><#40a0ff><link="ID_01">
|
||||
m_ClosingDefinition: </u></color></link>
|
||||
m_OpeningTagArray: 3c000000750000003e0000003c000000230000003400000030000000610000003000000066000000660000003e0000003c0000006c000000690000006e0000006b0000003d0000002200000049000000440000005f0000003000000031000000220000003e000000
|
||||
m_ClosingTagArray: 3c0000002f000000750000003e0000003c0000002f000000630000006f0000006c0000006f000000720000003e0000003c0000002f0000006c000000690000006e0000006b0000003e000000
|
||||
- m_Name: Title
|
||||
m_HashCode: 97690656
|
||||
m_OpeningDefinition: <size=125%><b><align=center>
|
||||
m_ClosingDefinition: </size></b></align>
|
||||
m_OpeningTagArray: 3c00000073000000690000007a000000650000003d000000310000003200000035000000250000003e0000003c000000620000003e0000003c000000610000006c00000069000000670000006e0000003d00000063000000650000006e0000007400000065000000720000003e000000
|
||||
m_ClosingTagArray: 3c0000002f00000073000000690000007a000000650000003e0000003c0000002f000000620000003e0000003c0000002f000000610000006c00000069000000670000006e0000003e000000
|
||||
- m_Name: H2
|
||||
m_HashCode: 2426
|
||||
m_OpeningDefinition: <size=1.5em><b><#4080FF>
|
||||
m_ClosingDefinition: </size></b></color>
|
||||
m_OpeningTagArray: 3c00000073000000690000007a000000650000003d000000310000002e00000035000000650000006d0000003e0000003c000000620000003e0000003c000000230000003400000030000000380000003000000046000000460000003e000000
|
||||
m_ClosingTagArray: 3c0000002f00000073000000690000007a000000650000003e0000003c0000002f000000620000003e0000003c0000002f000000630000006f0000006c0000006f000000720000003e000000
|
||||
- m_Name: H3
|
||||
m_HashCode: 2427
|
||||
m_OpeningDefinition: <size=1.17em><b><#FF8040>
|
||||
m_ClosingDefinition: </size></b></color>
|
||||
m_OpeningTagArray: 3c00000073000000690000007a000000650000003d000000310000002e0000003100000037000000650000006d0000003e0000003c000000620000003e0000003c000000230000004600000046000000380000003000000034000000300000003e000000
|
||||
m_ClosingTagArray: 3c0000002f00000073000000690000007a000000650000003e0000003c0000002f000000620000003e0000003c0000002f000000630000006f0000006c0000006f000000720000003e000000
|
||||
- m_Name: C1
|
||||
m_HashCode: 2194
|
||||
m_OpeningDefinition: <color=#ffff40>
|
||||
m_ClosingDefinition: </color>
|
||||
m_OpeningTagArray: 3c000000630000006f0000006c0000006f000000720000003d000000230000006600000066000000660000006600000034000000300000003e000000
|
||||
m_ClosingTagArray: 3c0000002f000000630000006f0000006c0000006f000000720000003e000000
|
||||
- m_Name: C2
|
||||
m_HashCode: 2193
|
||||
m_OpeningDefinition: <color=#ff40FF><size=125%>
|
||||
m_ClosingDefinition: </color></size>
|
||||
m_OpeningTagArray: 3c000000630000006f0000006c0000006f000000720000003d000000230000006600000066000000340000003000000046000000460000003e0000003c00000073000000690000007a000000650000003d000000310000003200000035000000250000003e000000
|
||||
m_ClosingTagArray: 3c0000002f000000630000006f0000006c0000006f000000720000003e0000003c0000002f00000073000000690000007a000000650000003e000000
|
||||
- m_Name: C3
|
||||
m_HashCode: 2192
|
||||
m_OpeningDefinition: <color=#80A0FF><b>
|
||||
m_ClosingDefinition: </color></b>
|
||||
m_OpeningTagArray: 3c000000630000006f0000006c0000006f000000720000003d000000230000003800000030000000410000003000000046000000460000003e0000003c000000620000003e000000
|
||||
m_ClosingTagArray: 3c0000002f000000630000006f0000006c0000006f000000720000003e0000003c0000002f000000620000003e000000
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f952c082cb03451daed3ee968ac6c63e
|
||||
timeCreated: 1432805430
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,53 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 2705215ac5b84b70bacc50632be6e391, type: 3}
|
||||
m_Name: TMP Settings
|
||||
m_EditorClassIdentifier:
|
||||
assetVersion: 2
|
||||
m_TextWrappingMode: 1
|
||||
m_enableKerning: 1
|
||||
m_ActiveFontFeatures: 6e72656b
|
||||
m_enableExtraPadding: 0
|
||||
m_enableTintAllSprites: 0
|
||||
m_enableParseEscapeCharacters: 1
|
||||
m_EnableRaycastTarget: 1
|
||||
m_GetFontFeaturesAtRuntime: 1
|
||||
m_missingGlyphCharacter: 0
|
||||
m_ClearDynamicDataOnBuild: 1
|
||||
m_warningsDisabled: 0
|
||||
m_defaultFontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
|
||||
m_defaultFontAssetPath: Fonts & Materials/
|
||||
m_defaultFontSize: 36
|
||||
m_defaultAutoSizeMinRatio: 0.5
|
||||
m_defaultAutoSizeMaxRatio: 2
|
||||
m_defaultTextMeshProTextContainerSize: {x: 20, y: 5}
|
||||
m_defaultTextMeshProUITextContainerSize: {x: 200, y: 50}
|
||||
m_autoSizeTextContainer: 0
|
||||
m_IsTextObjectScaleStatic: 0
|
||||
m_fallbackFontAssets:
|
||||
- {fileID: 11400000, guid: 39a0999dfda46415d8cb47c0af34425c, type: 2}
|
||||
m_matchMaterialPreset: 1
|
||||
m_HideSubTextObjects: 1
|
||||
m_defaultSpriteAsset: {fileID: 11400000, guid: c41005c129ba4d66911b75229fd70b45,
|
||||
type: 2}
|
||||
m_defaultSpriteAssetPath: Sprite Assets/
|
||||
m_enableEmojiSupport: 1
|
||||
m_MissingCharacterSpriteUnicode: 0
|
||||
m_EmojiFallbackTextAssets: []
|
||||
m_defaultColorGradientPresetsPath: Color Gradient Presets/
|
||||
m_defaultStyleSheet: {fileID: 11400000, guid: f952c082cb03451daed3ee968ac6c63e,
|
||||
type: 2}
|
||||
m_StyleSheetsResourcePath:
|
||||
m_leadingCharacters: {fileID: 4900000, guid: d82c1b31c7e74239bff1220585707d2b, type: 3}
|
||||
m_followingCharacters: {fileID: 4900000, guid: fade42e8bc714b018fac513c043d323b,
|
||||
type: 3}
|
||||
m_UseModernHangulLineBreakingRules: 0
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3f5b5dff67a942289a9defa416b206f3
|
||||
timeCreated: 1436653997
|
||||
licenseType: Pro
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e9f693669af91aa45ad615fc681ed29f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,178 @@
|
||||
float2 UnpackUV(float uv)
|
||||
{
|
||||
float2 output;
|
||||
output.x = floor(uv / 4096.0);
|
||||
output.y = uv - 4096.0 * output.x;
|
||||
|
||||
return output * 0.001953125;
|
||||
}
|
||||
|
||||
float4 BlendARGB(float4 overlying, float4 underlying)
|
||||
{
|
||||
overlying.rgb *= overlying.a;
|
||||
underlying.rgb *= underlying.a;
|
||||
float3 blended = overlying.rgb + ((1 - overlying.a) * underlying.rgb);
|
||||
float alpha = underlying.a + (1 - underlying.a) * overlying.a;
|
||||
return float4(blended / alpha, alpha);
|
||||
}
|
||||
|
||||
float3 GetSpecular(float3 n, float3 l)
|
||||
{
|
||||
float spec = pow(max(0.0, dot(n, l)), _Reflectivity);
|
||||
return _SpecularColor.rgb * spec * _SpecularPower;
|
||||
}
|
||||
|
||||
void GetSurfaceNormal_float(texture2D atlas, float textureWidth, float textureHeight, float2 uv, bool isFront, out float3 nornmal)
|
||||
{
|
||||
float3 delta = float3(1.0 / textureWidth, 1.0 / textureHeight, 0.0);
|
||||
|
||||
// Read "height field"
|
||||
float4 h = float4(
|
||||
SAMPLE_TEXTURE2D(atlas, SamplerState_Linear_Clamp, uv - delta.xz).a,
|
||||
SAMPLE_TEXTURE2D(atlas, SamplerState_Linear_Clamp, uv + delta.xz).a,
|
||||
SAMPLE_TEXTURE2D(atlas, SamplerState_Linear_Clamp, uv - delta.zy).a,
|
||||
SAMPLE_TEXTURE2D(atlas, SamplerState_Linear_Clamp, uv + delta.zy).a);
|
||||
|
||||
bool raisedBevel = _BevelType;
|
||||
|
||||
h += _BevelOffset;
|
||||
|
||||
float bevelWidth = max(.01, _BevelWidth);
|
||||
|
||||
// Track outline
|
||||
h -= .5;
|
||||
h /= bevelWidth;
|
||||
h = saturate(h + .5);
|
||||
|
||||
if (raisedBevel) h = 1 - abs(h * 2.0 - 1.0);
|
||||
h = lerp(h, sin(h * 3.141592 / 2.0), float4(_BevelRoundness, _BevelRoundness, _BevelRoundness, _BevelRoundness));
|
||||
h = min(h, 1.0 - float4(_BevelClamp, _BevelClamp, _BevelClamp, _BevelClamp));
|
||||
h *= _BevelAmount * bevelWidth * _GradientScale * -2.0;
|
||||
|
||||
float3 va = normalize(float3(-1.0, 0.0, h.y - h.x));
|
||||
float3 vb = normalize(float3(0.0, 1.0, h.w - h.z));
|
||||
|
||||
float3 f = float3(1, 1, 1);
|
||||
if (isFront) f = float3(1, 1, -1);
|
||||
nornmal = cross(va, vb) * f;
|
||||
}
|
||||
|
||||
void EvaluateLight_float(float4 faceColor, float3 n, out float4 color)
|
||||
{
|
||||
n.z = abs(n.z);
|
||||
float3 light = normalize(float3(sin(_LightAngle), cos(_LightAngle), 1.0));
|
||||
|
||||
float3 col = max(faceColor.rgb, 0) + GetSpecular(n, light)* faceColor.a;
|
||||
//faceColor.rgb += col * faceColor.a;
|
||||
col *= 1 - (dot(n, light) * _Diffuse);
|
||||
col *= lerp(_Ambient, 1, n.z * n.z);
|
||||
|
||||
//fixed4 reflcol = texCUBE(_Cube, reflect(input.viewDir, -n));
|
||||
//faceColor.rgb += reflcol.rgb * lerp(_ReflectFaceColor.rgb, _ReflectOutlineColor.rgb, saturate(sd + outline * 0.5)) * faceColor.a;
|
||||
|
||||
color = float4(col, faceColor.a);
|
||||
}
|
||||
|
||||
// Add custom function to handle time in HDRP
|
||||
|
||||
|
||||
//
|
||||
void GenerateUV_float(float2 inUV, float4 transform, float2 animSpeed, out float2 outUV)
|
||||
{
|
||||
outUV = inUV * transform.xy + transform.zw + (animSpeed * _Time.y);
|
||||
}
|
||||
|
||||
void ComputeUVOffset_float(float texWidth, float texHeight, float2 offset, float SDR, out float2 uvOffset)
|
||||
{
|
||||
uvOffset = float2(-offset.x * SDR / texWidth, -offset.y * SDR / texHeight);
|
||||
}
|
||||
|
||||
void ScreenSpaceRatio2_float(float4x4 projection, float4 position, float2 objectScale, float screenWidth, float screenHeight, float fontScale, out float SSR)
|
||||
{
|
||||
float2 pixelSize = position.w;
|
||||
pixelSize /= (objectScale * mul((float2x2)projection, float2(screenWidth, screenHeight)));
|
||||
SSR = rsqrt(dot(pixelSize, pixelSize)*2) * fontScale;
|
||||
}
|
||||
|
||||
// UV : Texture coordinate of the source distance field texture
|
||||
// TextureSize : Size of the source distance field texture
|
||||
// Filter : Enable perspective filter (soften)
|
||||
void ScreenSpaceRatio_float(float2 UV, float TextureSize, bool Filter, out float SSR)
|
||||
{
|
||||
if(Filter)
|
||||
{
|
||||
float2 a = float2(ddx(UV.x), ddy(UV.x));
|
||||
float2 b = float2(ddx(UV.y), ddy(UV.y));
|
||||
float s = lerp(dot(a,a), dot(b,b), 0.5);
|
||||
SSR = rsqrt(s) / TextureSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
float s = rsqrt(abs(ddx(UV.x) * ddy(UV.y) - ddy(UV.x) * ddx(UV.y)));
|
||||
SSR = s / TextureSize;
|
||||
}
|
||||
}
|
||||
|
||||
// SSR : Screen Space Ratio
|
||||
// SD : Signed Distance (encoded : Distance / SDR + .5)
|
||||
// SDR : Signed Distance Ratio
|
||||
//
|
||||
// IsoPerimeter : Dilate / Contract the shape
|
||||
void ComputeSDF_float(float SSR, float SD, float SDR, float isoPerimeter, float softness, out float outAlpha)
|
||||
{
|
||||
softness *= SSR * SDR;
|
||||
float d = (SD - 0.5) * SDR; // Signed distance to edge, in Texture space
|
||||
outAlpha = saturate((d * 2.0 * SSR + 0.5 + isoPerimeter * SDR * SSR + softness * 0.5) / (1.0 + softness)); // Screen pixel coverage (alpha)
|
||||
}
|
||||
|
||||
void ComputeSDF2_float(float SSR, float SD, float SDR, float2 isoPerimeter, float2 softness, out float2 outAlpha)
|
||||
{
|
||||
softness *= SSR * SDR;
|
||||
float d = (SD - 0.5f) * SDR;
|
||||
outAlpha = saturate((d * 2.0f * SSR + 0.5f + isoPerimeter * SDR * SSR + softness * 0.5) / (1.0 + softness));
|
||||
}
|
||||
|
||||
void ComputeSDF4_float(float SSR, float SD, float SDR, float4 isoPerimeter, float4 softness, out float4 outAlpha)
|
||||
{
|
||||
softness *= SSR * SDR;
|
||||
float d = (SD - 0.5f) * SDR;
|
||||
outAlpha = saturate((d * 2.0f * SSR + 0.5f + isoPerimeter * SDR * SSR + softness * 0.5) / (1.0 + softness));
|
||||
}
|
||||
|
||||
void ComputeSDF44_float(float SSR, float4 SD, float SDR, float4 isoPerimeter, float4 softness, bool outline, out float4 outAlpha)
|
||||
{
|
||||
softness *= SSR * SDR;
|
||||
float4 d = (SD - 0.5f) * SDR;
|
||||
if(outline) d.w = max(max(d.x, d.y), d.z);
|
||||
outAlpha = saturate((d * 2.0f * SSR + 0.5f + isoPerimeter * SDR * SSR + softness * 0.5) / (1.0 + softness));
|
||||
}
|
||||
|
||||
void Composite_float(float4 overlying, float4 underlying, out float4 outColor)
|
||||
{
|
||||
outColor = BlendARGB(overlying, underlying);
|
||||
}
|
||||
|
||||
// Face only
|
||||
void Layer1_float(float alpha, float4 color0, out float4 outColor)
|
||||
{
|
||||
color0.a *= alpha;
|
||||
outColor = color0;
|
||||
}
|
||||
|
||||
// Face + 1 Outline
|
||||
void Layer2_float(float2 alpha, float4 color0, float4 color1, out float4 outColor)
|
||||
{
|
||||
color1.a *= alpha.y;
|
||||
color0.rgb *= color0.a; color1.rgb *= color1.a;
|
||||
outColor = lerp(color1, color0, alpha.x);
|
||||
outColor.rgb /= outColor.a;
|
||||
}
|
||||
|
||||
// Face + 3 Outline
|
||||
void Layer4_float(float4 alpha, float4 color0, float4 color1, float4 color2, float4 color3, out float4 outColor)
|
||||
{
|
||||
color3.a *= alpha.w;
|
||||
color0.rgb *= color0.a; color1.rgb *= color1.a; color2.rgb *= color2.a; color3.rgb *= color3.a;
|
||||
outColor = lerp(lerp(lerp(color3, color2, alpha.z), color1, alpha.y), color0, alpha.x);
|
||||
outColor.rgb /= outColor.a;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 96de908384869cd409c75efa351d5edf
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
preprocessorOverride: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,145 @@
|
||||
Shader "TextMeshPro/Bitmap Custom Atlas" {
|
||||
|
||||
Properties {
|
||||
_MainTex ("Font Atlas", 2D) = "white" {}
|
||||
_FaceTex ("Font Texture", 2D) = "white" {}
|
||||
_FaceColor ("Text Color", Color) = (1,1,1,1)
|
||||
|
||||
_VertexOffsetX ("Vertex OffsetX", float) = 0
|
||||
_VertexOffsetY ("Vertex OffsetY", float) = 0
|
||||
_MaskSoftnessX ("Mask SoftnessX", float) = 0
|
||||
_MaskSoftnessY ("Mask SoftnessY", float) = 0
|
||||
|
||||
_ClipRect ("Clip Rect", vector) = (-32767, -32767, 32767, 32767)
|
||||
_Padding ("Padding", float) = 0
|
||||
|
||||
_StencilComp ("Stencil Comparison", Float) = 8
|
||||
_Stencil ("Stencil ID", Float) = 0
|
||||
_StencilOp ("Stencil Operation", Float) = 0
|
||||
_StencilWriteMask ("Stencil Write Mask", Float) = 255
|
||||
_StencilReadMask ("Stencil Read Mask", Float) = 255
|
||||
|
||||
_CullMode ("Cull Mode", Float) = 0
|
||||
_ColorMask ("Color Mask", Float) = 15
|
||||
}
|
||||
|
||||
SubShader{
|
||||
|
||||
Tags { "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" }
|
||||
|
||||
Stencil
|
||||
{
|
||||
Ref[_Stencil]
|
||||
Comp[_StencilComp]
|
||||
Pass[_StencilOp]
|
||||
ReadMask[_StencilReadMask]
|
||||
WriteMask[_StencilWriteMask]
|
||||
}
|
||||
|
||||
|
||||
Lighting Off
|
||||
Cull [_CullMode]
|
||||
ZTest [unity_GUIZTestMode]
|
||||
ZWrite Off
|
||||
Fog { Mode Off }
|
||||
Blend SrcAlpha OneMinusSrcAlpha
|
||||
ColorMask[_ColorMask]
|
||||
|
||||
Pass {
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
|
||||
#pragma multi_compile __ UNITY_UI_CLIP_RECT
|
||||
#pragma multi_compile __ UNITY_UI_ALPHACLIP
|
||||
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
#include "UnityUI.cginc"
|
||||
|
||||
struct appdata_t
|
||||
{
|
||||
float4 vertex : POSITION;
|
||||
fixed4 color : COLOR;
|
||||
float4 texcoord0 : TEXCOORD0;
|
||||
float2 texcoord1 : TEXCOORD1;
|
||||
};
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float4 vertex : SV_POSITION;
|
||||
fixed4 color : COLOR;
|
||||
float2 texcoord0 : TEXCOORD0;
|
||||
float2 texcoord1 : TEXCOORD1;
|
||||
float4 mask : TEXCOORD2;
|
||||
};
|
||||
|
||||
uniform sampler2D _MainTex;
|
||||
uniform sampler2D _FaceTex;
|
||||
uniform float4 _FaceTex_ST;
|
||||
uniform fixed4 _FaceColor;
|
||||
|
||||
uniform float _VertexOffsetX;
|
||||
uniform float _VertexOffsetY;
|
||||
uniform float4 _ClipRect;
|
||||
uniform float _MaskSoftnessX;
|
||||
uniform float _MaskSoftnessY;
|
||||
uniform float _UIMaskSoftnessX;
|
||||
uniform float _UIMaskSoftnessY;
|
||||
uniform int _UIVertexColorAlwaysGammaSpace;
|
||||
|
||||
v2f vert (appdata_t v)
|
||||
{
|
||||
float4 vert = v.vertex;
|
||||
vert.x += _VertexOffsetX;
|
||||
vert.y += _VertexOffsetY;
|
||||
|
||||
vert.xy += (vert.w * 0.5) / _ScreenParams.xy;
|
||||
|
||||
float4 vPosition = UnityPixelSnap(UnityObjectToClipPos(vert));
|
||||
|
||||
if (_UIVertexColorAlwaysGammaSpace && !IsGammaSpace())
|
||||
{
|
||||
v.color.rgb = UIGammaToLinear(v.color.rgb);
|
||||
}
|
||||
fixed4 faceColor = v.color;
|
||||
faceColor *= _FaceColor;
|
||||
|
||||
v2f OUT;
|
||||
OUT.vertex = vPosition;
|
||||
OUT.color = faceColor;
|
||||
OUT.texcoord0 = v.texcoord0;
|
||||
OUT.texcoord1 = TRANSFORM_TEX(v.texcoord1, _FaceTex);
|
||||
float2 pixelSize = vPosition.w;
|
||||
pixelSize /= abs(float2(_ScreenParams.x * UNITY_MATRIX_P[0][0], _ScreenParams.y * UNITY_MATRIX_P[1][1]));
|
||||
|
||||
// Clamp _ClipRect to 16bit.
|
||||
const float4 clampedRect = clamp(_ClipRect, -2e10, 2e10);
|
||||
const half2 maskSoftness = half2(max(_UIMaskSoftnessX, _MaskSoftnessX), max(_UIMaskSoftnessY, _MaskSoftnessY));
|
||||
OUT.mask = float4(vert.xy * 2 - clampedRect.xy - clampedRect.zw, 0.25 / (0.25 * maskSoftness + pixelSize.xy));
|
||||
|
||||
return OUT;
|
||||
}
|
||||
|
||||
fixed4 frag (v2f IN) : SV_Target
|
||||
{
|
||||
fixed4 color = tex2D(_MainTex, IN.texcoord0) * tex2D(_FaceTex, IN.texcoord1) * IN.color;
|
||||
|
||||
// Alternative implementation to UnityGet2DClipping with support for softness.
|
||||
#if UNITY_UI_CLIP_RECT
|
||||
half2 m = saturate((_ClipRect.zw - _ClipRect.xy - abs(IN.mask.xy)) * IN.mask.zw);
|
||||
color *= m.x * m.y;
|
||||
#endif
|
||||
|
||||
#if UNITY_UI_ALPHACLIP
|
||||
clip(color.a - 0.001);
|
||||
#endif
|
||||
|
||||
return color;
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
CustomEditor "TMPro.EditorUtilities.TMP_BitmapShaderGUI"
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 48bb5f55d8670e349b6e614913f9d910
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,155 @@
|
||||
Shader "TextMeshPro/Mobile/Bitmap" {
|
||||
|
||||
Properties {
|
||||
_MainTex ("Font Atlas", 2D) = "white" {}
|
||||
_Color ("Text Color", Color) = (1,1,1,1)
|
||||
_DiffusePower ("Diffuse Power", Range(1.0,4.0)) = 1.0
|
||||
|
||||
_VertexOffsetX ("Vertex OffsetX", float) = 0
|
||||
_VertexOffsetY ("Vertex OffsetY", float) = 0
|
||||
_MaskSoftnessX ("Mask SoftnessX", float) = 0
|
||||
_MaskSoftnessY ("Mask SoftnessY", float) = 0
|
||||
|
||||
_ClipRect ("Clip Rect", vector) = (-32767, -32767, 32767, 32767)
|
||||
|
||||
_StencilComp ("Stencil Comparison", Float) = 8
|
||||
_Stencil ("Stencil ID", Float) = 0
|
||||
_StencilOp ("Stencil Operation", Float) = 0
|
||||
_StencilWriteMask ("Stencil Write Mask", Float) = 255
|
||||
_StencilReadMask ("Stencil Read Mask", Float) = 255
|
||||
|
||||
_CullMode ("Cull Mode", Float) = 0
|
||||
_ColorMask ("Color Mask", Float) = 15
|
||||
}
|
||||
|
||||
SubShader {
|
||||
|
||||
Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
|
||||
|
||||
Stencil
|
||||
{
|
||||
Ref[_Stencil]
|
||||
Comp[_StencilComp]
|
||||
Pass[_StencilOp]
|
||||
ReadMask[_StencilReadMask]
|
||||
WriteMask[_StencilWriteMask]
|
||||
}
|
||||
|
||||
|
||||
Lighting Off
|
||||
Cull [_CullMode]
|
||||
ZTest [unity_GUIZTestMode]
|
||||
ZWrite Off
|
||||
Fog { Mode Off }
|
||||
Blend SrcAlpha OneMinusSrcAlpha
|
||||
ColorMask[_ColorMask]
|
||||
|
||||
Pass {
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#pragma fragmentoption ARB_precision_hint_fastest
|
||||
|
||||
#pragma multi_compile __ UNITY_UI_CLIP_RECT
|
||||
#pragma multi_compile __ UNITY_UI_ALPHACLIP
|
||||
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
#include "UnityUI.cginc"
|
||||
|
||||
struct appdata_t
|
||||
{
|
||||
float4 vertex : POSITION;
|
||||
fixed4 color : COLOR;
|
||||
float2 texcoord0 : TEXCOORD0;
|
||||
float2 texcoord1 : TEXCOORD1;
|
||||
};
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float4 vertex : POSITION;
|
||||
fixed4 color : COLOR;
|
||||
float2 texcoord0 : TEXCOORD0;
|
||||
float4 mask : TEXCOORD2;
|
||||
};
|
||||
|
||||
sampler2D _MainTex;
|
||||
fixed4 _Color;
|
||||
float _DiffusePower;
|
||||
|
||||
uniform float _VertexOffsetX;
|
||||
uniform float _VertexOffsetY;
|
||||
uniform float4 _ClipRect;
|
||||
uniform float _MaskSoftnessX;
|
||||
uniform float _MaskSoftnessY;
|
||||
uniform float _UIMaskSoftnessX;
|
||||
uniform float _UIMaskSoftnessY;
|
||||
uniform int _UIVertexColorAlwaysGammaSpace;
|
||||
|
||||
v2f vert (appdata_t v)
|
||||
{
|
||||
v2f OUT;
|
||||
float4 vert = v.vertex;
|
||||
vert.x += _VertexOffsetX;
|
||||
vert.y += _VertexOffsetY;
|
||||
|
||||
vert.xy += (vert.w * 0.5) / _ScreenParams.xy;
|
||||
if (_UIVertexColorAlwaysGammaSpace && !IsGammaSpace())
|
||||
{
|
||||
v.color.rgb = UIGammaToLinear(v.color.rgb);
|
||||
}
|
||||
OUT.vertex = UnityPixelSnap(UnityObjectToClipPos(vert));
|
||||
OUT.color = v.color;
|
||||
OUT.color *= _Color;
|
||||
OUT.color.rgb *= _DiffusePower;
|
||||
OUT.texcoord0 = v.texcoord0;
|
||||
|
||||
float2 pixelSize = OUT.vertex.w;
|
||||
//pixelSize /= abs(float2(_ScreenParams.x * UNITY_MATRIX_P[0][0], _ScreenParams.y * UNITY_MATRIX_P[1][1]));
|
||||
|
||||
// Clamp _ClipRect to 16bit.
|
||||
const float4 clampedRect = clamp(_ClipRect, -2e10, 2e10);
|
||||
const half2 maskSoftness = half2(max(_UIMaskSoftnessX, _MaskSoftnessX), max(_UIMaskSoftnessY, _MaskSoftnessY));
|
||||
OUT.mask = float4(vert.xy * 2 - clampedRect.xy - clampedRect.zw, 0.25 / (0.25 * maskSoftness + pixelSize.xy));
|
||||
|
||||
return OUT;
|
||||
}
|
||||
|
||||
fixed4 frag (v2f IN) : COLOR
|
||||
{
|
||||
fixed4 color = fixed4(IN.color.rgb, IN.color.a * tex2D(_MainTex, IN.texcoord0).a);
|
||||
|
||||
// Alternative implementation to UnityGet2DClipping with support for softness.
|
||||
#if UNITY_UI_CLIP_RECT
|
||||
half2 m = saturate((_ClipRect.zw - _ClipRect.xy - abs(IN.mask.xy)) * IN.mask.zw);
|
||||
color *= m.x * m.y;
|
||||
#endif
|
||||
|
||||
#if UNITY_UI_ALPHACLIP
|
||||
clip(color.a - 0.001);
|
||||
#endif
|
||||
|
||||
return color;
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
SubShader {
|
||||
Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
|
||||
Lighting Off Cull Off ZTest Always ZWrite Off Fog { Mode Off }
|
||||
Blend SrcAlpha OneMinusSrcAlpha
|
||||
BindChannels {
|
||||
Bind "Color", color
|
||||
Bind "Vertex", vertex
|
||||
Bind "TexCoord", texcoord0
|
||||
}
|
||||
Pass {
|
||||
SetTexture [_MainTex] {
|
||||
constantColor [_Color] combine constant * primary, constant * texture
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CustomEditor "TMPro.EditorUtilities.TMP_BitmapShaderGUI"
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1e3b057af24249748ff873be7fafee47
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
Shader "TextMeshPro/Bitmap" {
|
||||
|
||||
Properties {
|
||||
_MainTex ("Font Atlas", 2D) = "white" {}
|
||||
_FaceTex ("Font Texture", 2D) = "white" {}
|
||||
_FaceColor ("Text Color", Color) = (1,1,1,1)
|
||||
|
||||
_VertexOffsetX ("Vertex OffsetX", float) = 0
|
||||
_VertexOffsetY ("Vertex OffsetY", float) = 0
|
||||
_MaskSoftnessX ("Mask SoftnessX", float) = 0
|
||||
_MaskSoftnessY ("Mask SoftnessY", float) = 0
|
||||
|
||||
_ClipRect ("Clip Rect", vector) = (-32767, -32767, 32767, 32767)
|
||||
|
||||
_StencilComp ("Stencil Comparison", Float) = 8
|
||||
_Stencil ("Stencil ID", Float) = 0
|
||||
_StencilOp ("Stencil Operation", Float) = 0
|
||||
_StencilWriteMask ("Stencil Write Mask", Float) = 255
|
||||
_StencilReadMask ("Stencil Read Mask", Float) = 255
|
||||
|
||||
_CullMode ("Cull Mode", Float) = 0
|
||||
_ColorMask ("Color Mask", Float) = 15
|
||||
}
|
||||
|
||||
SubShader{
|
||||
|
||||
Tags { "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" }
|
||||
|
||||
Stencil
|
||||
{
|
||||
Ref[_Stencil]
|
||||
Comp[_StencilComp]
|
||||
Pass[_StencilOp]
|
||||
ReadMask[_StencilReadMask]
|
||||
WriteMask[_StencilWriteMask]
|
||||
}
|
||||
|
||||
|
||||
Lighting Off
|
||||
Cull [_CullMode]
|
||||
ZTest [unity_GUIZTestMode]
|
||||
ZWrite Off
|
||||
Fog { Mode Off }
|
||||
Blend SrcAlpha OneMinusSrcAlpha
|
||||
ColorMask[_ColorMask]
|
||||
|
||||
Pass {
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
|
||||
#pragma multi_compile __ UNITY_UI_CLIP_RECT
|
||||
#pragma multi_compile __ UNITY_UI_ALPHACLIP
|
||||
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
#include "UnityUI.cginc"
|
||||
|
||||
struct appdata_t
|
||||
{
|
||||
float4 vertex : POSITION;
|
||||
fixed4 color : COLOR;
|
||||
float4 texcoord0 : TEXCOORD0;
|
||||
float2 texcoord1 : TEXCOORD1;
|
||||
};
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float4 vertex : SV_POSITION;
|
||||
fixed4 color : COLOR;
|
||||
float2 texcoord0 : TEXCOORD0;
|
||||
float2 texcoord1 : TEXCOORD1;
|
||||
float4 mask : TEXCOORD2;
|
||||
};
|
||||
|
||||
uniform sampler2D _MainTex;
|
||||
uniform sampler2D _FaceTex;
|
||||
uniform float4 _FaceTex_ST;
|
||||
uniform fixed4 _FaceColor;
|
||||
|
||||
uniform float _VertexOffsetX;
|
||||
uniform float _VertexOffsetY;
|
||||
uniform float4 _ClipRect;
|
||||
uniform float _MaskSoftnessX;
|
||||
uniform float _MaskSoftnessY;
|
||||
uniform float _UIMaskSoftnessX;
|
||||
uniform float _UIMaskSoftnessY;
|
||||
uniform int _UIVertexColorAlwaysGammaSpace;
|
||||
|
||||
v2f vert (appdata_t v)
|
||||
{
|
||||
float4 vert = v.vertex;
|
||||
vert.x += _VertexOffsetX;
|
||||
vert.y += _VertexOffsetY;
|
||||
|
||||
vert.xy += (vert.w * 0.5) / _ScreenParams.xy;
|
||||
|
||||
float4 vPosition = UnityPixelSnap(UnityObjectToClipPos(vert));
|
||||
|
||||
if (_UIVertexColorAlwaysGammaSpace && !IsGammaSpace())
|
||||
{
|
||||
v.color.rgb = UIGammaToLinear(v.color.rgb);
|
||||
}
|
||||
fixed4 faceColor = v.color;
|
||||
faceColor *= _FaceColor;
|
||||
|
||||
v2f OUT;
|
||||
OUT.vertex = vPosition;
|
||||
OUT.color = faceColor;
|
||||
OUT.texcoord0 = v.texcoord0;
|
||||
OUT.texcoord1 = TRANSFORM_TEX(v.texcoord1, _FaceTex);
|
||||
float2 pixelSize = vPosition.w;
|
||||
pixelSize /= abs(float2(_ScreenParams.x * UNITY_MATRIX_P[0][0], _ScreenParams.y * UNITY_MATRIX_P[1][1]));
|
||||
|
||||
// Clamp _ClipRect to 16bit.
|
||||
const float4 clampedRect = clamp(_ClipRect, -2e10, 2e10);
|
||||
const half2 maskSoftness = half2(max(_UIMaskSoftnessX, _MaskSoftnessX), max(_UIMaskSoftnessY, _MaskSoftnessY));
|
||||
OUT.mask = float4(vert.xy * 2 - clampedRect.xy - clampedRect.zw, 0.25 / (0.25 * maskSoftness + pixelSize.xy));
|
||||
|
||||
return OUT;
|
||||
}
|
||||
|
||||
fixed4 frag (v2f IN) : SV_Target
|
||||
{
|
||||
fixed4 color = tex2D(_MainTex, IN.texcoord0);
|
||||
color = fixed4 (tex2D(_FaceTex, IN.texcoord1).rgb * IN.color.rgb, IN.color.a * color.a);
|
||||
|
||||
// Alternative implementation to UnityGet2DClipping with support for softness.
|
||||
#if UNITY_UI_CLIP_RECT
|
||||
half2 m = saturate((_ClipRect.zw - _ClipRect.xy - abs(IN.mask.xy)) * IN.mask.zw);
|
||||
color *= m.x * m.y;
|
||||
#endif
|
||||
|
||||
#if UNITY_UI_ALPHACLIP
|
||||
clip(color.a - 0.001);
|
||||
#endif
|
||||
|
||||
return color;
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
CustomEditor "TMPro.EditorUtilities.TMP_BitmapShaderGUI"
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 128e987d567d4e2c824d754223b3f3b0
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+326
@@ -0,0 +1,326 @@
|
||||
Shader "TextMeshPro/Distance Field Overlay" {
|
||||
|
||||
Properties {
|
||||
_FaceTex ("Face Texture", 2D) = "white" {}
|
||||
_FaceUVSpeedX ("Face UV Speed X", Range(-5, 5)) = 0.0
|
||||
_FaceUVSpeedY ("Face UV Speed Y", Range(-5, 5)) = 0.0
|
||||
_FaceColor ("Face Color", Color) = (1,1,1,1)
|
||||
_FaceDilate ("Face Dilate", Range(-1,1)) = 0
|
||||
|
||||
_OutlineColor ("Outline Color", Color) = (0,0,0,1)
|
||||
_OutlineTex ("Outline Texture", 2D) = "white" {}
|
||||
_OutlineUVSpeedX ("Outline UV Speed X", Range(-5, 5)) = 0.0
|
||||
_OutlineUVSpeedY ("Outline UV Speed Y", Range(-5, 5)) = 0.0
|
||||
_OutlineWidth ("Outline Thickness", Range(0, 1)) = 0
|
||||
_OutlineSoftness ("Outline Softness", Range(0,1)) = 0
|
||||
|
||||
_Bevel ("Bevel", Range(0,1)) = 0.5
|
||||
_BevelOffset ("Bevel Offset", Range(-0.5,0.5)) = 0
|
||||
_BevelWidth ("Bevel Width", Range(-.5,0.5)) = 0
|
||||
_BevelClamp ("Bevel Clamp", Range(0,1)) = 0
|
||||
_BevelRoundness ("Bevel Roundness", Range(0,1)) = 0
|
||||
|
||||
_LightAngle ("Light Angle", Range(0.0, 6.2831853)) = 3.1416
|
||||
_SpecularColor ("Specular", Color) = (1,1,1,1)
|
||||
_SpecularPower ("Specular", Range(0,4)) = 2.0
|
||||
_Reflectivity ("Reflectivity", Range(5.0,15.0)) = 10
|
||||
_Diffuse ("Diffuse", Range(0,1)) = 0.5
|
||||
_Ambient ("Ambient", Range(1,0)) = 0.5
|
||||
|
||||
_BumpMap ("Normal map", 2D) = "bump" {}
|
||||
_BumpOutline ("Bump Outline", Range(0,1)) = 0
|
||||
_BumpFace ("Bump Face", Range(0,1)) = 0
|
||||
|
||||
_ReflectFaceColor ("Reflection Color", Color) = (0,0,0,1)
|
||||
_ReflectOutlineColor("Reflection Color", Color) = (0,0,0,1)
|
||||
_Cube ("Reflection Cubemap", Cube) = "black" { /* TexGen CubeReflect */ }
|
||||
_EnvMatrixRotation ("Texture Rotation", vector) = (0, 0, 0, 0)
|
||||
|
||||
|
||||
_UnderlayColor ("Border Color", Color) = (0,0,0, 0.5)
|
||||
_UnderlayOffsetX ("Border OffsetX", Range(-1,1)) = 0
|
||||
_UnderlayOffsetY ("Border OffsetY", Range(-1,1)) = 0
|
||||
_UnderlayDilate ("Border Dilate", Range(-1,1)) = 0
|
||||
_UnderlaySoftness ("Border Softness", Range(0,1)) = 0
|
||||
|
||||
_GlowColor ("Color", Color) = (0, 1, 0, 0.5)
|
||||
_GlowOffset ("Offset", Range(-1,1)) = 0
|
||||
_GlowInner ("Inner", Range(0,1)) = 0.05
|
||||
_GlowOuter ("Outer", Range(0,1)) = 0.05
|
||||
_GlowPower ("Falloff", Range(1, 0)) = 0.75
|
||||
|
||||
_WeightNormal ("Weight Normal", float) = 0
|
||||
_WeightBold ("Weight Bold", float) = 0.5
|
||||
|
||||
_ShaderFlags ("Flags", float) = 0
|
||||
_ScaleRatioA ("Scale RatioA", float) = 1
|
||||
_ScaleRatioB ("Scale RatioB", float) = 1
|
||||
_ScaleRatioC ("Scale RatioC", float) = 1
|
||||
|
||||
_MainTex ("Font Atlas", 2D) = "white" {}
|
||||
_TextureWidth ("Texture Width", float) = 512
|
||||
_TextureHeight ("Texture Height", float) = 512
|
||||
_GradientScale ("Gradient Scale", float) = 5.0
|
||||
_ScaleX ("Scale X", float) = 1.0
|
||||
_ScaleY ("Scale Y", float) = 1.0
|
||||
_PerspectiveFilter ("Perspective Correction", Range(0, 1)) = 0.875
|
||||
_Sharpness ("Sharpness", Range(-1,1)) = 0
|
||||
|
||||
_VertexOffsetX ("Vertex OffsetX", float) = 0
|
||||
_VertexOffsetY ("Vertex OffsetY", float) = 0
|
||||
|
||||
_MaskCoord ("Mask Coordinates", vector) = (0, 0, 32767, 32767)
|
||||
_ClipRect ("Clip Rect", vector) = (-32767, -32767, 32767, 32767)
|
||||
_MaskSoftnessX ("Mask SoftnessX", float) = 0
|
||||
_MaskSoftnessY ("Mask SoftnessY", float) = 0
|
||||
|
||||
_StencilComp ("Stencil Comparison", Float) = 8
|
||||
_Stencil ("Stencil ID", Float) = 0
|
||||
_StencilOp ("Stencil Operation", Float) = 0
|
||||
_StencilWriteMask ("Stencil Write Mask", Float) = 255
|
||||
_StencilReadMask ("Stencil Read Mask", Float) = 255
|
||||
|
||||
_CullMode ("Cull Mode", Float) = 0
|
||||
_ColorMask ("Color Mask", Float) = 15
|
||||
}
|
||||
|
||||
SubShader {
|
||||
|
||||
Tags
|
||||
{
|
||||
"Queue"="Overlay"
|
||||
"IgnoreProjector"="True"
|
||||
"RenderType"="Transparent"
|
||||
}
|
||||
|
||||
Stencil
|
||||
{
|
||||
Ref [_Stencil]
|
||||
Comp [_StencilComp]
|
||||
Pass [_StencilOp]
|
||||
ReadMask [_StencilReadMask]
|
||||
WriteMask [_StencilWriteMask]
|
||||
}
|
||||
|
||||
Cull [_CullMode]
|
||||
ZWrite Off
|
||||
Lighting Off
|
||||
Fog { Mode Off }
|
||||
ZTest Always
|
||||
Blend One OneMinusSrcAlpha
|
||||
ColorMask [_ColorMask]
|
||||
|
||||
Pass {
|
||||
CGPROGRAM
|
||||
#pragma target 3.0
|
||||
#pragma vertex VertShader
|
||||
#pragma fragment PixShader
|
||||
#pragma shader_feature __ BEVEL_ON
|
||||
#pragma shader_feature __ UNDERLAY_ON UNDERLAY_INNER
|
||||
#pragma shader_feature __ GLOW_ON
|
||||
|
||||
#pragma multi_compile __ UNITY_UI_CLIP_RECT
|
||||
#pragma multi_compile __ UNITY_UI_ALPHACLIP
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
#include "UnityUI.cginc"
|
||||
#include "TMPro_Properties.cginc"
|
||||
#include "TMPro.cginc"
|
||||
|
||||
struct vertex_t
|
||||
{
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
float4 position : POSITION;
|
||||
float3 normal : NORMAL;
|
||||
fixed4 color : COLOR;
|
||||
float4 texcoord0 : TEXCOORD0;
|
||||
float2 texcoord1 : TEXCOORD1;
|
||||
};
|
||||
|
||||
struct pixel_t
|
||||
{
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
UNITY_VERTEX_OUTPUT_STEREO
|
||||
float4 position : SV_POSITION;
|
||||
fixed4 color : COLOR;
|
||||
float2 atlas : TEXCOORD0; // Atlas
|
||||
float4 param : TEXCOORD1; // alphaClip, scale, bias, weight
|
||||
float4 mask : TEXCOORD2; // Position in object space(xy), pixel Size(zw)
|
||||
float3 viewDir : TEXCOORD3;
|
||||
|
||||
#if (UNDERLAY_ON || UNDERLAY_INNER)
|
||||
float4 texcoord2 : TEXCOORD4; // u,v, scale, bias
|
||||
fixed4 underlayColor : COLOR1;
|
||||
#endif
|
||||
|
||||
float4 textures : TEXCOORD5;
|
||||
};
|
||||
|
||||
// Used by Unity internally to handle Texture Tiling and Offset.
|
||||
uniform float4 _FaceTex_ST;
|
||||
uniform float4 _OutlineTex_ST;
|
||||
uniform float _UIMaskSoftnessX;
|
||||
uniform float _UIMaskSoftnessY;
|
||||
uniform int _UIVertexColorAlwaysGammaSpace;
|
||||
|
||||
pixel_t VertShader(vertex_t input)
|
||||
{
|
||||
pixel_t output;
|
||||
|
||||
UNITY_INITIALIZE_OUTPUT(pixel_t, output);
|
||||
UNITY_SETUP_INSTANCE_ID(input);
|
||||
UNITY_TRANSFER_INSTANCE_ID(input,output);
|
||||
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
|
||||
|
||||
float bold = step(input.texcoord0.w, 0);
|
||||
|
||||
float4 vert = input.position;
|
||||
vert.x += _VertexOffsetX;
|
||||
vert.y += _VertexOffsetY;
|
||||
|
||||
float4 vPosition = UnityObjectToClipPos(vert);
|
||||
|
||||
float2 pixelSize = vPosition.w;
|
||||
pixelSize /= float2(_ScaleX, _ScaleY) * abs(mul((float2x2)UNITY_MATRIX_P, _ScreenParams.xy));
|
||||
float scale = rsqrt(dot(pixelSize, pixelSize));
|
||||
scale *= abs(input.texcoord0.w) * _GradientScale * (_Sharpness + 1);
|
||||
if (UNITY_MATRIX_P[3][3] == 0) scale = lerp(abs(scale) * (1 - _PerspectiveFilter), scale, abs(dot(UnityObjectToWorldNormal(input.normal.xyz), normalize(WorldSpaceViewDir(vert)))));
|
||||
|
||||
float weight = lerp(_WeightNormal, _WeightBold, bold) / 4.0;
|
||||
weight = (weight + _FaceDilate) * _ScaleRatioA * 0.5;
|
||||
|
||||
float bias =(.5 - weight) + (.5 / scale);
|
||||
|
||||
float alphaClip = (1.0 - _OutlineWidth*_ScaleRatioA - _OutlineSoftness*_ScaleRatioA);
|
||||
|
||||
#if GLOW_ON
|
||||
alphaClip = min(alphaClip, 1.0 - _GlowOffset * _ScaleRatioB - _GlowOuter * _ScaleRatioB);
|
||||
#endif
|
||||
|
||||
alphaClip = alphaClip / 2.0 - ( .5 / scale) - weight;
|
||||
|
||||
#if (UNDERLAY_ON || UNDERLAY_INNER)
|
||||
float4 underlayColor = _UnderlayColor;
|
||||
underlayColor.rgb *= underlayColor.a;
|
||||
|
||||
float bScale = scale;
|
||||
bScale /= 1 + ((_UnderlaySoftness*_ScaleRatioC) * bScale);
|
||||
float bBias = (0.5 - weight) * bScale - 0.5 - ((_UnderlayDilate * _ScaleRatioC) * 0.5 * bScale);
|
||||
|
||||
float x = -(_UnderlayOffsetX * _ScaleRatioC) * _GradientScale / _TextureWidth;
|
||||
float y = -(_UnderlayOffsetY * _ScaleRatioC) * _GradientScale / _TextureHeight;
|
||||
float2 bOffset = float2(x, y);
|
||||
#endif
|
||||
|
||||
// Generate UV for the Masking Texture
|
||||
float4 clampedRect = clamp(_ClipRect, -2e10, 2e10);
|
||||
float2 maskUV = (vert.xy - clampedRect.xy) / (clampedRect.zw - clampedRect.xy);
|
||||
|
||||
// Support for texture tiling and offset
|
||||
float2 textureUV = input.texcoord1;
|
||||
float2 faceUV = TRANSFORM_TEX(textureUV, _FaceTex);
|
||||
float2 outlineUV = TRANSFORM_TEX(textureUV, _OutlineTex);
|
||||
|
||||
|
||||
if (_UIVertexColorAlwaysGammaSpace && !IsGammaSpace())
|
||||
{
|
||||
input.color.rgb = UIGammaToLinear(input.color.rgb);
|
||||
}
|
||||
output.position = vPosition;
|
||||
output.color = input.color;
|
||||
output.atlas = input.texcoord0;
|
||||
output.param = float4(alphaClip, scale, bias, weight);
|
||||
const half2 maskSoftness = half2(max(_UIMaskSoftnessX, _MaskSoftnessX), max(_UIMaskSoftnessY, _MaskSoftnessY));
|
||||
output.mask = half4(vert.xy * 2 - clampedRect.xy - clampedRect.zw, 0.25 / (0.25 * maskSoftness + pixelSize.xy));
|
||||
output.viewDir = mul((float3x3)_EnvMatrix, _WorldSpaceCameraPos.xyz - mul(unity_ObjectToWorld, vert).xyz);
|
||||
#if (UNDERLAY_ON || UNDERLAY_INNER)
|
||||
output.texcoord2 = float4(input.texcoord0 + bOffset, bScale, bBias);
|
||||
output.underlayColor = underlayColor;
|
||||
#endif
|
||||
output.textures = float4(faceUV, outlineUV);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
fixed4 PixShader(pixel_t input) : SV_Target
|
||||
{
|
||||
UNITY_SETUP_INSTANCE_ID(input);
|
||||
|
||||
float c = tex2D(_MainTex, input.atlas).a;
|
||||
|
||||
#ifndef UNDERLAY_ON
|
||||
clip(c - input.param.x);
|
||||
#endif
|
||||
|
||||
float scale = input.param.y;
|
||||
float bias = input.param.z;
|
||||
float weight = input.param.w;
|
||||
float sd = (bias - c) * scale;
|
||||
|
||||
float outline = (_OutlineWidth * _ScaleRatioA) * scale;
|
||||
float softness = (_OutlineSoftness * _ScaleRatioA) * scale;
|
||||
|
||||
half4 faceColor = _FaceColor;
|
||||
half4 outlineColor = _OutlineColor;
|
||||
|
||||
faceColor.rgb *= input.color.rgb;
|
||||
|
||||
faceColor *= tex2D(_FaceTex, input.textures.xy + float2(_FaceUVSpeedX, _FaceUVSpeedY) * _Time.y);
|
||||
outlineColor *= tex2D(_OutlineTex, input.textures.zw + float2(_OutlineUVSpeedX, _OutlineUVSpeedY) * _Time.y);
|
||||
|
||||
faceColor = GetColor(sd, faceColor, outlineColor, outline, softness);
|
||||
|
||||
#if BEVEL_ON
|
||||
float3 dxy = float3(0.5 / _TextureWidth, 0.5 / _TextureHeight, 0);
|
||||
float3 n = GetSurfaceNormal(input.atlas, weight, dxy);
|
||||
|
||||
float3 bump = UnpackNormal(tex2D(_BumpMap, input.textures.xy + float2(_FaceUVSpeedX, _FaceUVSpeedY) * _Time.y)).xyz;
|
||||
bump *= lerp(_BumpFace, _BumpOutline, saturate(sd + outline * 0.5));
|
||||
n = normalize(n- bump);
|
||||
|
||||
float3 light = normalize(float3(sin(_LightAngle), cos(_LightAngle), -1.0));
|
||||
|
||||
float3 col = GetSpecular(n, light);
|
||||
faceColor.rgb += col*faceColor.a;
|
||||
faceColor.rgb *= 1-(dot(n, light)*_Diffuse);
|
||||
faceColor.rgb *= lerp(_Ambient, 1, n.z*n.z);
|
||||
|
||||
fixed4 reflcol = texCUBE(_Cube, reflect(input.viewDir, -n));
|
||||
faceColor.rgb += reflcol.rgb * lerp(_ReflectFaceColor.rgb, _ReflectOutlineColor.rgb, saturate(sd + outline * 0.5)) * faceColor.a;
|
||||
#endif
|
||||
|
||||
#if UNDERLAY_ON
|
||||
float d = tex2D(_MainTex, input.texcoord2.xy).a * input.texcoord2.z;
|
||||
faceColor += input.underlayColor * saturate(d - input.texcoord2.w) * (1 - faceColor.a);
|
||||
#endif
|
||||
|
||||
#if UNDERLAY_INNER
|
||||
float d = tex2D(_MainTex, input.texcoord2.xy).a * input.texcoord2.z;
|
||||
faceColor += input.underlayColor * (1 - saturate(d - input.texcoord2.w)) * saturate(1 - sd) * (1 - faceColor.a);
|
||||
#endif
|
||||
|
||||
#if GLOW_ON
|
||||
float4 glowColor = GetGlowColor(sd, scale);
|
||||
faceColor.rgb += glowColor.rgb * glowColor.a;
|
||||
#endif
|
||||
|
||||
// Alternative implementation to UnityGet2DClipping with support for softness.
|
||||
#if UNITY_UI_CLIP_RECT
|
||||
half2 m = saturate((_ClipRect.zw - _ClipRect.xy - abs(input.mask.xy)) * input.mask.zw);
|
||||
faceColor *= m.x * m.y;
|
||||
#endif
|
||||
|
||||
#if UNITY_UI_ALPHACLIP
|
||||
clip(faceColor.a - 0.001);
|
||||
#endif
|
||||
|
||||
return faceColor * input.color.a;
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
Fallback "TextMeshPro/Mobile/Distance Field"
|
||||
CustomEditor "TMPro.EditorUtilities.TMP_SDFShaderGUI"
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dd89cf5b9246416f84610a006f916af7
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+321
@@ -0,0 +1,321 @@
|
||||
Shader "TextMeshPro/Distance Field SSD" {
|
||||
|
||||
Properties {
|
||||
_FaceTex ("Face Texture", 2D) = "white" {}
|
||||
_FaceUVSpeedX ("Face UV Speed X", Range(-5, 5)) = 0.0
|
||||
_FaceUVSpeedY ("Face UV Speed Y", Range(-5, 5)) = 0.0
|
||||
_FaceColor ("Face Color", Color) = (1,1,1,1)
|
||||
_FaceDilate ("Face Dilate", Range(-1,1)) = 0
|
||||
|
||||
_OutlineColor ("Outline Color", Color) = (0,0,0,1)
|
||||
_OutlineTex ("Outline Texture", 2D) = "white" {}
|
||||
_OutlineUVSpeedX ("Outline UV Speed X", Range(-5, 5)) = 0.0
|
||||
_OutlineUVSpeedY ("Outline UV Speed Y", Range(-5, 5)) = 0.0
|
||||
_OutlineWidth ("Outline Thickness", Range(0, 1)) = 0
|
||||
_OutlineSoftness ("Outline Softness", Range(0,1)) = 0
|
||||
|
||||
_Bevel ("Bevel", Range(0,1)) = 0.5
|
||||
_BevelOffset ("Bevel Offset", Range(-0.5,0.5)) = 0
|
||||
_BevelWidth ("Bevel Width", Range(-.5,0.5)) = 0
|
||||
_BevelClamp ("Bevel Clamp", Range(0,1)) = 0
|
||||
_BevelRoundness ("Bevel Roundness", Range(0,1)) = 0
|
||||
|
||||
_LightAngle ("Light Angle", Range(0.0, 6.2831853)) = 3.1416
|
||||
_SpecularColor ("Specular", Color) = (1,1,1,1)
|
||||
_SpecularPower ("Specular", Range(0,4)) = 2.0
|
||||
_Reflectivity ("Reflectivity", Range(5.0,15.0)) = 10
|
||||
_Diffuse ("Diffuse", Range(0,1)) = 0.5
|
||||
_Ambient ("Ambient", Range(1,0)) = 0.5
|
||||
|
||||
_BumpMap ("Normal map", 2D) = "bump" {}
|
||||
_BumpOutline ("Bump Outline", Range(0,1)) = 0
|
||||
_BumpFace ("Bump Face", Range(0,1)) = 0
|
||||
|
||||
_ReflectFaceColor ("Reflection Color", Color) = (0,0,0,1)
|
||||
_ReflectOutlineColor("Reflection Color", Color) = (0,0,0,1)
|
||||
_Cube ("Reflection Cubemap", Cube) = "black" { /* TexGen CubeReflect */ }
|
||||
_EnvMatrixRotation ("Texture Rotation", vector) = (0, 0, 0, 0)
|
||||
|
||||
|
||||
_UnderlayColor ("Border Color", Color) = (0,0,0, 0.5)
|
||||
_UnderlayOffsetX ("Border OffsetX", Range(-1,1)) = 0
|
||||
_UnderlayOffsetY ("Border OffsetY", Range(-1,1)) = 0
|
||||
_UnderlayDilate ("Border Dilate", Range(-1,1)) = 0
|
||||
_UnderlaySoftness ("Border Softness", Range(0,1)) = 0
|
||||
|
||||
_GlowColor ("Color", Color) = (0, 1, 0, 0.5)
|
||||
_GlowOffset ("Offset", Range(-1,1)) = 0
|
||||
_GlowInner ("Inner", Range(0,1)) = 0.05
|
||||
_GlowOuter ("Outer", Range(0,1)) = 0.05
|
||||
_GlowPower ("Falloff", Range(1, 0)) = 0.75
|
||||
|
||||
_WeightNormal ("Weight Normal", float) = 0
|
||||
_WeightBold ("Weight Bold", float) = 0.5
|
||||
|
||||
_ShaderFlags ("Flags", float) = 0
|
||||
_ScaleRatioA ("Scale RatioA", float) = 1
|
||||
_ScaleRatioB ("Scale RatioB", float) = 1
|
||||
_ScaleRatioC ("Scale RatioC", float) = 1
|
||||
|
||||
_MainTex ("Font Atlas", 2D) = "white" {}
|
||||
_TextureWidth ("Texture Width", float) = 512
|
||||
_TextureHeight ("Texture Height", float) = 512
|
||||
_GradientScale ("Gradient Scale", float) = 5.0
|
||||
_ScaleX ("Scale X", float) = 1.0
|
||||
_ScaleY ("Scale Y", float) = 1.0
|
||||
_PerspectiveFilter ("Perspective Correction", Range(0, 1)) = 0.875
|
||||
_Sharpness ("Sharpness", Range(-1,1)) = 0
|
||||
|
||||
_VertexOffsetX ("Vertex OffsetX", float) = 0
|
||||
_VertexOffsetY ("Vertex OffsetY", float) = 0
|
||||
|
||||
_MaskCoord ("Mask Coordinates", vector) = (0, 0, 32767, 32767)
|
||||
_ClipRect ("Clip Rect", vector) = (-32767, -32767, 32767, 32767)
|
||||
_MaskSoftnessX ("Mask SoftnessX", float) = 0
|
||||
_MaskSoftnessY ("Mask SoftnessY", float) = 0
|
||||
|
||||
_StencilComp ("Stencil Comparison", Float) = 8
|
||||
_Stencil ("Stencil ID", Float) = 0
|
||||
_StencilOp ("Stencil Operation", Float) = 0
|
||||
_StencilWriteMask ("Stencil Write Mask", Float) = 255
|
||||
_StencilReadMask ("Stencil Read Mask", Float) = 255
|
||||
|
||||
_CullMode ("Cull Mode", Float) = 0
|
||||
_ColorMask ("Color Mask", Float) = 15
|
||||
}
|
||||
|
||||
SubShader {
|
||||
Tags
|
||||
{
|
||||
"Queue" = "Transparent"
|
||||
"IgnoreProjector" = "True"
|
||||
"RenderType" = "Transparent"
|
||||
}
|
||||
|
||||
Stencil
|
||||
{
|
||||
Ref[_Stencil]
|
||||
Comp[_StencilComp]
|
||||
Pass[_StencilOp]
|
||||
ReadMask[_StencilReadMask]
|
||||
WriteMask[_StencilWriteMask]
|
||||
}
|
||||
|
||||
Cull[_CullMode]
|
||||
ZWrite Off
|
||||
Lighting Off
|
||||
Fog { Mode Off }
|
||||
ZTest[unity_GUIZTestMode]
|
||||
Blend One OneMinusSrcAlpha
|
||||
ColorMask[_ColorMask]
|
||||
|
||||
Pass
|
||||
{
|
||||
CGPROGRAM
|
||||
#pragma target 3.0
|
||||
#pragma vertex VertShader
|
||||
#pragma fragment PixShader
|
||||
#pragma shader_feature __ BEVEL_ON
|
||||
#pragma shader_feature __ UNDERLAY_ON UNDERLAY_INNER
|
||||
#pragma shader_feature __ GLOW_ON
|
||||
#pragma shader_feature __ FORCE_LINEAR
|
||||
|
||||
#pragma multi_compile __ UNITY_UI_CLIP_RECT
|
||||
#pragma multi_compile __ UNITY_UI_ALPHACLIP
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
#include "UnityUI.cginc"
|
||||
#include "TMPro_Properties.cginc"
|
||||
#include "TMPro.cginc"
|
||||
|
||||
struct vertex_t
|
||||
{
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
float4 position : POSITION;
|
||||
float3 normal : NORMAL;
|
||||
float4 color : COLOR;
|
||||
float4 texcoord0 : TEXCOORD0;
|
||||
float2 texcoord1 : TEXCOORD1;
|
||||
};
|
||||
|
||||
struct pixel_t
|
||||
{
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
UNITY_VERTEX_OUTPUT_STEREO
|
||||
float4 position : SV_POSITION;
|
||||
float4 color : COLOR;
|
||||
float2 atlas : TEXCOORD0;
|
||||
float weight : TEXCOORD1;
|
||||
float2 mask : TEXCOORD2; // Position in object space(xy)
|
||||
float3 viewDir : TEXCOORD3;
|
||||
|
||||
#if (UNDERLAY_ON || UNDERLAY_INNER)
|
||||
float2 texcoord2 : TEXCOORD4;
|
||||
float4 underlayColor : COLOR1;
|
||||
#endif
|
||||
|
||||
float4 textures : TEXCOORD5;
|
||||
};
|
||||
|
||||
// Used by Unity internally to handle Texture Tiling and Offset.
|
||||
float4 _FaceTex_ST;
|
||||
float4 _OutlineTex_ST;
|
||||
float _UIMaskSoftnessX;
|
||||
float _UIMaskSoftnessY;
|
||||
int _UIVertexColorAlwaysGammaSpace;
|
||||
|
||||
float4 SRGBToLinear(float4 rgba)
|
||||
{
|
||||
return float4(lerp(rgba.rgb / 12.92f, pow((rgba.rgb + 0.055f) / 1.055f, 2.4f), step(0.04045f, rgba.rgb)), rgba.a);
|
||||
}
|
||||
|
||||
pixel_t VertShader(vertex_t input)
|
||||
{
|
||||
pixel_t output;
|
||||
|
||||
UNITY_INITIALIZE_OUTPUT(pixel_t, output);
|
||||
UNITY_SETUP_INSTANCE_ID(input);
|
||||
UNITY_TRANSFER_INSTANCE_ID(input,output);
|
||||
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
|
||||
|
||||
float bold = step(input.texcoord0.w, 0);
|
||||
|
||||
float4 vert = input.position;
|
||||
vert.x += _VertexOffsetX;
|
||||
vert.y += _VertexOffsetY;
|
||||
|
||||
float4 vPosition = UnityObjectToClipPos(vert);
|
||||
|
||||
float weight = lerp(_WeightNormal, _WeightBold, bold) / 4.0;
|
||||
weight = (weight + _FaceDilate) * _ScaleRatioA * 0.5;
|
||||
|
||||
#if (UNDERLAY_ON || UNDERLAY_INNER)
|
||||
float4 underlayColor = _UnderlayColor;
|
||||
underlayColor.rgb *= underlayColor.a;
|
||||
|
||||
float x = -(_UnderlayOffsetX * _ScaleRatioC) * _GradientScale / _TextureWidth;
|
||||
float y = -(_UnderlayOffsetY * _ScaleRatioC) * _GradientScale / _TextureHeight;
|
||||
float2 bOffset = float2(x, y);
|
||||
#endif
|
||||
|
||||
// Generate UV for the Masking Texture
|
||||
float4 clampedRect = clamp(_ClipRect, -2e10, 2e10);
|
||||
|
||||
// Support for texture tiling and offset
|
||||
float2 textureUV = input.texcoord1;
|
||||
float2 faceUV = TRANSFORM_TEX(textureUV, _FaceTex);
|
||||
float2 outlineUV = TRANSFORM_TEX(textureUV, _OutlineTex);
|
||||
|
||||
if (_UIVertexColorAlwaysGammaSpace && !IsGammaSpace())
|
||||
{
|
||||
input.color.rgb = UIGammaToLinear(input.color.rgb);
|
||||
}
|
||||
float4 color = input.color;
|
||||
#if (FORCE_LINEAR && !UNITY_COLORSPACE_GAMMA)
|
||||
color = SRGBToLinear(input.color);
|
||||
#endif
|
||||
|
||||
output.position = vPosition;
|
||||
output.color = color;
|
||||
output.atlas = input.texcoord0;
|
||||
output.weight = weight;
|
||||
output.mask = half2(vert.xy * 2 - clampedRect.xy - clampedRect.zw);
|
||||
output.viewDir = mul((float3x3)_EnvMatrix, _WorldSpaceCameraPos.xyz - mul(unity_ObjectToWorld, vert).xyz);
|
||||
#if (UNDERLAY_ON || UNDERLAY_INNER)
|
||||
output.texcoord2 = input.texcoord0 + bOffset;
|
||||
output.underlayColor = underlayColor;
|
||||
#endif
|
||||
output.textures = float4(faceUV, outlineUV);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
fixed4 PixShader(pixel_t input) : SV_Target
|
||||
{
|
||||
UNITY_SETUP_INSTANCE_ID(input);
|
||||
|
||||
float c = tex2D(_MainTex, input.atlas).a;
|
||||
|
||||
float pixelSize = abs(ddx(input.atlas.y)) + abs(ddy(input.atlas.y));
|
||||
pixelSize *= _TextureHeight * 0.75;
|
||||
float scale = 1 / pixelSize * _GradientScale * (_Sharpness + 1);
|
||||
|
||||
float weight = input.weight;
|
||||
float bias = (.5 - weight) + (.5 / scale);
|
||||
float sd = (bias - c) * scale;
|
||||
|
||||
float outline = (_OutlineWidth * _ScaleRatioA) * scale;
|
||||
float softness = (_OutlineSoftness * _ScaleRatioA) * scale;
|
||||
|
||||
half4 faceColor = _FaceColor;
|
||||
half4 outlineColor = _OutlineColor;
|
||||
|
||||
faceColor.rgb *= input.color.rgb;
|
||||
|
||||
faceColor *= tex2D(_FaceTex, input.textures.xy + float2(_FaceUVSpeedX, _FaceUVSpeedY) * _Time.y);
|
||||
outlineColor *= tex2D(_OutlineTex, input.textures.zw + float2(_OutlineUVSpeedX, _OutlineUVSpeedY) * _Time.y);
|
||||
|
||||
faceColor = GetColor(sd, faceColor, outlineColor, outline, softness);
|
||||
|
||||
#if BEVEL_ON
|
||||
float3 dxy = float3(0.5 / _TextureWidth, 0.5 / _TextureHeight, 0);
|
||||
float3 n = GetSurfaceNormal(input.atlas, weight, dxy);
|
||||
|
||||
float3 bump = UnpackNormal(tex2D(_BumpMap, input.textures.xy + float2(_FaceUVSpeedX, _FaceUVSpeedY) * _Time.y)).xyz;
|
||||
bump *= lerp(_BumpFace, _BumpOutline, saturate(sd + outline * 0.5));
|
||||
n = normalize(n - bump);
|
||||
|
||||
float3 light = normalize(float3(sin(_LightAngle), cos(_LightAngle), -1.0));
|
||||
|
||||
float3 col = GetSpecular(n, light);
|
||||
faceColor.rgb += col * faceColor.a;
|
||||
faceColor.rgb *= 1 - (dot(n, light) * _Diffuse);
|
||||
faceColor.rgb *= lerp(_Ambient, 1, n.z * n.z);
|
||||
|
||||
fixed4 reflcol = texCUBE(_Cube, reflect(input.viewDir, -n));
|
||||
faceColor.rgb += reflcol.rgb * lerp(_ReflectFaceColor.rgb, _ReflectOutlineColor.rgb, saturate(sd + outline * 0.5)) * faceColor.a;
|
||||
#endif
|
||||
|
||||
#if (UNDERLAY_ON || UNDERLAY_INNER)
|
||||
float bScale = scale;
|
||||
bScale /= 1 + ((_UnderlaySoftness * _ScaleRatioC) * bScale);
|
||||
float bBias = (0.5 - weight) * bScale - 0.5 - ((_UnderlayDilate * _ScaleRatioC) * 0.5 * bScale);
|
||||
#endif
|
||||
|
||||
#if UNDERLAY_ON
|
||||
float d = tex2D(_MainTex, input.texcoord2.xy).a * bScale;
|
||||
faceColor += input.underlayColor * saturate(d - bBias) * (1 - faceColor.a);
|
||||
#endif
|
||||
|
||||
#if UNDERLAY_INNER
|
||||
float d = tex2D(_MainTex, input.texcoord2.xy).a * bScale;
|
||||
faceColor += input.underlayColor * (1 - saturate(d - bBias)) * saturate(1 - sd) * (1 - faceColor.a);
|
||||
#endif
|
||||
|
||||
#if GLOW_ON
|
||||
float4 glowColor = GetGlowColor(sd, scale);
|
||||
faceColor.rgb += glowColor.rgb * glowColor.a;
|
||||
#endif
|
||||
|
||||
// Alternative implementation to UnityGet2DClipping with support for softness.
|
||||
#if UNITY_UI_CLIP_RECT
|
||||
half2 maskSoftness = half2(max(_UIMaskSoftnessX, _MaskSoftnessX), max(_UIMaskSoftnessY, _MaskSoftnessY));
|
||||
float2 maskZW = 0.25 / (0.25 * maskSoftness + 1 / scale);
|
||||
half2 m = saturate((_ClipRect.zw - _ClipRect.xy - abs(input.mask.xy)) * maskZW);
|
||||
faceColor *= m.x * m.y;
|
||||
#endif
|
||||
|
||||
#if UNITY_UI_ALPHACLIP
|
||||
clip(faceColor.a - 0.001);
|
||||
#endif
|
||||
|
||||
return faceColor * input.color.a;
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
Fallback "TextMeshPro/Mobile/Distance Field"
|
||||
CustomEditor "TMPro.EditorUtilities.TMP_SDFShaderGUI"
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 14eb328de4b8eb245bb7cea29e4ac00b
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large.
Load diff
Loaded 100 of 315 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user