Init
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
%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: e651dbb3fbac04af2b8f5abf007ddc23, type: 3}
|
||||
m_Name: DefaultNetworkPrefabs
|
||||
m_EditorClassIdentifier:
|
||||
IsDefault: 1
|
||||
List:
|
||||
- Override: 0
|
||||
Prefab: {fileID: 3439633038736912633, guid: 398aad09d8b2a47eba664a076763cdcc, type: 3}
|
||||
SourcePrefabToOverride: {fileID: 0}
|
||||
SourceHashToOverride: 0
|
||||
OverridingTargetPrefab: {fileID: 0}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ade67b675ab279949a8c1b7b0684ce60
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 052faaac586de48259a63d0c4782560b
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 11500000, guid: 8404be70184654265930450def6a9037, type: 3}
|
||||
generateWrapperCode: 0
|
||||
wrapperCodePath:
|
||||
wrapperClassName:
|
||||
wrapperCodeNamespace:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e09ca9c29032caf40bebc8c816cf7971
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5b89e375a14f4e049b207cb0f3daaadf
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 240c6ee064ec9b34888740ebc2d7c2dc
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1d47210b6a0af2247b2ddbb08cc85e7d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9d463107ae5974c4a8bffb4f6a04bf54
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,269 @@
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
using System.Reflection;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
[InitializeOnLoad]
|
||||
public static class SceneSwitcherToolbar
|
||||
{
|
||||
private static string[] sceneNames = new string[0];
|
||||
private static int selectedIndex = 0;
|
||||
private static string lastActiveScene = "";
|
||||
private static VisualElement toolbarUI;
|
||||
|
||||
private static float positionOffset = 180f;
|
||||
private static float dropdownBoxHeight = 20f;
|
||||
|
||||
private static bool fetchAllScenes
|
||||
{
|
||||
get => EditorPrefs.GetBool("SceneSwitcher_FetchAllScenes", false);
|
||||
set => EditorPrefs.SetBool("SceneSwitcher_FetchAllScenes", value);
|
||||
}
|
||||
|
||||
static SceneSwitcherToolbar()
|
||||
{
|
||||
RefreshSceneList();
|
||||
SelectCurrentScene();
|
||||
|
||||
EditorSceneManager.activeSceneChangedInEditMode += (prev, current) => UpdateSceneSelection();
|
||||
EditorApplication.playModeStateChanged += OnPlayModeChanged;
|
||||
|
||||
EditorApplication.delayCall += AddToolbarUI;
|
||||
}
|
||||
|
||||
static void AddToolbarUI()
|
||||
{
|
||||
var toolbarType = typeof(Editor).Assembly.GetType("UnityEditor.Toolbar");
|
||||
if (toolbarType == null) return;
|
||||
|
||||
var toolbars = Resources.FindObjectsOfTypeAll(toolbarType);
|
||||
if (toolbars.Length == 0) return;
|
||||
|
||||
var toolbar = toolbars[0];
|
||||
var rootField = toolbarType.GetField("m_Root", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
if (rootField == null) return;
|
||||
|
||||
var root = rootField.GetValue(toolbar) as VisualElement;
|
||||
if (root == null) return;
|
||||
|
||||
var leftContainer = root.Q("ToolbarZoneLeftAlign");
|
||||
if (leftContainer == null) return;
|
||||
|
||||
if (toolbarUI != null)
|
||||
{
|
||||
leftContainer.Remove(toolbarUI);
|
||||
}
|
||||
|
||||
toolbarUI = new IMGUIContainer(OnGUI);
|
||||
toolbarUI.style.marginLeft = positionOffset;
|
||||
|
||||
leftContainer.Add(toolbarUI);
|
||||
}
|
||||
|
||||
static void OnGUI()
|
||||
{
|
||||
CheckAndRefreshScenes();
|
||||
|
||||
if (selectedIndex >= sceneNames.Length)
|
||||
selectedIndex = 0;
|
||||
|
||||
bool isPlaying = EditorApplication.isPlaying;
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
// Fetch all scenes toggle button
|
||||
EditorGUI.BeginDisabledGroup(isPlaying);
|
||||
bool newFetchAllScenes = GUILayout.Toggle(fetchAllScenes, "All Scenes", "Button", GUILayout.Height(dropdownBoxHeight));
|
||||
if (newFetchAllScenes != fetchAllScenes)
|
||||
{
|
||||
fetchAllScenes = newFetchAllScenes;
|
||||
RefreshSceneList();
|
||||
SelectCurrentScene();
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
// Add Scene button
|
||||
EditorGUI.BeginDisabledGroup(isPlaying || fetchAllScenes);
|
||||
if (GUILayout.Button("Add Scene", GUILayout.Height(dropdownBoxHeight)))
|
||||
{
|
||||
AddCurrentSceneToBuildSettings();
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
// Scene dropdown
|
||||
EditorGUI.BeginDisabledGroup(isPlaying);
|
||||
GUIStyle popupStyle = new GUIStyle(EditorStyles.popup)
|
||||
{
|
||||
fixedHeight = dropdownBoxHeight
|
||||
};
|
||||
|
||||
int newIndex = EditorGUILayout.Popup(selectedIndex, sceneNames, popupStyle, GUILayout.Width(150), GUILayout.Height(dropdownBoxHeight));
|
||||
|
||||
if (newIndex != selectedIndex)
|
||||
{
|
||||
selectedIndex = newIndex;
|
||||
LoadScene(sceneNames[selectedIndex]);
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
static void AddCurrentSceneToBuildSettings()
|
||||
{
|
||||
string currentScenePath = EditorSceneManager.GetActiveScene().path;
|
||||
|
||||
if (string.IsNullOrEmpty(currentScenePath))
|
||||
{
|
||||
EditorUtility.DisplayDialog("Scene Not Saved",
|
||||
"Please save the scene before adding it to Build Settings.", "OK");
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if scene is already in build settings
|
||||
var buildScenes = EditorBuildSettings.scenes.ToList();
|
||||
bool sceneExists = buildScenes.Any(s => s.path == currentScenePath);
|
||||
|
||||
if (sceneExists)
|
||||
{
|
||||
// Enable the scene if it was disabled
|
||||
var existingScene = buildScenes.Find(s => s.path == currentScenePath);
|
||||
if (!existingScene.enabled)
|
||||
{
|
||||
existingScene.enabled = true;
|
||||
EditorBuildSettings.scenes = buildScenes.ToArray();
|
||||
Debug.Log($"<color=green>Scene '{Path.GetFileNameWithoutExtension(currentScenePath)}' enabled in Build Settings.</color>");
|
||||
RefreshSceneList();
|
||||
SelectCurrentScene();
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log($"Scene '{Path.GetFileNameWithoutExtension(currentScenePath)}' is already in Build Settings.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add new scene to build settings
|
||||
buildScenes.Add(new EditorBuildSettingsScene(currentScenePath, true));
|
||||
EditorBuildSettings.scenes = buildScenes.ToArray();
|
||||
|
||||
Debug.Log($"<color=green>Scene '{Path.GetFileNameWithoutExtension(currentScenePath)}' added to Build Settings.</color>");
|
||||
|
||||
RefreshSceneList();
|
||||
SelectCurrentScene();
|
||||
}
|
||||
}
|
||||
|
||||
static void RefreshSceneList()
|
||||
{
|
||||
if (fetchAllScenes)
|
||||
{
|
||||
sceneNames = Directory.GetFiles("Assets", "*.unity", SearchOption.AllDirectories)
|
||||
.Select(path => Path.GetFileNameWithoutExtension(path))
|
||||
.ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
sceneNames = EditorBuildSettings.scenes
|
||||
.Where(scene => scene.enabled)
|
||||
.Select(scene => Path.GetFileNameWithoutExtension(scene.path))
|
||||
.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
static void CheckAndRefreshScenes()
|
||||
{
|
||||
string[] currentScenes;
|
||||
if (fetchAllScenes)
|
||||
{
|
||||
currentScenes = Directory.GetFiles("Assets", "*.unity", SearchOption.AllDirectories)
|
||||
.Select(path => Path.GetFileNameWithoutExtension(path))
|
||||
.ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
currentScenes = EditorBuildSettings.scenes
|
||||
.Where(scene => scene.enabled)
|
||||
.Select(scene => Path.GetFileNameWithoutExtension(scene.path))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
if (!currentScenes.SequenceEqual(sceneNames))
|
||||
{
|
||||
sceneNames = currentScenes;
|
||||
SelectCurrentScene();
|
||||
}
|
||||
}
|
||||
|
||||
static void SelectCurrentScene()
|
||||
{
|
||||
string currentScene = Path.GetFileNameWithoutExtension(EditorSceneManager.GetActiveScene().path);
|
||||
int index = System.Array.IndexOf(sceneNames, currentScene);
|
||||
|
||||
if (index != -1)
|
||||
{
|
||||
selectedIndex = index;
|
||||
lastActiveScene = currentScene;
|
||||
}
|
||||
else
|
||||
{
|
||||
string notInBuildName = currentScene + " (not in build index)";
|
||||
sceneNames = new[] { notInBuildName }.Concat(sceneNames).ToArray();
|
||||
selectedIndex = 0;
|
||||
lastActiveScene = currentScene;
|
||||
}
|
||||
}
|
||||
|
||||
static void UpdateSceneSelection()
|
||||
{
|
||||
string currentScene = Path.GetFileNameWithoutExtension(EditorSceneManager.GetActiveScene().path);
|
||||
if (currentScene != lastActiveScene)
|
||||
{
|
||||
lastActiveScene = currentScene;
|
||||
sceneNames = sceneNames.Where(name => !name.EndsWith(" (not in build index)")).ToArray();
|
||||
SelectCurrentScene();
|
||||
}
|
||||
}
|
||||
|
||||
static void LoadScene(string sceneName)
|
||||
{
|
||||
string scenePath;
|
||||
|
||||
if (fetchAllScenes)
|
||||
{
|
||||
scenePath = Directory.GetFiles("Assets", "*.unity", SearchOption.AllDirectories)
|
||||
.FirstOrDefault(path => Path.GetFileNameWithoutExtension(path) == sceneName);
|
||||
}
|
||||
else
|
||||
{
|
||||
scenePath = EditorBuildSettings.scenes
|
||||
.FirstOrDefault(scene => scene.enabled && scene.path.Contains(sceneName))?.path;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(scenePath))
|
||||
{
|
||||
if (EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo())
|
||||
{
|
||||
EditorSceneManager.OpenScene(scenePath);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("Scene not found: " + sceneName);
|
||||
}
|
||||
}
|
||||
|
||||
static void OnPlayModeChanged(PlayModeStateChange state)
|
||||
{
|
||||
if (state == PlayModeStateChange.EnteredPlayMode || state == PlayModeStateChange.ExitingPlayMode)
|
||||
{
|
||||
EditorApplication.delayCall += () => AddToolbarUI();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 09ae5cf30ab3ca54f92f91841e5f2c04
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 313355
|
||||
packageName: Scene Switcher Pro
|
||||
packageVersion: 1.0.0
|
||||
assetPath: Assets/SceneSwitcherPro/Editor/SceneSwitcherToolbar.cs
|
||||
uploadId: 758164
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 47cf9d3c724f25f4c80adada943326ba
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d454140e53231466b8d485f9ff487b2e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 842468ccf23564770b4b1cb9f7eca30e
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "VFavorites",
|
||||
"rootNamespace": "",
|
||||
"references": [],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d8266c7db84a045d3b706b23e60aa197
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6651039474d594cdd91489768cf293f6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,225 @@
|
||||
#if UNITY_EDITOR
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
using UnityEditor;
|
||||
using UnityEditor.ShortcutManagement;
|
||||
using System.Reflection;
|
||||
using System.Linq;
|
||||
using UnityEngine.UIElements;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEditor.SceneManagement;
|
||||
using Type = System.Type;
|
||||
using static VFavorites.VFavoritesState;
|
||||
using static VFavorites.Libs.VUtils;
|
||||
using static VFavorites.Libs.VGUI;
|
||||
|
||||
|
||||
|
||||
namespace VFavorites
|
||||
{
|
||||
public class VFavoritesData : ScriptableObject
|
||||
{
|
||||
public List<Page> pages = new List<Page>();
|
||||
|
||||
public Page curPage
|
||||
{
|
||||
get
|
||||
{
|
||||
while (curPageIndex >= pages.Count - 1)
|
||||
pages.Add(new Page("Page " + (pages.Count + 1)));
|
||||
|
||||
return pages[curPageIndex];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public int curPageIndex { get => VFavoritesState.instance.curPageIndex; set => VFavoritesState.instance.curPageIndex = value; }
|
||||
|
||||
public float rowScale = 1;
|
||||
|
||||
|
||||
[System.Serializable]
|
||||
public class Page
|
||||
{
|
||||
public List<Item> items = new List<Item>();
|
||||
|
||||
public string name = "";
|
||||
|
||||
public Page(string name) => this.name = name;
|
||||
|
||||
|
||||
|
||||
|
||||
[System.NonSerialized]
|
||||
public List<float> _rowGaps = new List<float>();
|
||||
public List<float> rowGaps
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_rowGaps == null)
|
||||
_rowGaps = new List<float>();
|
||||
|
||||
while (_rowGaps.Count < items.Count + 1) _rowGaps.Add(0);
|
||||
while (_rowGaps.Count > items.Count + 1) _rowGaps.RemoveLast();
|
||||
|
||||
return _rowGaps;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public float scrollPos { get => state.scrollPos; set => state.scrollPos = value; }
|
||||
|
||||
public long lastItemSelectTime_ticks { get => state.lastItemSelectTime_ticks; set => state.lastItemSelectTime_ticks = value; }
|
||||
public long lastItemDragTime_ticks { get => state.lastItemDragTime_ticks; set => state.lastItemDragTime_ticks = value; }
|
||||
|
||||
|
||||
public PageState state
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!VFavoritesState.instance.pageStates_byPageId.ContainsKey(id))
|
||||
VFavoritesState.instance.pageStates_byPageId[id] = new PageState();
|
||||
|
||||
return VFavoritesState.instance.pageStates_byPageId[id];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public int id
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_id == 0)
|
||||
_id = Random.value.GetHashCode();
|
||||
|
||||
return _id;
|
||||
|
||||
}
|
||||
}
|
||||
public int _id = 0;
|
||||
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class Item
|
||||
{
|
||||
public GlobalID globalId;
|
||||
|
||||
|
||||
public Type type => Type.GetType(_typeString) ?? typeof(DefaultAsset);
|
||||
public string _typeString;
|
||||
|
||||
public Object obj => _obj != null ? _obj : (_obj = globalId.GetObject());
|
||||
public Object _obj;
|
||||
|
||||
|
||||
public bool isSceneGameObject;
|
||||
public bool isFolder;
|
||||
public bool isAsset;
|
||||
|
||||
|
||||
public bool isLoadable => obj != null;
|
||||
|
||||
public bool isDeleted
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!isSceneGameObject)
|
||||
return !isLoadable;
|
||||
|
||||
if (isLoadable)
|
||||
return false;
|
||||
|
||||
if (!AssetDatabase.LoadAssetAtPath<SceneAsset>(globalId.guid.ToPath()))
|
||||
return true;
|
||||
|
||||
for (int i = 0; i < EditorSceneManager.sceneCount; i++)
|
||||
if (EditorSceneManager.GetSceneAt(i).path == globalId.guid.ToPath())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public string assetPath => globalId.guid.ToPath();
|
||||
|
||||
|
||||
public Item(Object o)
|
||||
{
|
||||
globalId = o.GetGlobalID();
|
||||
|
||||
|
||||
isSceneGameObject = o is GameObject go && go.scene.rootCount != 0;
|
||||
isFolder = AssetDatabase.IsValidFolder(o.GetPath());
|
||||
isAsset = !isSceneGameObject && !isFolder;
|
||||
|
||||
_typeString = o.GetType().AssemblyQualifiedName;
|
||||
|
||||
_name = o.name;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public string name
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!isLoadable) return _name;
|
||||
|
||||
if (assetPath.GetExtension() == ".cs")
|
||||
_name = obj.name.Decamelcase();
|
||||
else
|
||||
_name = obj.name;
|
||||
|
||||
return _name;
|
||||
|
||||
}
|
||||
}
|
||||
public string _name { get => state._name; set => state._name = value; }
|
||||
|
||||
public string sceneGameObjectIconName { get => state.sceneGameObjectIconName; set => state.sceneGameObjectIconName = value; }
|
||||
|
||||
public long lastSelectTime_ticks { get => state.lastSelectTime_ticks; set => state.lastSelectTime_ticks = value; }
|
||||
public bool isSelected { get => state.isSelected; set => state.isSelected = value; }
|
||||
|
||||
|
||||
|
||||
public ItemState state
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!VFavoritesState.instance.itemStates_byItemId.ContainsKey(id))
|
||||
VFavoritesState.instance.itemStates_byItemId[id] = new ItemState();
|
||||
|
||||
return VFavoritesState.instance.itemStates_byItemId[id];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public int id
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_id == 0)
|
||||
_id = Random.value.GetHashCode();
|
||||
|
||||
return _id;
|
||||
|
||||
}
|
||||
}
|
||||
public int _id = 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 066cf82f8f80d408c856e48fc8f1127b
|
||||
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,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 38092f82a4c054086826261d88277942
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,140 @@
|
||||
#if UNITY_EDITOR
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using static VFavorites.Libs.VUtils;
|
||||
using static VFavorites.Libs.VGUI;
|
||||
|
||||
|
||||
|
||||
namespace VFavorites
|
||||
{
|
||||
public class VFavoritesMenu
|
||||
{
|
||||
|
||||
public static bool pageScrollEnabled { get => EditorPrefsCached.GetBool("vFavorites-pageScrollEnabled", true); set => EditorPrefsCached.SetBool("vFavorites-pageScrollEnabled", value); }
|
||||
public static bool numberKeysEnabled { get => EditorPrefsCached.GetBool("vFavorites-numberKeysEnabled", true); set => EditorPrefsCached.SetBool("vFavorites-numberKeysEnabled", value); }
|
||||
public static bool arrowKeysEnabled { get => EditorPrefsCached.GetBool("vFavorites-arrowKeysEnabled", true); set => EditorPrefsCached.SetBool("vFavorites-arrowKeysEnabled", value); }
|
||||
|
||||
public static bool fadeAnimationsEnabled { get => EditorPrefsCached.GetBool("vFavorites-fadeAnimationsEnabled", true); set => EditorPrefsCached.SetBool("vFavorites-fadeAnimationsEnabled", value); }
|
||||
public static bool pageScrollAnimationEnabled { get => EditorPrefsCached.GetBool("vFavorites-pageScrollAnimationEnabled", true); set => EditorPrefsCached.SetBool("vFavorites-pageScrollAnimationEnabled", value); }
|
||||
|
||||
public static int activeOnKeyCombination { get => EditorPrefsCached.GetInt("vFavorites-activeOnKeyCombination", 0); set => EditorPrefsCached.SetInt("vFavorites-activeOnKeyCombination", value); }
|
||||
public static bool activeOnAltEnabled { get => activeOnKeyCombination == 0; set => activeOnKeyCombination = 0; }
|
||||
public static bool activeOnAltShiftEnabled { get => activeOnKeyCombination == 1; set => activeOnKeyCombination = 1; }
|
||||
public static bool activeOnCtrlAltEnabled { get => activeOnKeyCombination == 2; set => activeOnKeyCombination = 2; }
|
||||
|
||||
public static bool pluginDisabled { get => EditorPrefsCached.GetBool("vFavorites-pluginDisabled", false); set => EditorPrefsCached.SetBool("vFavorites-pluginDisabled", value); }
|
||||
|
||||
|
||||
|
||||
|
||||
const string dir = "Tools/vFavorites/";
|
||||
|
||||
const string pageScroll = dir + "Scroll to change page";
|
||||
const string numberKeys = dir + "1-9 keys to change page";
|
||||
const string arrowKeys = dir + "Arrow keys to change page or selection ";
|
||||
|
||||
const string fadeAnimations = dir + "Fade animations";
|
||||
const string pageScrollAnimation = dir + "Page scroll animation";
|
||||
|
||||
const string activeOnAlt = dir + "Holding Alt";
|
||||
const string activeOnAltShift = dir + "Holding Alt and Shift";
|
||||
#if UNITY_EDITOR_OSX
|
||||
const string activeOnCtrlAlt = dir + "Holding Cmd and Alt";
|
||||
#else
|
||||
const string activeOnCtrlAlt = dir + "Holding Ctrl and Alt";
|
||||
|
||||
#endif
|
||||
|
||||
const string disablePlugin = dir + "Disable vFavorites";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[MenuItem(dir + "Shortcuts", false, 1)] static void dadsas() { }
|
||||
[MenuItem(dir + "Shortcuts", true, 1)] static bool dadsas123() => false;
|
||||
|
||||
[MenuItem(pageScroll, false, 2)] static void dadsadasadsdadsas() => pageScrollEnabled = !pageScrollEnabled;
|
||||
[MenuItem(pageScroll, true, 2)] static bool dadsadasdadsdasadsas() { Menu.SetChecked(pageScroll, pageScrollEnabled); return !pluginDisabled; }
|
||||
|
||||
[MenuItem(numberKeys, false, 4)] static void dadsadadsas() => numberKeysEnabled = !numberKeysEnabled;
|
||||
[MenuItem(numberKeys, true, 4)] static bool dadsaddasadsas() { Menu.SetChecked(numberKeys, numberKeysEnabled); return !pluginDisabled; }
|
||||
|
||||
[MenuItem(arrowKeys, false, 5)] static void dadsadaddassas() => arrowKeysEnabled = !arrowKeysEnabled;
|
||||
[MenuItem(arrowKeys, true, 5)] static bool dadadssaddasadsas() { Menu.SetChecked(arrowKeys, arrowKeysEnabled); return !pluginDisabled; }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[MenuItem(dir + "Animations", false, 101)] static void dadsadsas() { }
|
||||
[MenuItem(dir + "Animations", true, 101)] static bool dadadssas123() => false;
|
||||
|
||||
[MenuItem(fadeAnimations, false, 102)] static void dadsdasadadsas() => fadeAnimationsEnabled = !fadeAnimationsEnabled;
|
||||
[MenuItem(fadeAnimations, true, 102)] static bool dadsadadsadsdasadsas() { Menu.SetChecked(fadeAnimations, fadeAnimationsEnabled); return !pluginDisabled; }
|
||||
|
||||
[MenuItem(pageScrollAnimation, false, 103)] static void dadsdasdasadadsas() => pageScrollAnimationEnabled = !pageScrollAnimationEnabled;
|
||||
[MenuItem(pageScrollAnimation, true, 103)] static bool dadsadaddassadsdasadsas() { Menu.SetChecked(pageScrollAnimation, pageScrollAnimationEnabled); return !pluginDisabled; }
|
||||
|
||||
|
||||
|
||||
|
||||
[MenuItem(dir + "Open when", false, 1001)] static void dadsaddssas() { }
|
||||
[MenuItem(dir + "Open when", true, 1001)] static bool dadadsssas123() => false;
|
||||
|
||||
[MenuItem(activeOnAlt, false, 1002)] static void dadsdasasdadsas() => activeOnAltEnabled = !activeOnAltEnabled;
|
||||
[MenuItem(activeOnAlt, true, 1002)] static bool dadsadadssdadsdasadsas() { Menu.SetChecked(activeOnAlt, activeOnAltEnabled); return !pluginDisabled; }
|
||||
|
||||
[MenuItem(activeOnAltShift, false, 1003)] static void dadsdasasdadsadsas() => activeOnAltShiftEnabled = !activeOnAltShiftEnabled;
|
||||
[MenuItem(activeOnAltShift, true, 1003)] static bool dadsadadssdasdadsdasadsas() { Menu.SetChecked(activeOnAltShift, activeOnAltShiftEnabled); return !pluginDisabled; }
|
||||
|
||||
[MenuItem(activeOnCtrlAlt, false, 1004)] static void dadsdasadasadssdadsas() => activeOnCtrlAltEnabled = !activeOnCtrlAltEnabled;
|
||||
[MenuItem(activeOnCtrlAlt, true, 1004)] static bool dadsadadsadssdadsdasadsas() { Menu.SetChecked(activeOnCtrlAlt, activeOnCtrlAltEnabled); return !pluginDisabled; }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[MenuItem(dir + "More", false, 10001)] static void daasadsddsas() { }
|
||||
[MenuItem(dir + "More", true, 10001)] static bool dadsadsdasas123() => false;
|
||||
|
||||
// [MenuItem(dir + "Open manual", false, 10002)]
|
||||
// static void dadadssadsas() => AssetDatabase.OpenAsset(AssetDatabase.LoadAssetAtPath<Object>(GetScriptPath("VFavorites").GetParentPath().CombinePath("Manual.pdf")));
|
||||
|
||||
[MenuItem(dir + "Join our Discord", false, 10002)]
|
||||
static void dadasdsas() => Application.OpenURL("https://discord.gg/pUektnZeJT");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[MenuItem(dir + "Deals ending soon/Get vHierarchy 2 at 60% off", false, 10003)]
|
||||
static void dadadssadasdsas() => Application.OpenURL("https://assetstore.unity.com/packages/slug/253397?aid=1100lGLBn&pubref=deal60menuvfav");
|
||||
|
||||
[MenuItem(dir + "Deals ending soon/Get vFolders 2 at 60% off", false, 10004)]
|
||||
static void dadadssasddsas() => Application.OpenURL("https://assetstore.unity.com/packages/slug/255470?aid=1100lGLBn&pubref=deal60menuvfav");
|
||||
|
||||
[MenuItem(dir + "Deals ending soon/Get vInspector 2 at 60% off", false, 10005)]
|
||||
static void dadadadsssadsas() => Application.OpenURL("https://assetstore.unity.com/packages/slug/252297?aid=1100lGLBn&pubref=deal60menuvfav");
|
||||
|
||||
[MenuItem(dir + "Deals ending soon/Get vTabs 2 at 60% off", false, 10006)]
|
||||
static void dadadadsssadsadsas() => Application.OpenURL("https://assetstore.unity.com/packages/slug/253396?aid=1100lGLBn&pubref=deal60menuvfav");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[MenuItem(disablePlugin, false, 100001)] static void dadsadsdasadasdasdsadadsas() { pluginDisabled = !pluginDisabled; UnityEditor.Compilation.CompilationPipeline.RequestScriptCompilation(); }
|
||||
[MenuItem(disablePlugin, true, 100001)] static bool dadsaddssdaasadsadadsdasadsas() { Menu.SetChecked(disablePlugin, pluginDisabled); return true; }
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 65f8f6586ea4740238f667f8337cf6fb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,6 @@
|
||||
|
||||
|
||||
// this file was present in a previus version and is supposed to be deleted now
|
||||
// but asset store update delivery system doesn't allow deleting files
|
||||
// so instead this file is now emptied
|
||||
// feel free to delete it if you want
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e1b1b30cd63e14da9a295742be768842
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,57 @@
|
||||
#if UNITY_EDITOR
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
using UnityEditor;
|
||||
using UnityEditor.ShortcutManagement;
|
||||
using System.Reflection;
|
||||
using System.Linq;
|
||||
using UnityEngine.UIElements;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEditor.SceneManagement;
|
||||
using Type = System.Type;
|
||||
using static VFavorites.Libs.VUtils;
|
||||
using static VFavorites.Libs.VGUI;
|
||||
|
||||
|
||||
namespace VFavorites
|
||||
{
|
||||
[FilePath("Library/vFavorites State.asset", FilePathAttribute.Location.ProjectFolder)]
|
||||
public class VFavoritesState : ScriptableSingleton<VFavoritesState>
|
||||
{
|
||||
public int curPageIndex;
|
||||
|
||||
public SerializableDictionary<int, PageState> pageStates_byPageId = new SerializableDictionary<int, PageState>();
|
||||
|
||||
public SerializableDictionary<int, ItemState> itemStates_byItemId = new SerializableDictionary<int, ItemState>();
|
||||
|
||||
|
||||
[System.Serializable]
|
||||
public class PageState
|
||||
{
|
||||
public long lastItemSelectTime_ticks;
|
||||
public long lastItemDragTime_ticks;
|
||||
|
||||
public float scrollPos;
|
||||
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class ItemState
|
||||
{
|
||||
public string _name;
|
||||
|
||||
public string sceneGameObjectIconName;
|
||||
|
||||
public long lastSelectTime_ticks;
|
||||
public bool isSelected;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static void Save() => instance.Save(true);
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 362e220c378db4e97ae41fa35a6fb58f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,22 @@
|
||||
%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: 066cf82f8f80d408c856e48fc8f1127b, type: 3}
|
||||
m_Name: vFavorites Data
|
||||
m_EditorClassIdentifier:
|
||||
pages:
|
||||
- items: []
|
||||
name: Page 1
|
||||
_id: 1039256194
|
||||
- items: []
|
||||
name: Page 2
|
||||
_id: 0
|
||||
rowScale: 1
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c421be6dfd25bbe458970dad85cc77f4
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 109ccfb08b9fd4bf5a9d8deee2ace2ed
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6c1da0cc833e64f4c96ba170387ea7a6
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "VFolders",
|
||||
"rootNamespace": "",
|
||||
"references": [],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3331bc437f3a24586b7e86e7bdd62b5e
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cb4ae53db31ef4fdfbfc47484afb8192
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,102 @@
|
||||
#if UNITY_EDITOR
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.ShortcutManagement;
|
||||
using System.Reflection;
|
||||
using System.Linq;
|
||||
using UnityEngine.UIElements;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEditor.SceneManagement;
|
||||
using static VFolders.Libs.VUtils;
|
||||
using static VFolders.Libs.VGUI;
|
||||
// using static VTools.VDebug;
|
||||
|
||||
namespace VFolders
|
||||
{
|
||||
[FilePath("Library/vFolders Cache.asset", FilePathAttribute.Location.ProjectFolder)]
|
||||
public class VFoldersCache : ScriptableSingleton<VFoldersCache>
|
||||
{
|
||||
|
||||
public Texture2D GetIcon(int key)
|
||||
{
|
||||
if (instance.iconTextures_byKey.ContainsKey(key))
|
||||
return instance.iconTextures_byKey[key];
|
||||
|
||||
if (instance.iconTextureDatas_byKey.ContainsKey(key))
|
||||
return instance.iconTextures_byKey[key] = instance.iconTextureDatas_byKey[key].GetTexture();
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
public void AddIcon(int key, Texture2D icon)
|
||||
{
|
||||
instance.iconTextures_byKey[key] = icon;
|
||||
instance.iconTextureDatas_byKey[key] = new TextureData(icon);
|
||||
|
||||
instance.Save(true);
|
||||
|
||||
}
|
||||
public bool HasIcon(int key) => instance.iconTextureDatas_byKey.ContainsKey(key);
|
||||
|
||||
public Dictionary<int, Texture2D> iconTextures_byKey = new();
|
||||
public SerializableDictionary<int, TextureData> iconTextureDatas_byKey = new();
|
||||
|
||||
[System.Serializable]
|
||||
public class TextureData
|
||||
{
|
||||
public byte[] rawData;
|
||||
public int width;
|
||||
public int height;
|
||||
public TextureFormat format;
|
||||
public int mipCount;
|
||||
public float pixelsPerPoint;
|
||||
|
||||
public TextureData(Texture2D t)
|
||||
{
|
||||
rawData = t.GetRawTextureData();
|
||||
width = t.width;
|
||||
height = t.height;
|
||||
format = t.format;
|
||||
mipCount = t.mipmapCount;
|
||||
pixelsPerPoint = t.GetPropertyValue<float>("pixelsPerPoint");
|
||||
|
||||
}
|
||||
|
||||
public Texture2D GetTexture()
|
||||
{
|
||||
var t = new Texture2D(width, height, format, mipCount, false);
|
||||
t.LoadRawTextureData(rawData);
|
||||
t.SetPropertyValue("pixelsPerPoint", pixelsPerPoint);
|
||||
t.hideFlags = HideFlags.DontSave;
|
||||
t.Apply();
|
||||
|
||||
return t;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public SerializableDictionary<string, FolderState> folderStates_byGuid = new();
|
||||
|
||||
[System.Serializable]
|
||||
public class FolderState
|
||||
{
|
||||
public bool isEmpty;
|
||||
|
||||
public List<string> contentMinimapIconNames = new();
|
||||
|
||||
public string autoIconName = "";
|
||||
|
||||
public bool needsUpdate;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 69c14c9fceb5b4c968f55fe5786a0bee
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,521 @@
|
||||
#if UNITY_EDITOR
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.ShortcutManagement;
|
||||
using UnityEngine.UIElements;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEditor.IMGUI.Controls;
|
||||
using Type = System.Type;
|
||||
using static VFolders.Libs.VUtils;
|
||||
using static VFolders.Libs.VGUI;
|
||||
// using static VTools.VDebug;
|
||||
using static VFolders.VFolders;
|
||||
using static VFolders.VFoldersData;
|
||||
using static VFolders.VFoldersCache;
|
||||
|
||||
|
||||
|
||||
namespace VFolders
|
||||
{
|
||||
public class VFoldersController
|
||||
{
|
||||
|
||||
public void UpdateExpandQueue()
|
||||
{
|
||||
if (treeViewAnimatesExpansion) return;
|
||||
|
||||
if (!expandQueue_toAnimate.Any())
|
||||
{
|
||||
if (!expandQueue_toCollapseAfterAnimation.Any()) return;
|
||||
|
||||
foreach (var id in expandQueue_toCollapseAfterAnimation)
|
||||
SetExpanded_withoutAnimation(id, false);
|
||||
|
||||
expandQueue_toCollapseAfterAnimation.Clear();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var iid = expandQueue_toAnimate.First().id;
|
||||
var expand = expandQueue_toAnimate.First().expand;
|
||||
|
||||
|
||||
if (expandedIds.Contains(iid) != expand)
|
||||
SetExpanded_withAnimation(iid, expand);
|
||||
|
||||
expandQueue_toAnimate.RemoveAt(0);
|
||||
|
||||
|
||||
window.Repaint();
|
||||
|
||||
}
|
||||
|
||||
public List<ExpandQueueEntry> expandQueue_toAnimate = new();
|
||||
public List<int> expandQueue_toCollapseAfterAnimation = new();
|
||||
|
||||
public struct ExpandQueueEntry { public int id; public bool expand; }
|
||||
|
||||
public bool animatingExpansion => expandQueue_toAnimate.Any() || expandQueue_toCollapseAfterAnimation.Any();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void UpdateScrollAnimation()
|
||||
{
|
||||
if (!animatingScroll) return;
|
||||
|
||||
|
||||
var lerpSpeed = 10;
|
||||
|
||||
var lerpedScrollPos = MathUtil.SmoothDamp(currentScrollPos, targetScrollPos, lerpSpeed, ref scrollPosDerivative, editorDeltaTime);
|
||||
|
||||
SetScrollPos(lerpedScrollPos);
|
||||
|
||||
window.Repaint();
|
||||
|
||||
|
||||
|
||||
if (lerpedScrollPos.DistanceTo(targetScrollPos) > .4f) return;
|
||||
|
||||
SetScrollPos(targetScrollPos);
|
||||
|
||||
animatingScroll = false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
public float targetScrollPos;
|
||||
public float scrollPosDerivative;
|
||||
|
||||
public bool animatingScroll;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void UpdateHighlightAnimation()
|
||||
{
|
||||
if (!animatingHighlight) return;
|
||||
|
||||
|
||||
var lerpSpeed = 1.2f;
|
||||
|
||||
MathUtil.SmoothDamp(ref highlightAmount, 0, lerpSpeed, ref highlightDerivative, editorDeltaTime);
|
||||
|
||||
window.Repaint();
|
||||
|
||||
|
||||
|
||||
if (highlightAmount > .05f) return;
|
||||
|
||||
highlightAmount = 0;
|
||||
|
||||
animatingHighlight = false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
public float highlightAmount;
|
||||
public float highlightDerivative;
|
||||
|
||||
public bool animatingHighlight;
|
||||
|
||||
public string folderToHighlight;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void UpdateState()
|
||||
{
|
||||
isOneColumn = window.GetFieldValue<int>("m_ViewMode") == 0;
|
||||
|
||||
treeViewController = window.GetFieldValue(isOneColumn ? "m_AssetTree" : "m_FolderTree");
|
||||
treeViewControllerData = treeViewController?.GetPropertyValue("data");
|
||||
|
||||
|
||||
|
||||
var treeViewState = treeViewController?.GetPropertyValue<TreeViewState>("state");
|
||||
|
||||
currentScrollPos = treeViewState?.scrollPos.y ?? 0;
|
||||
|
||||
expandedIds = treeViewState?.expandedIDs ?? new List<int>();
|
||||
|
||||
|
||||
|
||||
var treeViewAnimator = treeViewController?.GetMemberValue("m_ExpansionAnimator");
|
||||
var treeViewAnimatorSetup = treeViewAnimator?.GetMemberValue("m_Setup");
|
||||
|
||||
treeViewAnimatesScroll = treeViewController?.GetMemberValue<UnityEditor.AnimatedValues.AnimFloat>("m_FramingAnimFloat").isAnimating ?? false;
|
||||
|
||||
treeViewAnimatesExpansion = treeViewAnimator?.GetMemberValue<bool>("isAnimating") ?? false;
|
||||
|
||||
}
|
||||
|
||||
bool isOneColumn;
|
||||
|
||||
object treeViewController;
|
||||
object treeViewControllerData;
|
||||
|
||||
public float currentScrollPos;
|
||||
|
||||
public List<int> expandedIds = new();
|
||||
|
||||
public bool treeViewAnimatesScroll;
|
||||
public bool treeViewAnimatesExpansion;
|
||||
|
||||
public int GetRowIndex(int instanceId)
|
||||
{
|
||||
return treeViewControllerData.InvokeMethod<int>("GetRow", instanceId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void ToggleExpanded(TreeViewItem item)
|
||||
{
|
||||
SetExpanded_withAnimation(item.id, !expandedIds.Contains(item.id));
|
||||
|
||||
window.Repaint();
|
||||
|
||||
}
|
||||
|
||||
public void CollapseAll()
|
||||
{
|
||||
|
||||
var idsToCollapse_roots = expandedIds.Where(id => EditorUtility.InstanceIDToObject(id).GetPath() is string path &&
|
||||
path.HasParentPath() &&
|
||||
(path.GetParentPath() == "Assets" || path.GetParentPath() == "Packages"));
|
||||
|
||||
|
||||
var idsToCollapse_children = expandedIds.Where(id => EditorUtility.InstanceIDToObject(id).GetPath() is string path &&
|
||||
!path.IsNullOrEmpty() &&
|
||||
path != "Assets" &&
|
||||
path != "Packages" &&
|
||||
!idsToCollapse_roots.Contains(id));
|
||||
|
||||
|
||||
expandQueue_toCollapseAfterAnimation = idsToCollapse_children.ToList();
|
||||
|
||||
expandQueue_toAnimate = idsToCollapse_roots.Select(id => new ExpandQueueEntry { id = id, expand = false })
|
||||
.OrderBy(row => GetRowIndex(row.id)).ToList();
|
||||
|
||||
|
||||
StartScrollAnimation(targetScrollPos: 0);
|
||||
|
||||
|
||||
window.Repaint();
|
||||
|
||||
}
|
||||
|
||||
public void Isolate(TreeViewItem targetItem)
|
||||
{
|
||||
|
||||
List<TreeViewItem> getParents(TreeViewItem item)
|
||||
{
|
||||
var parents = new List<TreeViewItem>();
|
||||
|
||||
while (item.parent != null)
|
||||
parents.Add(item = item.parent);
|
||||
|
||||
return parents;
|
||||
|
||||
}
|
||||
|
||||
var targetItemParents = getParents(targetItem);
|
||||
|
||||
|
||||
|
||||
var expandedVisibleItems = new List<TreeViewItem>();
|
||||
|
||||
foreach (var expandedId in expandedIds)
|
||||
if (GetRowIndex(expandedId) is int rowIndex && rowIndex != -1)
|
||||
expandedVisibleItems.Add(treeViewControllerData.InvokeMethod<TreeViewItem>("GetItem", rowIndex));
|
||||
|
||||
|
||||
|
||||
var itemsToCollapse = expandedVisibleItems.ToList();
|
||||
|
||||
itemsToCollapse.Remove(targetItem);
|
||||
itemsToCollapse.RemoveAll(r => targetItemParents.Contains(r));
|
||||
itemsToCollapse.RemoveAll(r => itemsToCollapse.Intersect(getParents(r)).Any());
|
||||
|
||||
|
||||
|
||||
expandQueue_toAnimate = itemsToCollapse.Select(item => new ExpandQueueEntry { id = item.id, expand = false })
|
||||
.Append(new ExpandQueueEntry { id = targetItem.id, expand = true })
|
||||
.OrderBy(r => GetRowIndex(r.id)).ToList();
|
||||
|
||||
|
||||
window.Repaint();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void StartExpandAnimation(List<int> targetExpandedIds)
|
||||
{
|
||||
|
||||
var toExpand = targetExpandedIds.Except(expandedIds).ToHashSet();
|
||||
var toCollapse = expandedIds.Except(targetExpandedIds).ToHashSet();
|
||||
|
||||
|
||||
|
||||
// hanlde non-animated expansions/collapses
|
||||
|
||||
bool hasParentToCollapse(int id)
|
||||
{
|
||||
var o = Resources.InstanceIDToObject(id);
|
||||
|
||||
if (!o) return false;
|
||||
|
||||
|
||||
var assetPath = AssetDatabase.GetAssetPath(o);
|
||||
|
||||
if (!assetPath.HasParentPath()) return false;
|
||||
if (assetPath == "Assets") return false;
|
||||
|
||||
|
||||
var parentAsset = AssetDatabase.LoadAssetAtPath<DefaultAsset>(assetPath.GetParentPath());
|
||||
|
||||
if (!parentAsset) return false; // packages item
|
||||
|
||||
|
||||
var parentId = parentAsset.GetInstanceID();
|
||||
|
||||
return toCollapse.Contains(parentId)
|
||||
|| hasParentToCollapse(parentId);
|
||||
|
||||
}
|
||||
bool areAllParentsExpanded(int id)
|
||||
{
|
||||
var o = Resources.InstanceIDToObject(id);
|
||||
|
||||
if (!o) return true;
|
||||
|
||||
|
||||
var assetPath = AssetDatabase.GetAssetPath(o);
|
||||
|
||||
if (!assetPath.HasParentPath()) return true;
|
||||
if (assetPath == "Assets") return true;
|
||||
|
||||
|
||||
var parentAsset = AssetDatabase.LoadAssetAtPath<DefaultAsset>(assetPath.GetParentPath());
|
||||
|
||||
if (!parentAsset) return true; // packages item
|
||||
|
||||
|
||||
var parentId = parentAsset.GetInstanceID();
|
||||
|
||||
return expandedIds.Contains(parentId)
|
||||
&& areAllParentsExpanded(parentId);
|
||||
|
||||
}
|
||||
|
||||
var toExpand_beforeAnimation = toExpand.Where(id => !areAllParentsExpanded(id)).ToHashSet();
|
||||
var toCollapse_afterAnimation = toCollapse.Where(id => hasParentToCollapse(id)).ToHashSet();
|
||||
|
||||
|
||||
foreach (var id in toExpand_beforeAnimation)
|
||||
SetExpanded_withoutAnimation(id, true);
|
||||
|
||||
foreach (var id in toCollapse_afterAnimation)
|
||||
expandQueue_toCollapseAfterAnimation.Add(id);
|
||||
|
||||
|
||||
toExpand.ExceptWith(toExpand_beforeAnimation);
|
||||
toCollapse.ExceptWith(toCollapse_afterAnimation);
|
||||
|
||||
|
||||
|
||||
|
||||
// setup animation
|
||||
|
||||
expandQueue_toAnimate = toCollapse.Select(id => new ExpandQueueEntry { id = id, expand = false })
|
||||
.Concat(toExpand.Select(id => new ExpandQueueEntry { id = id, expand = true }))
|
||||
.OrderBy(r => GetRowIndex(r.id)).ToList();
|
||||
|
||||
}
|
||||
|
||||
public void SetExpandedIds(List<int> targetExpandedIds)
|
||||
{
|
||||
treeViewControllerData.InvokeMethod("SetExpandedIDs", targetExpandedIds.ToArray());
|
||||
}
|
||||
public void SetExpanded_withAnimation(int instanceId, bool expanded)
|
||||
{
|
||||
treeViewController.InvokeMethod("ChangeFoldingForSingleItem", instanceId, expanded);
|
||||
}
|
||||
public void SetExpanded_withoutAnimation(int instanceId, bool expanded)
|
||||
{
|
||||
treeViewControllerData.InvokeMethod("SetExpanded", instanceId, expanded);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void StartScrollAnimation(float targetScrollPos)
|
||||
{
|
||||
if (targetScrollPos.DistanceTo(currentScrollPos) < .05f) return;
|
||||
|
||||
this.targetScrollPos = targetScrollPos;
|
||||
|
||||
animatingScroll = true;
|
||||
|
||||
}
|
||||
|
||||
public void SetScrollPos(float targetScrollPos)
|
||||
{
|
||||
treeViewController.GetPropertyValue<TreeViewState>("state").scrollPos = Vector2.up * targetScrollPos;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public void RevealFolder(string path, bool expand, bool highlight, bool snapToTopMargin)
|
||||
{
|
||||
|
||||
int getId(string path) => AssetDatabase.LoadAssetAtPath<DefaultAsset>(path).GetInstanceID();
|
||||
|
||||
|
||||
var idsToExpand = new List<int>();
|
||||
|
||||
if (expand)
|
||||
idsToExpand.Add(getId(path));
|
||||
|
||||
var cur = path;
|
||||
while (!(cur = cur.GetParentPath()).IsNullOrEmpty())
|
||||
idsToExpand.Add(getId(cur));
|
||||
|
||||
idsToExpand.RemoveAll(r => expandedIds.Contains(r));
|
||||
|
||||
|
||||
|
||||
|
||||
foreach (var id in idsToExpand.SkipLast(1))
|
||||
SetExpanded_withoutAnimation(id, true);
|
||||
|
||||
if (idsToExpand.Any())
|
||||
SetExpanded_withAnimation(idsToExpand.Last(), true);
|
||||
|
||||
|
||||
|
||||
|
||||
var rowCount = treeViewControllerData.GetMemberValue<ICollection>("m_Rows").Count;
|
||||
var maxScrollPos = rowCount * 16 - window.position.height + (isOneColumn ? 49.9f : 45.9f);
|
||||
|
||||
var rowIndex = treeViewControllerData.InvokeMethod<int>("GetRow", getId(path));
|
||||
var rowPos = rowIndex * 16f + (isOneColumn ? 11 : 23);
|
||||
|
||||
var scrollAreaHeight = window.GetMemberValue<Rect>("m_TreeViewRect").height;
|
||||
|
||||
|
||||
|
||||
|
||||
var margin = 48;
|
||||
|
||||
var targetScrollPos = 0f;
|
||||
|
||||
if (snapToTopMargin)
|
||||
targetScrollPos = (rowPos - margin).Min(maxScrollPos)
|
||||
.Max(0);
|
||||
else
|
||||
targetScrollPos = currentScrollPos.Min(rowPos - margin)
|
||||
.Max(rowPos - scrollAreaHeight + margin)
|
||||
.Min(maxScrollPos)
|
||||
.Max(0);
|
||||
if (targetScrollPos < 25)
|
||||
targetScrollPos = 0;
|
||||
|
||||
StartScrollAnimation(targetScrollPos);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (!highlight) return;
|
||||
|
||||
highlightAmount = 2.2f;
|
||||
|
||||
animatingHighlight = true;
|
||||
|
||||
folderToHighlight = path;
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void OpenFolder(string path)
|
||||
{
|
||||
// update search
|
||||
window.GetMemberValue("m_SearchFilter").InvokeMethod("ClearSearch");
|
||||
window.GetMemberValue("m_SearchFilter").SetMemberValue("folders", new[] { path });
|
||||
|
||||
|
||||
// update folder tree
|
||||
window.GetMemberValue("m_FolderTree").InvokeMethod("SetSelection", new[] { AssetDatabase.LoadAssetAtPath<DefaultAsset>(path).GetInstanceID() }, false);
|
||||
|
||||
|
||||
// update list area
|
||||
var listAreaRect = window.GetMemberValue("m_ListAreaRect");
|
||||
var searchFilter = window.GetMemberValue("m_SearchFilter");
|
||||
var checkThumbnails = false;
|
||||
var assetToInstanceId = (System.Func<string, int>)((s) => typeof(AssetDatabase).InvokeMethod<int>("GetMainAssetInstanceID", s));
|
||||
|
||||
window.GetMemberValue("m_ListArea")?.InvokeMethod("InitForSearch", listAreaRect, HierarchyType.Assets, searchFilter, checkThumbnails, assetToInstanceId);
|
||||
|
||||
|
||||
// updat breadcrumbs
|
||||
window.GetMemberValue<IList>("m_BreadCrumbs").Clear();
|
||||
|
||||
|
||||
|
||||
// pretty much the same as ProjectBrowser.ShowFolderContents()
|
||||
// but without m_FolderTree.SetSelection()
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public VFoldersController(EditorWindow window) => this.window = window;
|
||||
|
||||
public EditorWindow window;
|
||||
|
||||
public VFoldersGUI gui => VFolders.guis_byWindow[window];
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 380edf2cfb553464d9f7ec73602e93d1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,145 @@
|
||||
#if UNITY_EDITOR
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
using UnityEditor;
|
||||
using UnityEditor.ShortcutManagement;
|
||||
using System.Reflection;
|
||||
using System.Linq;
|
||||
using UnityEngine.UIElements;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEditor.SceneManagement;
|
||||
using static VFolders.Libs.VUtils;
|
||||
using static VFolders.Libs.VGUI;
|
||||
// using static VTools.VDebug;
|
||||
|
||||
|
||||
namespace VFolders
|
||||
{
|
||||
public class VFoldersData : ScriptableObject, ISerializationCallbackReceiver
|
||||
{
|
||||
|
||||
public SerializableDictionary<string, FolderData> folderDatas_byGuid = new();
|
||||
|
||||
[System.Serializable]
|
||||
public class FolderData
|
||||
{
|
||||
public string iconNameOrGuid = "";
|
||||
public int colorIndex = 0;
|
||||
|
||||
public bool isIconRecursive;
|
||||
public bool isColorRecursive;
|
||||
|
||||
}
|
||||
|
||||
public void OnBeforeSerialize() => VFolders.OnDataSerialization();
|
||||
public void OnAfterDeserialize() { }
|
||||
|
||||
|
||||
|
||||
|
||||
public List<Bookmark> bookmarks = new();
|
||||
|
||||
[System.Serializable]
|
||||
public class Bookmark
|
||||
{
|
||||
|
||||
public string name => isDeleted ? "Deleted" : guid.ToPath().GetFilename();
|
||||
|
||||
|
||||
public bool isDeleted => !AssetDatabase.IsValidFolder(guid.ToPath());
|
||||
|
||||
|
||||
|
||||
public Bookmark(Object o) => guid = o.GetGuid();
|
||||
|
||||
public string guid;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[CustomEditor(typeof(VFoldersData))]
|
||||
class Editor : UnityEditor.Editor
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
var style = new GUIStyle(EditorStyles.label) { wordWrap = true };
|
||||
|
||||
void normal()
|
||||
{
|
||||
if (storeDataInMetaFiles) return;
|
||||
|
||||
SetGUIEnabled(false);
|
||||
BeginIndent(0);
|
||||
|
||||
Space(10);
|
||||
EditorGUILayout.LabelField("This file stores data about which icons and colors are assigned to folders, along with bookmarks from navigation bar.", style);
|
||||
|
||||
Space(6);
|
||||
GUILayout.Label("If there are multiple people working on the project, it's better to store icon and color data in .meta files of folders to avoid merge conflicts. To do that, click the ⋮ button at the top right corner and enable Team Mode.", style);
|
||||
|
||||
EndIndent(10);
|
||||
ResetGUIEnabled();
|
||||
}
|
||||
void meta()
|
||||
{
|
||||
if (!storeDataInMetaFiles) return;
|
||||
|
||||
SetGUIEnabled(false);
|
||||
BeginIndent(0);
|
||||
|
||||
Space(10);
|
||||
EditorGUILayout.LabelField("Icon and color data is currently stored in folders .meta files of folders, and this file only contains bookmarks from navigation bar.", style);
|
||||
|
||||
Space(6);
|
||||
GUILayout.Label("If you want all data to be stored in this file, click the ⋮ button at the top right corner and disable Team Mode.", style);
|
||||
|
||||
EndIndent(10);
|
||||
ResetGUIEnabled();
|
||||
}
|
||||
|
||||
normal();
|
||||
meta();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static bool storeDataInMetaFiles { get => EditorPrefsCached.GetBool("vFolders-teamModeEnabled", false); set => EditorPrefsCached.SetBool("vFolders-teamModeEnabled", value); }
|
||||
|
||||
|
||||
|
||||
[ContextMenu("Enable Team Mode", isValidateFunction: false, priority: 1)]
|
||||
public void EnableTeamMode()
|
||||
{
|
||||
var option = EditorUtility.DisplayDialogComplex("Licensing notice",
|
||||
"To use vFolders 2 within a team, licenses must be purchased for each individual user as per the Asset Store EULA.\n\n Sharing one license across the team is illegal and considered piracy.",
|
||||
"Acknowledge",
|
||||
"Cancel",
|
||||
"Purchase more seats");
|
||||
if (option == 0)
|
||||
storeDataInMetaFiles = true;
|
||||
|
||||
if (option == 2)
|
||||
Application.OpenURL("https://prf.hn/click/camref:1100lGLBn/pubref:teammode/destination:https://assetstore.unity.com/packages/tools/utilities/vfolders-2-255470");
|
||||
// Application.OpenURL("https://assetstore.unity.com/packages/slug/255470");
|
||||
|
||||
}
|
||||
|
||||
[ContextMenu("Disable Team Mode", isValidateFunction: false, priority: 2)]
|
||||
public void DisableTeamMode() => storeDataInMetaFiles = false;
|
||||
|
||||
[ContextMenu("Enable Team Mode", isValidateFunction: true, priority: 1)] bool asd() => !storeDataInMetaFiles;
|
||||
[ContextMenu("Disable Team Mode", isValidateFunction: true, priority: 2)] bool ads() => storeDataInMetaFiles;
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: adb9c12a8c6c949f7af83a3d238359d0
|
||||
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,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0743ead56bea942af9c21d27c5c45b62
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,403 @@
|
||||
#if UNITY_EDITOR
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.ShortcutManagement;
|
||||
using UnityEngine.UIElements;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEditor.IMGUI.Controls;
|
||||
using Type = System.Type;
|
||||
using static VFolders.Libs.VUtils;
|
||||
using static VFolders.Libs.VGUI;
|
||||
// using static VTools.VDebug;
|
||||
using static VFolders.VFolders;
|
||||
using static VFolders.VFoldersData;
|
||||
using static VFolders.VFoldersCache;
|
||||
|
||||
|
||||
|
||||
namespace VFolders
|
||||
{
|
||||
[System.Serializable]
|
||||
public class VFoldersHistory
|
||||
{
|
||||
|
||||
public void CheckTreeStateChange()
|
||||
{
|
||||
if (!VFoldersMenu.navigationBarEnabled) return;
|
||||
if (!isOneColumn) return;
|
||||
|
||||
if (lastTreeState == null) { lastTreeState = new() { scrollPos = currentScrollPos, expandedIds = expandedIds.ToList() }; return; }
|
||||
|
||||
|
||||
var curTreeState = new TreeState();
|
||||
|
||||
var targetScrollPosChanged = false;
|
||||
var targetExpandedIdsChanged = false;
|
||||
|
||||
|
||||
|
||||
void set_curState_scrollPos()
|
||||
{
|
||||
if (controller.animatingScroll)
|
||||
curTreeState.scrollPos = controller.targetScrollPos;
|
||||
else
|
||||
curTreeState.scrollPos = currentScrollPos;
|
||||
|
||||
}
|
||||
void set_curState_expandedIds()
|
||||
{
|
||||
var expandedIdsHashset = expandedIds.ToHashSet();
|
||||
|
||||
|
||||
|
||||
if (treeViewAnimatesExpansion)
|
||||
if (animatingItemTragetExpanded_fromTreeViewExpandAnimator == true)
|
||||
expandedIdsHashset.UnionWith(new HashSet<int>() { animatingItemId_fromTreeViewExpandAnimator });
|
||||
else
|
||||
expandedIdsHashset.ExceptWith(new HashSet<int>() { animatingItemId_fromTreeViewExpandAnimator });
|
||||
|
||||
|
||||
|
||||
if (controller.animatingExpansion)
|
||||
{
|
||||
foreach (var r in controller.expandQueue_toAnimate)
|
||||
if (r.expand)
|
||||
expandedIdsHashset.UnionWith(new HashSet<int>() { r.id });
|
||||
else
|
||||
expandedIdsHashset.ExceptWith(new HashSet<int>() { r.id });
|
||||
|
||||
expandedIdsHashset.ExceptWith(controller.expandQueue_toCollapseAfterAnimation.ToHashSet());
|
||||
}
|
||||
|
||||
|
||||
curTreeState.expandedIds = expandedIdsHashset.ToList();
|
||||
|
||||
}
|
||||
|
||||
void checkScrollPosChange()
|
||||
{
|
||||
if (framesSinceLastExpansionAnimation < 2) return;
|
||||
if (framesSinceLastScrollAnimation < 2) return;
|
||||
|
||||
if (curTreeState.scrollPos == lastTreeState.scrollPos) return;
|
||||
|
||||
|
||||
|
||||
if (EditorApplication.timeSinceStartup - lastScrollTime > 2 || lastTargetStateChangeWasExpandedIds)
|
||||
targetScrollPosChanged = true;
|
||||
|
||||
lastScrollTime = EditorApplication.timeSinceStartup;
|
||||
|
||||
}
|
||||
void checkExpandedIdsChange()
|
||||
{
|
||||
if (lastTreeState.expandedIds.ToHashSet().SetEquals(curTreeState.expandedIds.ToHashSet())) return;
|
||||
|
||||
targetExpandedIdsChanged = true;
|
||||
|
||||
// lastTargetState.expandedIds.LogAll("lastTargetState");
|
||||
// curTargetState.expandedIds.LogAll("curTargetState");
|
||||
|
||||
}
|
||||
|
||||
void registerStateChange()
|
||||
{
|
||||
if (!targetScrollPosChanged && !targetExpandedIdsChanged) return;
|
||||
|
||||
|
||||
prevTreeStates.Add(lastTreeState);
|
||||
nextTreeStates.Clear();
|
||||
|
||||
lastTargetStateChangeWasExpandedIds = targetExpandedIdsChanged;
|
||||
|
||||
|
||||
if (prevTreeStates.Count > 50)
|
||||
prevTreeStates.RemoveAt(0);
|
||||
|
||||
|
||||
// if (targetScrollPosChanged && targetExpandedIdsChanged)
|
||||
// "expand and scroll".Log();
|
||||
// else if (targetScrollPosChanged)
|
||||
// "scroll".Log();
|
||||
// else if (targetExpandedIdsChanged)
|
||||
// "expand".Log();
|
||||
|
||||
}
|
||||
|
||||
void updateCountersSinceAnimation()
|
||||
{
|
||||
if (controller.animatingExpansion || treeViewAnimatesExpansion)
|
||||
framesSinceLastExpansionAnimation = 0;
|
||||
else
|
||||
framesSinceLastExpansionAnimation++;
|
||||
|
||||
if (controller.animatingScroll || treeViewAnimatesScroll)
|
||||
framesSinceLastScrollAnimation = 0;
|
||||
else
|
||||
framesSinceLastScrollAnimation++;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
set_curState_scrollPos();
|
||||
set_curState_expandedIds();
|
||||
|
||||
checkScrollPosChange();
|
||||
checkExpandedIdsChange();
|
||||
|
||||
registerStateChange();
|
||||
|
||||
updateCountersSinceAnimation();
|
||||
|
||||
|
||||
lastTreeState = curTreeState;
|
||||
|
||||
}
|
||||
|
||||
int framesSinceLastExpansionAnimation;
|
||||
int framesSinceLastScrollAnimation;
|
||||
|
||||
public double lastScrollTime = 0;
|
||||
|
||||
bool lastTargetStateChangeWasExpandedIds;
|
||||
|
||||
[System.NonSerialized] TreeState lastTreeState = null;
|
||||
|
||||
|
||||
|
||||
public void CheckFolderPathChange()
|
||||
{
|
||||
if (!VFoldersMenu.navigationBarEnabled) return;
|
||||
if (isOneColumn) return;
|
||||
|
||||
var curFolderPath = window.GetMemberValue("m_SearchFilter").GetMemberValue<string[]>("folders").FirstOrDefault();
|
||||
|
||||
if (curFolderPath.IsNullOrEmpty()) return;
|
||||
|
||||
if (lastFolderPath.IsNullOrEmpty()) lastFolderPath = curFolderPath;
|
||||
if (curFolderPath == lastFolderPath) return;
|
||||
|
||||
|
||||
prevFolderPaths.Add(lastFolderPath);
|
||||
nextFolderPaths.Clear();
|
||||
|
||||
if (prevFolderPaths.Count > 50)
|
||||
prevFolderPaths.RemoveAt(0);
|
||||
|
||||
|
||||
lastFolderPath = curFolderPath;
|
||||
|
||||
}
|
||||
|
||||
string lastFolderPath = "";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void UpdateState()
|
||||
{
|
||||
if (!VFoldersMenu.navigationBarEnabled) return;
|
||||
|
||||
|
||||
isOneColumn = window.GetFieldValue<int>("m_ViewMode") == 0;
|
||||
|
||||
var treeViewController = window.GetFieldValue(isOneColumn ? "m_AssetTree" : "m_FolderTree");
|
||||
var treeViewControllerData = treeViewController?.GetPropertyValue("data");
|
||||
|
||||
|
||||
|
||||
var treeViewControllerState = treeViewController?.GetPropertyValue<TreeViewState>("state");
|
||||
|
||||
currentScrollPos = treeViewControllerState?.scrollPos.y ?? 0;
|
||||
|
||||
expandedIds = treeViewControllerState?.expandedIDs ?? new List<int>();
|
||||
|
||||
|
||||
|
||||
var treeViewAnimator = treeViewController?.GetMemberValue("m_ExpansionAnimator");
|
||||
var treeViewAnimatorSetup = treeViewAnimator?.GetMemberValue("m_Setup");
|
||||
|
||||
treeViewAnimatesScroll = treeViewController?.GetMemberValue<UnityEditor.AnimatedValues.AnimFloat>("m_FramingAnimFloat").isAnimating ?? false;
|
||||
|
||||
treeViewAnimatesExpansion = treeViewAnimator?.GetMemberValue<bool>("isAnimating") ?? false;
|
||||
animatingItemTragetExpanded_fromTreeViewExpandAnimator = treeViewAnimatorSetup?.GetMemberValue<bool>("expanding") ?? false;
|
||||
animatingItemId_fromTreeViewExpandAnimator = treeViewAnimatorSetup?.GetMemberValue("item").GetMemberValue<int>("id") ?? 0;
|
||||
|
||||
}
|
||||
|
||||
public bool isOneColumn;
|
||||
public bool isTwoColumns => !isOneColumn;
|
||||
|
||||
public bool isSearchActive;
|
||||
|
||||
public float currentScrollPos;
|
||||
|
||||
public List<int> expandedIds = new();
|
||||
|
||||
public bool treeViewAnimatesScroll;
|
||||
|
||||
public bool treeViewAnimatesExpansion;
|
||||
public bool animatingItemTragetExpanded_fromTreeViewExpandAnimator;
|
||||
public int animatingItemId_fromTreeViewExpandAnimator;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void MoveBack_OneColumn(bool withAnimation = true)
|
||||
{
|
||||
var prevState = prevTreeStates.Last();
|
||||
|
||||
prevTreeStates.Remove(prevState);
|
||||
nextTreeStates.Add(lastTreeState);
|
||||
lastTreeState = prevState;
|
||||
|
||||
|
||||
if (withAnimation)
|
||||
{
|
||||
controller.StartScrollAnimation(prevState.scrollPos);
|
||||
controller.StartExpandAnimation(prevState.expandedIds);
|
||||
}
|
||||
else
|
||||
{
|
||||
controller.SetScrollPos(prevState.scrollPos);
|
||||
controller.SetExpandedIds(prevState.expandedIds);
|
||||
}
|
||||
|
||||
}
|
||||
public void MoveForward_OneColumn(bool withAnimation = true)
|
||||
{
|
||||
var nextState = nextTreeStates.Last();
|
||||
|
||||
nextTreeStates.Remove(nextState);
|
||||
prevTreeStates.Add(lastTreeState);
|
||||
lastTreeState = nextState;
|
||||
|
||||
|
||||
if (withAnimation)
|
||||
{
|
||||
controller.StartScrollAnimation(nextState.scrollPos);
|
||||
controller.StartExpandAnimation(nextState.expandedIds);
|
||||
}
|
||||
else
|
||||
{
|
||||
controller.SetScrollPos(nextState.scrollPos);
|
||||
controller.SetExpandedIds(nextState.expandedIds);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public List<TreeState> prevTreeStates = new();
|
||||
public List<TreeState> nextTreeStates = new();
|
||||
|
||||
|
||||
|
||||
public void MoveBack_TwoColumns(bool withAnimation = true)
|
||||
{
|
||||
var prevPath = prevFolderPaths.Last();
|
||||
|
||||
prevFolderPaths.RemoveLast();
|
||||
nextFolderPaths.Add(lastFolderPath);
|
||||
lastFolderPath = prevPath;
|
||||
|
||||
|
||||
if (withAnimation)
|
||||
{
|
||||
controller.RevealFolder(prevPath, expand: false, highlight: false, snapToTopMargin: false);
|
||||
controller.OpenFolder(prevPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
window.InvokeMethod("ShowFolderContents", AssetDatabase.LoadAssetAtPath<DefaultAsset>(prevPath).GetInstanceID(), true);
|
||||
}
|
||||
|
||||
}
|
||||
public void MoveForward_TwoColumns(bool withAnimation = true)
|
||||
{
|
||||
var nextPath = nextFolderPaths.Last();
|
||||
|
||||
nextFolderPaths.RemoveLast();
|
||||
prevFolderPaths.Add(lastFolderPath);
|
||||
lastFolderPath = nextPath;
|
||||
|
||||
|
||||
if (withAnimation)
|
||||
{
|
||||
controller.RevealFolder(nextPath, expand: false, highlight: false, snapToTopMargin: false);
|
||||
controller.OpenFolder(nextPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
window.InvokeMethod("ShowFolderContents", AssetDatabase.LoadAssetAtPath<DefaultAsset>(nextPath).GetInstanceID(), true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public List<string> prevFolderPaths = new();
|
||||
public List<string> nextFolderPaths = new();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[System.Serializable]
|
||||
public class TreeState
|
||||
{
|
||||
public List<int> expandedIds = new();
|
||||
|
||||
public float scrollPos;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public VFoldersHistory(EditorWindow window) => this.window = window;
|
||||
|
||||
EditorWindow window;
|
||||
|
||||
VFoldersGUI gui => VFolders.guis_byWindow[window];
|
||||
VFoldersController controller => VFolders.controllers_byWindow[window];
|
||||
|
||||
}
|
||||
|
||||
|
||||
public class VFoldersHistorySingleton : ScriptableSingleton<VFoldersHistorySingleton>
|
||||
{
|
||||
public SerializableDictionary<EditorWindow, VFoldersHistory> histories_byWindow = new();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2d3e0e15bb2714894bdfb696f7509428
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
// this file was present in a previus version and is supposed to be deleted now
|
||||
// but asset store update delivery system doesn't allow deleting files
|
||||
// so instead this file is now emptied
|
||||
// feel free to delete it if you want
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fc2d205dd3ec1446d843e566b05c2eda
|
||||
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,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d2528d4639fe84d44bfdfde62c65dc86
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,128 @@
|
||||
#if UNITY_EDITOR
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using static VFolders.Libs.VUtils;
|
||||
using static VFolders.Libs.VGUI;
|
||||
// using static VTools.VDebug;
|
||||
|
||||
|
||||
namespace VFolders
|
||||
{
|
||||
class VFoldersMenu
|
||||
{
|
||||
|
||||
public static bool navigationBarEnabled { get => EditorPrefsCached.GetBool("vFolders-navigationBarEnabled", false); set => EditorPrefsCached.SetBool("vFolders-navigationBarEnabled", value); }
|
||||
public static bool twoLineNamesEnabled { get => EditorPrefsCached.GetBool("vFolders-twoLineNamesEnabled", false); set => EditorPrefsCached.SetBool("vFolders-twoLineNamesEnabled", value); }
|
||||
|
||||
public static bool autoIconsEnabled { get => EditorPrefsCached.GetBool("vFolders-autoIconsEnabled", false); set => EditorPrefsCached.SetBool("vFolders-autoIconsEnabled", value); }
|
||||
public static bool hierarchyLinesEnabled { get => EditorPrefsCached.GetBool("vFolders-hierarchyLinesEnabled", false); set => EditorPrefsCached.SetBool("vFolders-hierarchyLinesEnabled", value); }
|
||||
public static bool zebraStripingEnabled { get => EditorPrefsCached.GetBool("vFolders-zebraStripingEnabled", false); set => EditorPrefsCached.SetBool("vFolders-zebraStripingEnabled", value); }
|
||||
public static bool contentMinimapEnabled { get => EditorPrefsCached.GetBool("vFolders-contentMinimapEnabled", false); set => EditorPrefsCached.SetBool("vFolders-contentMinimapEnabled", value); }
|
||||
public static bool backgroundColorsEnabled { get => EditorPrefsCached.GetBool("vFolders-backgroundColorsEnabled", false); set => EditorPrefsCached.SetBool("vFolders-backgroundColorsEnabled", value); }
|
||||
public static bool minimalModeEnabled { get => EditorPrefsCached.GetBool("vFolders-minimalModeEnabled", false); set => EditorPrefsCached.SetBool("vFolders-minimalModeEnabled", value); }
|
||||
public static bool foldersFirstEnabled { get => EditorPrefsCached.GetBool("vFolders-foldersFirstEnabled", false); set => EditorPrefsCached.SetBool("vFolders-foldersFirstEnabled", value); }
|
||||
public static bool toggleExpandedEnabled { get => EditorPrefsCached.GetBool("vFolders-toggleExpandedEnabled", true); set => EditorPrefsCached.SetBool("vFolders-toggleExpandedEnabled", value); }
|
||||
public static bool collapseEverythingElseEnabled { get => EditorPrefsCached.GetBool("vFolders-collapseEverythingElseEnabled", true); set => EditorPrefsCached.SetBool("vFolders-collapseEverythingElseEnabled", value); }
|
||||
public static bool collapseEverythingEnabled { get => EditorPrefsCached.GetBool("vFolders-collapseEverythingEnabled", true); set => EditorPrefsCached.SetBool("vFolders-collapseEverythingEnabled", value); }
|
||||
|
||||
public static bool pluginDisabled { get => EditorPrefsCached.GetBool("vFolders-pluginDisabled", false); set => EditorPrefsCached.SetBool("vFolders-pluginDisabled", value); }
|
||||
|
||||
|
||||
|
||||
|
||||
const string dir = "Tools/vFolders/";
|
||||
|
||||
const string navigationBar = dir + "Navigation bar";
|
||||
const string autoIcons = dir + "Automatic icons";
|
||||
const string twoLineNames = dir + "Two-line names";
|
||||
const string hierarchyLines = dir + "Hierarchy lines";
|
||||
const string backgroundColors = dir + "Background colors";
|
||||
const string minimalMode = dir + "Minimal mode";
|
||||
const string zebraStriping = dir + "Zebra striping";
|
||||
const string contentMinimap = dir + "Content minimap";
|
||||
const string foldersFirst = dir + "Sort folders first";
|
||||
|
||||
const string toggleExpanded = dir + "E to expand \u2215 collapse folder";
|
||||
const string collapseEverythingElse = dir + "Shift-E to isolate folder";
|
||||
const string collapseEverything = dir + "Ctrl-Shift-E to collapse all folders";
|
||||
|
||||
const string disablePlugin = dir + "Disable vFolders";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[MenuItem(dir + "Features", false, 1)] static void daasddsas() { }
|
||||
[MenuItem(dir + "Features", true, 1)] static bool dadsdasas123() => false;
|
||||
|
||||
[MenuItem(navigationBar, false, 2)] static void dadsaadsdsadasdsadadsas() { navigationBarEnabled = !navigationBarEnabled; EditorApplication.RepaintProjectWindow(); }
|
||||
[MenuItem(navigationBar, true, 2)] static bool dadsaddasdsasadadsdasadsas() { Menu.SetChecked(navigationBar, navigationBarEnabled); return !pluginDisabled; }
|
||||
|
||||
[MenuItem(twoLineNames, false, 3)] static void dadsadaddssadass() { twoLineNamesEnabled = !twoLineNamesEnabled; EditorApplication.RepaintProjectWindow(); }
|
||||
[MenuItem(twoLineNames, true, 3)] static bool dadsaddasdsaasddsas() { Menu.SetChecked(twoLineNames, twoLineNamesEnabled); return !pluginDisabled; }
|
||||
|
||||
[MenuItem(autoIcons, false, 4)] static void dadsadadsas() { autoIconsEnabled = !autoIconsEnabled; VFolders.folderInfoCache.Clear(); EditorApplication.RepaintProjectWindow(); }
|
||||
[MenuItem(autoIcons, true, 4)] static bool dadsaddasadsas() { Menu.SetChecked(autoIcons, autoIconsEnabled); return !pluginDisabled; }
|
||||
|
||||
[MenuItem(hierarchyLines, false, 5)] static void dadsadadsadass() { hierarchyLinesEnabled = !hierarchyLinesEnabled; EditorApplication.RepaintProjectWindow(); }
|
||||
[MenuItem(hierarchyLines, true, 5)] static bool dadsaddasaasddsas() { Menu.SetChecked(hierarchyLines, hierarchyLinesEnabled); return !pluginDisabled; }
|
||||
|
||||
[MenuItem(zebraStriping, false, 6)] static void dadsadaddsasadsadass() { zebraStripingEnabled = !zebraStripingEnabled; EditorApplication.RepaintProjectWindow(); }
|
||||
[MenuItem(zebraStriping, true, 6)] static bool dadsaddadassadsaasddsas() { Menu.SetChecked(zebraStriping, zebraStripingEnabled); return !pluginDisabled; }
|
||||
|
||||
[MenuItem(contentMinimap, false, 7)] static void dadsadadasdsadass() { contentMinimapEnabled = !contentMinimapEnabled; EditorApplication.RepaintProjectWindow(); }
|
||||
[MenuItem(contentMinimap, true, 7)] static bool dadsadddasasaasddsas() { Menu.SetChecked(contentMinimap, contentMinimapEnabled); return !pluginDisabled; }
|
||||
|
||||
[MenuItem(backgroundColors, false, 8)] static void dadsadadsadsadass() { backgroundColorsEnabled = !backgroundColorsEnabled; EditorApplication.RepaintProjectWindow(); }
|
||||
[MenuItem(backgroundColors, true, 8)] static bool dadsaddasadsaasddsas() { Menu.SetChecked(backgroundColors, backgroundColorsEnabled); return !pluginDisabled; }
|
||||
|
||||
[MenuItem(minimalMode, false, 9)] static void dadsadadsaddsasadass() { minimalModeEnabled = !minimalModeEnabled; EditorApplication.RepaintProjectWindow(); }
|
||||
[MenuItem(minimalMode, true, 9)] static bool dadsaddasadsadsaasddsas() { Menu.SetChecked(minimalMode, minimalModeEnabled); return !pluginDisabled; }
|
||||
#if UNITY_EDITOR_OSX
|
||||
[MenuItem(foldersFirst, false, 10)] static void dadsdsfaadsdadsas() { foldersFirstEnabled = !foldersFirstEnabled; EditorApplication.RepaintProjectWindow(); if (!foldersFirstEnabled) UnityEditor.Compilation.CompilationPipeline.RequestScriptCompilation(); }
|
||||
[MenuItem(foldersFirst, true, 10)] static bool dadsasdfdadsdasadsas() { Menu.SetChecked(foldersFirst, foldersFirstEnabled); return !pluginDisabled; }
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
[MenuItem(dir + "Shortcuts", false, 101)] static void dadsas() { }
|
||||
[MenuItem(dir + "Shortcuts", true, 101)] static bool dadsas123() => false;
|
||||
|
||||
[MenuItem(toggleExpanded, false, 102)] static void dadsadsadasdsadadsas() => toggleExpandedEnabled = !toggleExpandedEnabled;
|
||||
[MenuItem(toggleExpanded, true, 102)] static bool dadsaddsasadadsdasadsas() { Menu.SetChecked(toggleExpanded, toggleExpandedEnabled); return !pluginDisabled; }
|
||||
|
||||
[MenuItem(collapseEverythingElse, false, 103)] static void dadsadsasdadasdsadadsas() => collapseEverythingElseEnabled = !collapseEverythingElseEnabled;
|
||||
[MenuItem(collapseEverythingElse, true, 103)] static bool dadsaddsdasasadadsdasadsas() { Menu.SetChecked(collapseEverythingElse, collapseEverythingElseEnabled); return !pluginDisabled; }
|
||||
|
||||
[MenuItem(collapseEverything, false, 104)] static void dadsadsdasadasdsadadsas() => collapseEverythingEnabled = !collapseEverythingEnabled;
|
||||
[MenuItem(collapseEverything, true, 104)] static bool dadsaddssdaasadadsdasadsas() { Menu.SetChecked(collapseEverything, collapseEverythingEnabled); return !pluginDisabled; }
|
||||
|
||||
|
||||
|
||||
|
||||
[MenuItem(dir + "More", false, 1001)] static void daasadsddsas() { }
|
||||
[MenuItem(dir + "More", true, 1001)] static bool dadsadsdasas123() => false;
|
||||
|
||||
[MenuItem(dir + "Open manual", false, 1002)]
|
||||
static void dadadssadsas() => Application.OpenURL("https://kubacho-lab.gitbook.io/vfolders-2");
|
||||
|
||||
[MenuItem(dir + "Join our Discord", false, 1003)]
|
||||
static void dadasdsas() => Application.OpenURL("https://discord.gg/pUektnZeJT");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[MenuItem(disablePlugin, false, 10001)] static void dadsadsdasadasdasdsadadsas() { pluginDisabled = !pluginDisabled; UnityEditor.Compilation.CompilationPipeline.RequestScriptCompilation(); }
|
||||
[MenuItem(disablePlugin, true, 10001)] static bool dadsaddssdaasadsadadsdasadsas() { Menu.SetChecked(disablePlugin, pluginDisabled); return true; }
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f118e09f35fa241fda19f1f3b1e7c5a2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
// this file was present in a previus version and is supposed to be deleted now
|
||||
// but asset store update delivery system doesn't allow deleting files
|
||||
// so instead this file is now emptied
|
||||
// feel free to delete it if you want
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ec6d8bc24e3ec4cb6b055630a6425686
|
||||
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,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 30acd0784e948403f8f15047ab22692c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,268 @@
|
||||
#if UNITY_EDITOR
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.ShortcutManagement;
|
||||
using System.Reflection;
|
||||
using System.Linq;
|
||||
using UnityEngine.UIElements;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEditorInternal;
|
||||
using static VFolders.Libs.VUtils;
|
||||
using static VFolders.Libs.VGUI;
|
||||
// using static VTools.VDebug;
|
||||
|
||||
|
||||
namespace VFolders
|
||||
{
|
||||
public class VFoldersPalette : ScriptableObject
|
||||
{
|
||||
public List<Color> colors = new();
|
||||
|
||||
public bool colorsEnabled;
|
||||
|
||||
public float colorSaturation = 1;
|
||||
public float colorBrightness = 1;
|
||||
public bool colorGradientsEnabled = true;
|
||||
|
||||
public void ResetColors()
|
||||
{
|
||||
colors.Clear();
|
||||
|
||||
for (int i = 0; i < colorsCount; i++)
|
||||
colors.Add(GetDefaultColor(i));
|
||||
|
||||
colorsEnabled = true;
|
||||
|
||||
this.Dirty();
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static Color GetDefaultColor(int colorIndex)
|
||||
{
|
||||
Color color = default;
|
||||
|
||||
void grey()
|
||||
{
|
||||
if (colorIndex >= greyColorsCount) return;
|
||||
|
||||
#if UNITY_2022_1_OR_NEWER
|
||||
color = Greyscale(EditorGUIUtility.isProSkin ? .16f : .9f);
|
||||
#else
|
||||
color = Greyscale(EditorGUIUtility.isProSkin ? .315f : .9f);
|
||||
#endif
|
||||
|
||||
}
|
||||
void rainbowDarkTheme()
|
||||
{
|
||||
if (colorIndex < greyColorsCount) return;
|
||||
if (!isDarkTheme) return;
|
||||
|
||||
|
||||
var t = (colorIndex - greyColorsCount.ToFloat()) / rainbowColorsCount;
|
||||
|
||||
if (colorIndex == 0)
|
||||
t += .01f;
|
||||
|
||||
if (colorIndex == 1)
|
||||
t -= .02f;
|
||||
|
||||
if (colorIndex == 2)
|
||||
t -= .015f;
|
||||
|
||||
if (colorIndex == 3)
|
||||
t -= .01f;
|
||||
|
||||
if (colorIndex == 4)
|
||||
t += .02f;
|
||||
|
||||
if (colorIndex == 5)
|
||||
t += .01f;
|
||||
|
||||
|
||||
if (colorIndex == 8)
|
||||
t -= .01f;
|
||||
|
||||
|
||||
// color = HSLToRGB(t, .61f, .57f);
|
||||
color = ColorUtils.HSLToRGB(t, .61f, .57f);
|
||||
|
||||
|
||||
if (colorIndex == 0)
|
||||
color *= 1.16f;
|
||||
|
||||
if (colorIndex == 1)
|
||||
color *= 1.17f;
|
||||
|
||||
if (colorIndex == 2)
|
||||
color *= 1.03f;
|
||||
|
||||
if (colorIndex == 6)
|
||||
color *= 1.2f;
|
||||
|
||||
if (colorIndex == 7)
|
||||
color *= 1.55f;
|
||||
|
||||
if (colorIndex == 8)
|
||||
color *= 1.2f;
|
||||
|
||||
if (colorIndex == 9)
|
||||
color *= 1.08f;
|
||||
|
||||
|
||||
color.a = .1f;
|
||||
|
||||
}
|
||||
void rainbowLightTheme()
|
||||
{
|
||||
if (colorIndex < greyColorsCount) return;
|
||||
if (isDarkTheme) return;
|
||||
|
||||
color = ColorUtils.HSLToRGB((colorIndex - greyColorsCount.ToFloat()) / rainbowColorsCount, .99f, .75f);
|
||||
|
||||
if (colorIndex == 0)
|
||||
color *= 1.1f;
|
||||
|
||||
if (colorIndex == 1)
|
||||
color *= 1.05f;
|
||||
|
||||
color.a = .1f;
|
||||
|
||||
}
|
||||
|
||||
grey();
|
||||
rainbowDarkTheme();
|
||||
rainbowLightTheme();
|
||||
|
||||
return color;
|
||||
|
||||
}
|
||||
|
||||
public static int greyColorsCount = 0;
|
||||
public static int rainbowColorsCount = 10;
|
||||
public static int colorsCount => greyColorsCount + rainbowColorsCount;
|
||||
|
||||
|
||||
|
||||
|
||||
public List<IconRow> iconRows = new();
|
||||
|
||||
[System.Serializable]
|
||||
public class IconRow
|
||||
{
|
||||
public List<string> builtinIcons = new(); // names
|
||||
public List<string> customIcons = new(); // guids
|
||||
|
||||
public bool enabled = true;
|
||||
|
||||
public bool isCustom => !builtinIcons.Any() || customIcons.Any();
|
||||
public bool isEmpty => !builtinIcons.Any() && !customIcons.Any();
|
||||
public int iconCount => builtinIcons.Count + customIcons.Count;
|
||||
|
||||
public IconRow(string[] builtinIcons) => this.builtinIcons = builtinIcons.ToList();
|
||||
public IconRow() { }
|
||||
|
||||
}
|
||||
|
||||
public void ResetIcons()
|
||||
{
|
||||
iconRows.Clear();
|
||||
|
||||
iconRows.Add(new IconRow(new[]
|
||||
{
|
||||
"SceneAsset Icon",
|
||||
"Prefab Icon",
|
||||
"PrefabModel Icon",
|
||||
"Material Icon",
|
||||
"Texture Icon",
|
||||
"Mesh Icon",
|
||||
"cs Script Icon",
|
||||
"Shader Icon",
|
||||
"ComputeShader Icon",
|
||||
"ScriptableObject Icon",
|
||||
|
||||
}));
|
||||
iconRows.Add(new IconRow(new[]
|
||||
{
|
||||
"Light Icon",
|
||||
"LightProbes Icon",
|
||||
"LightmapParameters Icon",
|
||||
"LightingDataAsset Icon",
|
||||
"Cubemap Icon"
|
||||
|
||||
}));
|
||||
iconRows.Add(new IconRow(new[]
|
||||
{
|
||||
#if UNITY_6000_0_OR_NEWER
|
||||
"PhysicsMaterial Icon",
|
||||
#else
|
||||
"PhysicMaterial Icon",
|
||||
#endif
|
||||
"BoxCollider Icon",
|
||||
"TerrainCollider Icon",
|
||||
"MeshCollider Icon",
|
||||
"WheelCollider Icon",
|
||||
"Rigidbody Icon",
|
||||
|
||||
}));
|
||||
iconRows.Add(new IconRow(new[]
|
||||
{
|
||||
"AudioClip Icon",
|
||||
"AudioMixerController Icon",
|
||||
"AudioMixerGroup Icon",
|
||||
"AudioEchoFilter Icon",
|
||||
"AudioSource Icon",
|
||||
|
||||
}));
|
||||
iconRows.Add(new IconRow(new[]
|
||||
{
|
||||
"TextAsset Icon",
|
||||
"AssemblyDefinitionAsset Icon",
|
||||
"TerrainData Icon",
|
||||
"Terrain Icon",
|
||||
"AnimatorController Icon",
|
||||
"AnimationClip Icon",
|
||||
"Font Icon",
|
||||
"RawImage Icon",
|
||||
"Settings Icon",
|
||||
|
||||
}));
|
||||
|
||||
this.Dirty();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
[ContextMenu("Export palette")]
|
||||
public void Export()
|
||||
{
|
||||
var packagePath = EditorUtility.SaveFilePanel("Export vFolders Palette", "", this.GetPath().GetFilename(withExtension: false), "unitypackage");
|
||||
|
||||
var iconPaths = iconRows.SelectMany(r => r.customIcons).Select(r => r.ToPath()).Where(r => !r.IsNullOrEmpty());
|
||||
|
||||
AssetDatabase.ExportPackage(iconPaths.Append(this.GetPath()).ToArray(), packagePath);
|
||||
|
||||
EditorUtility.RevealInFinder(packagePath);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Reset()
|
||||
{
|
||||
ResetColors();
|
||||
ResetIcons();
|
||||
|
||||
VFolders.folderInfoCache.Clear();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 618f730fcd14941fab38169a7dde8c64
|
||||
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,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 085d323b143d5403fb4beda728e65139
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,783 @@
|
||||
#if UNITY_EDITOR
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.ShortcutManagement;
|
||||
using System.Reflection;
|
||||
using System.Linq;
|
||||
using UnityEngine.UIElements;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEditor.SceneManagement;
|
||||
using Type = System.Type;
|
||||
using static VFolders.VFolders;
|
||||
using static VFolders.VFoldersData;
|
||||
using static VFolders.VFoldersPalette;
|
||||
using static VFolders.VFoldersCache;
|
||||
using static VFolders.Libs.VUtils;
|
||||
using static VFolders.Libs.VGUI;
|
||||
// using static VTools.VDebug;
|
||||
|
||||
|
||||
namespace VFolders
|
||||
{
|
||||
public class VFoldersPaletteWindow : EditorWindow
|
||||
{
|
||||
|
||||
void OnGUI()
|
||||
{
|
||||
if (!palette) { Close(); return; }
|
||||
|
||||
int hoveredColorIndex = -1;
|
||||
string hoveredIconNameOrGuid = null;
|
||||
|
||||
void background()
|
||||
{
|
||||
position.SetPos(0, 0).Draw(windowBackground);
|
||||
}
|
||||
void outline()
|
||||
{
|
||||
if (Application.platform == RuntimePlatform.OSXEditor) return;
|
||||
|
||||
position.SetPos(0, 0).DrawOutline(Greyscale(.1f));
|
||||
|
||||
}
|
||||
void colors()
|
||||
{
|
||||
if (!palette.colorsEnabled) return;
|
||||
|
||||
var rowRect = this.position.SetPos(paddingX, paddingY).SetHeight(cellSize);
|
||||
|
||||
|
||||
void color(int i)
|
||||
{
|
||||
var cellRect = rowRect.MoveX(i * cellSize).SetWidth(cellSize).SetHeightFromMid(cellSize);
|
||||
|
||||
void backgroundSelected()
|
||||
{
|
||||
if (!colorIndexes_initial.Contains(i)) return;
|
||||
|
||||
cellRect.Resize(1).DrawRounded(selectedBackground, 2);
|
||||
|
||||
}
|
||||
void backgroundHovered()
|
||||
{
|
||||
if (!cellRect.IsHovered()) return;
|
||||
|
||||
cellRect.Resize(1).DrawRounded(this.hoveredBackground, 2);
|
||||
|
||||
}
|
||||
void crossIcon()
|
||||
{
|
||||
if (i != 0) return;
|
||||
|
||||
GUI.DrawTexture(cellRect.SetSizeFromMid(iconSize), EditorIcons.GetIcon("CrossIcon"));
|
||||
|
||||
}
|
||||
void colorOutline()
|
||||
{
|
||||
if (i == 0) return;
|
||||
|
||||
var outlineColor = i <= VFoldersPalette.greyColorsCount ? Greyscale(.0f, .4f) : Greyscale(.15f, .2f);
|
||||
|
||||
cellRect.Resize(3).DrawRounded(outlineColor, 4);
|
||||
|
||||
}
|
||||
void color()
|
||||
{
|
||||
if (i == 0) return;
|
||||
|
||||
var brightness = palette.colorBrightness;
|
||||
var saturation = palette.colorSaturation;
|
||||
var drawGradients = palette.colorGradientsEnabled;
|
||||
|
||||
if (!palette.colorGradientsEnabled)
|
||||
brightness *= isDarkTheme ? .75f : .97f;
|
||||
|
||||
if (i <= VFoldersPalette.greyColorsCount)
|
||||
{
|
||||
saturation = brightness = 1;
|
||||
drawGradients = false;
|
||||
}
|
||||
|
||||
|
||||
var colorRaw = palette ? palette.colors[i - 1] : VFoldersPalette.GetDefaultColor(i - 1);
|
||||
|
||||
var color = MathUtil.Lerp(Greyscale(.2f), colorRaw, brightness);
|
||||
|
||||
Color.RGBToHSV(color, out float h, out float s, out float v);
|
||||
color = Color.HSVToRGB(h, s * saturation, v);
|
||||
|
||||
color = MathUtil.Lerp(color, colorRaw, .5f).SetAlpha(1);
|
||||
|
||||
|
||||
|
||||
|
||||
cellRect.Resize(4).DrawRounded(color, 3);
|
||||
|
||||
if (drawGradients)
|
||||
cellRect.Resize(4).AddWidthFromRight(-2).DrawCurtainLeft(GUIColors.windowBackground.SetAlpha(.45f));
|
||||
|
||||
}
|
||||
void recursiveIndicator()
|
||||
{
|
||||
if (!curEvent.isRepaint) return;
|
||||
|
||||
|
||||
var isRecursive = folderDatas.First().colorIndex == i && folderDatas.First().isColorRecursive;
|
||||
|
||||
if (!isRecursive) return;
|
||||
|
||||
|
||||
|
||||
var iconRect = cellRect.SetSizeFromMid(16).Move(-6, -7);
|
||||
var shadowRect = iconRect.Resize(3).Move(2, 1).AddWidthFromRight(3);
|
||||
var shadowRadius = 4;
|
||||
|
||||
shadowRect.DrawBlurred(GUIColors.windowBackground, shadowRadius);
|
||||
|
||||
|
||||
SetGUIColor(Color.white * 2);
|
||||
|
||||
GUI.DrawTexture(iconRect, EditorIcons.GetIcon("UnityEditor.SceneHierarchyWindow@2x"));
|
||||
|
||||
ResetGUIColor();
|
||||
|
||||
|
||||
}
|
||||
|
||||
void setHovered()
|
||||
{
|
||||
if (!cellRect.IsHovered()) return;
|
||||
|
||||
hoveredColorIndex = i;
|
||||
|
||||
}
|
||||
void closeOnClick()
|
||||
{
|
||||
if (!cellRect.IsHovered()) return;
|
||||
if (!curEvent.isMouseUp) return;
|
||||
|
||||
curEvent.Use();
|
||||
|
||||
Close();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
cellRect.MarkInteractive();
|
||||
|
||||
backgroundSelected();
|
||||
backgroundHovered();
|
||||
crossIcon();
|
||||
colorOutline();
|
||||
color();
|
||||
recursiveIndicator();
|
||||
|
||||
setHovered();
|
||||
closeOnClick();
|
||||
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < palette.colors.Count + 1; i++)
|
||||
color(i);
|
||||
|
||||
}
|
||||
void icons()
|
||||
{
|
||||
void row(int i, IconRow iconRow)
|
||||
{
|
||||
var rowRect = this.position.SetPos(paddingX, paddingY).SetHeight(cellSize).MoveY(palette.colorsEnabled ? cellSize + spaceAfterColors : 0).MoveY(i * (cellSize + rowSpacing));
|
||||
|
||||
var isFirstEnabledRow = palette.iconRows.First(r => r.enabled) == iconRow;
|
||||
|
||||
|
||||
void icon(int i)
|
||||
{
|
||||
var cellRect = rowRect.MoveX(i * cellSize).SetWidth(cellSize).SetHeightFromMid(cellSize);
|
||||
|
||||
var isCrossIcon = isFirstEnabledRow && i == 0;
|
||||
var actualIconIndex = isFirstEnabledRow ? i - 1 : i;
|
||||
var isCustomIcon = !isCrossIcon && actualIconIndex >= iconRow.builtinIcons.Count;
|
||||
var iconNameOrGuid = isCrossIcon ? "" : isCustomIcon ? iconRow.customIcons[actualIconIndex - iconRow.builtinIcons.Count] : iconRow.builtinIcons[actualIconIndex];
|
||||
|
||||
|
||||
void backgroundSelected()
|
||||
{
|
||||
if (!iconNamesOrGuids_initial.Contains(iconNameOrGuid)) return;
|
||||
|
||||
cellRect.Resize(1).DrawRounded(selectedBackground, 2);
|
||||
|
||||
}
|
||||
void backgroundHovered()
|
||||
{
|
||||
if (!cellRect.IsHovered()) return;
|
||||
|
||||
cellRect.Resize(1).DrawRounded(this.hoveredBackground, 2);
|
||||
|
||||
}
|
||||
void crossIcon()
|
||||
{
|
||||
if (!isCrossIcon) return;
|
||||
|
||||
GUI.DrawTexture(cellRect.SetSizeFromMid(iconSize), EditorIcons.GetIcon("CrossIcon"));
|
||||
|
||||
}
|
||||
void normalIcon()
|
||||
{
|
||||
if (isCrossIcon) return;
|
||||
|
||||
var iconNameOrPath = iconNameOrGuid?.Length == 32 ? iconNameOrGuid.ToPath() : iconNameOrGuid;
|
||||
var icon = EditorIcons.GetIcon(iconNameOrPath) ?? Texture2D.blackTexture;
|
||||
|
||||
var iconRect = cellRect.SetSizeFromMid(iconSize);
|
||||
|
||||
if (icon.width < icon.height) iconRect = iconRect.SetWidthFromMid(iconRect.height * icon.width / icon.height);
|
||||
if (icon.height < icon.width) iconRect = iconRect.SetHeightFromMid(iconRect.width * icon.height / icon.width);
|
||||
|
||||
|
||||
GUI.DrawTexture(iconRect, icon);
|
||||
|
||||
}
|
||||
void recursiveIndicator()
|
||||
{
|
||||
if (!curEvent.isRepaint) return;
|
||||
|
||||
|
||||
var isRecursive = folderDatas.First().iconNameOrGuid == iconNameOrGuid && folderDatas.First().isIconRecursive;
|
||||
|
||||
if (!isRecursive) return;
|
||||
|
||||
|
||||
|
||||
var iconRect = cellRect.SetSizeFromMid(16).Move(-6, -7);
|
||||
var shadowRect = iconRect.Resize(3).Move(2, 1).AddWidthFromRight(3);
|
||||
var shadowRadius = 4;
|
||||
|
||||
shadowRect.DrawBlurred(GUIColors.windowBackground, shadowRadius);
|
||||
|
||||
|
||||
|
||||
SetGUIColor(Color.white * 2);
|
||||
|
||||
GUI.DrawTexture(iconRect, EditorIcons.GetIcon("UnityEditor.SceneHierarchyWindow@2x"));
|
||||
|
||||
ResetGUIColor();
|
||||
|
||||
|
||||
}
|
||||
|
||||
void setHovered()
|
||||
{
|
||||
if (!cellRect.IsHovered()) return;
|
||||
|
||||
hoveredIconNameOrGuid = iconNameOrGuid;
|
||||
|
||||
}
|
||||
void closeOnClick()
|
||||
{
|
||||
if (!cellRect.IsHovered()) return;
|
||||
if (!curEvent.isMouseUp) return;
|
||||
|
||||
curEvent.Use();
|
||||
|
||||
Close();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
cellRect.MarkInteractive();
|
||||
|
||||
backgroundSelected();
|
||||
backgroundHovered();
|
||||
crossIcon();
|
||||
normalIcon();
|
||||
recursiveIndicator();
|
||||
|
||||
setHovered();
|
||||
closeOnClick();
|
||||
|
||||
}
|
||||
|
||||
|
||||
for (int j = 0; j < iconRow.iconCount + (isFirstEnabledRow ? 1 : 0); j++)
|
||||
icon(j);
|
||||
|
||||
}
|
||||
|
||||
|
||||
var i = 0;
|
||||
|
||||
foreach (var iconRow in palette.iconRows)
|
||||
{
|
||||
if (!iconRow.enabled) continue;
|
||||
if (iconRow.isEmpty) continue;
|
||||
|
||||
row(i, iconRow);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
}
|
||||
void editPaletteButton()
|
||||
{
|
||||
var buttonRect = position.SetPos(0, 0).SetWidthFromRight(16).SetHeightFromBottom(16).Move(-14, -14);
|
||||
var buttonColor = isDarkTheme ? Greyscale(.6f) : Greyscale(1, .6f);
|
||||
|
||||
if (!IconButton(buttonRect, "Toolbar Plus", 16, buttonColor)) return;
|
||||
|
||||
|
||||
palette.SelectInInspector(frameInProject: false);
|
||||
|
||||
this.Close();
|
||||
|
||||
}
|
||||
|
||||
void setColorsAndIcons()
|
||||
{
|
||||
if (!curEvent.isLayout) return;
|
||||
|
||||
|
||||
if (palette.iconRows.Any(r => r.enabled))
|
||||
if (hoveredIconNameOrGuid != null)
|
||||
SetIcon(hoveredIconNameOrGuid, isRecursive: curEvent.holdingAlt);
|
||||
else
|
||||
SetInitialIcons();
|
||||
|
||||
|
||||
if (palette.colorsEnabled)
|
||||
if (hoveredColorIndex != -1)
|
||||
SetColor(hoveredColorIndex, isRecursive: curEvent.holdingAlt);
|
||||
else
|
||||
SetInitialColors();
|
||||
|
||||
}
|
||||
void updatePosition()
|
||||
{
|
||||
if (!curEvent.isLayout) return;
|
||||
|
||||
void calcDeltaTime()
|
||||
{
|
||||
deltaTime = (float)(EditorApplication.timeSinceStartup - lastLayoutTime);
|
||||
|
||||
if (deltaTime > .05f)
|
||||
deltaTime = .0166f;
|
||||
|
||||
lastLayoutTime = EditorApplication.timeSinceStartup;
|
||||
|
||||
}
|
||||
void resetCurPos()
|
||||
{
|
||||
if (currentPosition != default) return;
|
||||
|
||||
currentPosition = position.position; // position.position is always int, which can't be used for lerping
|
||||
|
||||
}
|
||||
void lerpCurPos()
|
||||
{
|
||||
var speed = 9;
|
||||
|
||||
MathUtil.SmoothDamp(ref currentPosition, targetPosition, speed, ref positionDeriv, deltaTime);
|
||||
// MathfUtils.Lerp(ref currentPosition, targetPosition, speed, deltaTime);
|
||||
|
||||
}
|
||||
void setCurPos()
|
||||
{
|
||||
position = position.SetPos(currentPosition);
|
||||
}
|
||||
|
||||
calcDeltaTime();
|
||||
resetCurPos();
|
||||
lerpCurPos();
|
||||
setCurPos();
|
||||
|
||||
if (!currentPosition.magnitude.Approx(targetPosition.magnitude))
|
||||
Repaint();
|
||||
|
||||
}
|
||||
void closeOnEscape()
|
||||
{
|
||||
if (!curEvent.isKeyDown) return;
|
||||
if (curEvent.keyCode != KeyCode.Escape) return;
|
||||
|
||||
SetInitialColors();
|
||||
SetInitialIcons();
|
||||
|
||||
Close();
|
||||
|
||||
}
|
||||
|
||||
|
||||
RecordUndoOnDatas();
|
||||
|
||||
background();
|
||||
outline();
|
||||
colors();
|
||||
icons();
|
||||
editPaletteButton();
|
||||
|
||||
setColorsAndIcons();
|
||||
updatePosition();
|
||||
closeOnEscape();
|
||||
|
||||
|
||||
|
||||
VFolders.folderInfoCache.Clear();
|
||||
|
||||
EditorApplication.RepaintProjectWindow();
|
||||
|
||||
EditorApplication.delayCall += EditorApplication.RepaintProjectWindow; // to show icons that will be generated in update
|
||||
|
||||
}
|
||||
|
||||
static float iconSize => 14;
|
||||
static float iconSpacing => 6;
|
||||
static float cellSize => iconSize + iconSpacing;
|
||||
static float spaceAfterColors => 13;
|
||||
public float rowSpacing = 1;
|
||||
static float paddingX => 12;
|
||||
static float paddingY => 12;
|
||||
|
||||
Color windowBackground => isDarkTheme ? Greyscale(.23f) : Greyscale(.75f);
|
||||
Color selectedBackground => isDarkTheme ? new Color(.3f, .5f, .7f, .8f) : new Color(.3f, .5f, .7f, .6f) * 1.25f;
|
||||
Color hoveredBackground => isDarkTheme ? Greyscale(1, .3f) : Greyscale(0, .1f);
|
||||
|
||||
public Vector2 targetPosition;
|
||||
public Vector2 currentPosition;
|
||||
Vector2 positionDeriv;
|
||||
float deltaTime;
|
||||
double lastLayoutTime;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void SetIcon(string iconNameOrGuid, bool isRecursive)
|
||||
{
|
||||
foreach (var r in folderDatas)
|
||||
{
|
||||
r.isIconRecursive = isRecursive; // setting it firstbecause iconNameOrGuid setter relies on isIconRecursive
|
||||
r.iconNameOrGuid = iconNameOrGuid;
|
||||
}
|
||||
}
|
||||
void SetColor(int colorIndex, bool isRecursive)
|
||||
{
|
||||
foreach (var r in folderDatas)
|
||||
{
|
||||
r.isColorRecursive = isRecursive;
|
||||
r.colorIndex = colorIndex;
|
||||
}
|
||||
}
|
||||
|
||||
void SetInitialIcons()
|
||||
{
|
||||
for (int i = 0; i < folderDatas.Count; i++)
|
||||
{
|
||||
folderDatas[i].isIconRecursive = isIconRecursives_initial[i];
|
||||
folderDatas[i].iconNameOrGuid = iconNamesOrGuids_initial[i];
|
||||
}
|
||||
}
|
||||
void SetInitialColors()
|
||||
{
|
||||
for (int i = 0; i < folderDatas.Count; i++)
|
||||
{
|
||||
folderDatas[i].isColorRecursive = isColorRecursives_initial[i];
|
||||
folderDatas[i].colorIndex = colorIndexes_initial[i];
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveEmptyFolderDatas()
|
||||
{
|
||||
if (VFoldersData.storeDataInMetaFiles) return; // empties removed from meta files in SaveData()
|
||||
|
||||
var toRemove = folderDatas.Select(r => r.folderData).Where(r => r.iconNameOrGuid == "" && r.colorIndex == 0);
|
||||
|
||||
foreach (var r in toRemove)
|
||||
data.folderDatas_byGuid.RemoveValue(r);
|
||||
|
||||
if (toRemove.Any())
|
||||
Undo.CollapseUndoOperations(Undo.GetCurrentGroup() - 1);
|
||||
|
||||
}
|
||||
|
||||
void RecordUndoOnDatas()
|
||||
{
|
||||
if (!VFoldersData.storeDataInMetaFiles)
|
||||
if (data)
|
||||
data.RecordUndo();
|
||||
|
||||
if (VFoldersData.storeDataInMetaFiles)
|
||||
foreach (var r in guids)
|
||||
AssetImporter.GetAtPath(r.ToPath()).RecordUndo();
|
||||
|
||||
}
|
||||
void MarkDatasDirty()
|
||||
{
|
||||
if (!VFoldersData.storeDataInMetaFiles)
|
||||
if (data)
|
||||
data.Dirty();
|
||||
|
||||
if (VFoldersData.storeDataInMetaFiles)
|
||||
VFolders.folderDatasFromMetaFiles_byGuid.Clear();
|
||||
|
||||
}
|
||||
void SaveData()
|
||||
{
|
||||
if (!VFoldersData.storeDataInMetaFiles) return;
|
||||
// if (!VFoldersData.storeDataInMetaFiles) { data.Save(); return; }
|
||||
|
||||
for (int i = 0; i < guids.Count; i++)
|
||||
if (folderDatas[i].iconNameOrGuid == "" && folderDatas[i].colorIndex == 0)
|
||||
AssetImporter.GetAtPath(guids[i].ToPath()).userData = "";
|
||||
else
|
||||
AssetImporter.GetAtPath(guids[i].ToPath()).userData = JsonUtility.ToJson(folderDatas[i].folderData);
|
||||
|
||||
for (int i = 0; i < guids.Count; i++)
|
||||
AssetImporter.GetAtPath(guids[i].ToPath()).SaveAndReimport();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void OnLostFocus()
|
||||
{
|
||||
if (curEvent.holdingAlt && EditorWindow.focusedWindow?.GetType().Name == "ProjectBrowser")
|
||||
CloseNextFrameIfNotRefocused();
|
||||
else
|
||||
Close();
|
||||
|
||||
}
|
||||
|
||||
void CloseNextFrameIfNotRefocused()
|
||||
{
|
||||
EditorApplication.delayCall += () => { if (EditorWindow.focusedWindow != this) Close(); };
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void RepaintOnAlt() // Update
|
||||
{
|
||||
if (curEvent.holdingAlt != wasHoldingAlt)
|
||||
if (EditorWindow.mouseOverWindow is VFoldersPaletteWindow paletteWindow)
|
||||
paletteWindow.Repaint();
|
||||
|
||||
wasHoldingAlt = curEvent.holdingAlt;
|
||||
|
||||
}
|
||||
|
||||
static bool wasHoldingAlt;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void Init(List<string> guids)
|
||||
{
|
||||
void createData()
|
||||
{
|
||||
if (VFolders.data) return;
|
||||
|
||||
VFolders.data = ScriptableObject.CreateInstance<VFoldersData>();
|
||||
|
||||
AssetDatabase.CreateAsset(VFolders.data, GetScriptPath("VFolders").GetParentPath().CombinePath("vFolders Data.asset"));
|
||||
|
||||
}
|
||||
void createPalette()
|
||||
{
|
||||
if (VFolders.palette) return;
|
||||
|
||||
VFolders.palette = ScriptableObject.CreateInstance<VFoldersPalette>();
|
||||
|
||||
AssetDatabase.CreateAsset(VFolders.palette, GetScriptPath("VFolders").GetParentPath().CombinePath("vFolders Palette.asset"));
|
||||
|
||||
}
|
||||
void setSize()
|
||||
{
|
||||
if (!palette.colorsEnabled && !palette.iconRows.Any(r => r.enabled && !r.isEmpty)) // somehow happened on first palette window opening in 2022.3.50
|
||||
palette.InvokeMethod("Reset");
|
||||
|
||||
|
||||
|
||||
var rowCellCounts = new List<int>();
|
||||
|
||||
if (palette.colorsEnabled)
|
||||
rowCellCounts.Add(palette.colors.Count + 1);
|
||||
|
||||
foreach (var r in palette.iconRows.Where(r => r.enabled && !r.isEmpty))
|
||||
rowCellCounts.Add(r.iconCount + (r == palette.iconRows.First(r => r.enabled) ? 1 : 0));
|
||||
|
||||
var width = paddingX
|
||||
+ rowCellCounts.Max() * cellSize
|
||||
+ (rowCellCounts.Last() == rowCellCounts.Max() ? cellSize : 0)
|
||||
+ paddingX;
|
||||
|
||||
|
||||
|
||||
var iconRowCount = palette.iconRows.Count(r => r.enabled && !r.isEmpty);
|
||||
|
||||
var height = paddingY
|
||||
+ (palette.colorsEnabled ? cellSize : 0)
|
||||
+ (palette.colorsEnabled && palette.iconRows.Any(r => r.enabled && !r.isEmpty) ? spaceAfterColors : 0)
|
||||
+ cellSize * iconRowCount
|
||||
+ rowSpacing * (iconRowCount - 1)
|
||||
+ paddingY;
|
||||
|
||||
|
||||
position = position.SetSize(width, height).SetPos(targetPosition);
|
||||
|
||||
}
|
||||
void getFolderDatas()
|
||||
{
|
||||
folderDatas.Clear();
|
||||
|
||||
foreach (var guid in guids)
|
||||
folderDatas.Add(new FolderDataWrapper(guid));
|
||||
|
||||
}
|
||||
void getInitialState()
|
||||
{
|
||||
iconNamesOrGuids_initial = folderDatas.Select(r => r.iconNameOrGuid).ToList();
|
||||
colorIndexes_initial = folderDatas.Select(r => r.colorIndex).ToList();
|
||||
|
||||
isIconRecursives_initial = folderDatas.Select(r => r.isIconRecursive).ToList();
|
||||
isColorRecursives_initial = folderDatas.Select(r => r.isColorRecursive).ToList();
|
||||
|
||||
}
|
||||
|
||||
|
||||
this.guids = guids;
|
||||
|
||||
RecordUndoOnDatas();
|
||||
|
||||
createData();
|
||||
createPalette();
|
||||
setSize();
|
||||
getFolderDatas();
|
||||
getInitialState();
|
||||
|
||||
Undo.undoRedoPerformed -= EditorApplication.RepaintProjectWindow;
|
||||
Undo.undoRedoPerformed += EditorApplication.RepaintProjectWindow;
|
||||
|
||||
EditorApplication.update -= RepaintOnAlt;
|
||||
EditorApplication.update += RepaintOnAlt;
|
||||
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
RemoveEmptyFolderDatas();
|
||||
MarkDatasDirty();
|
||||
SaveData();
|
||||
|
||||
EditorApplication.update -= RepaintOnAlt;
|
||||
|
||||
}
|
||||
|
||||
public List<string> guids = new();
|
||||
public List<FolderDataWrapper> folderDatas = new();
|
||||
|
||||
public List<string> iconNamesOrGuids_initial = new();
|
||||
public List<int> colorIndexes_initial = new();
|
||||
|
||||
public List<bool> isIconRecursives_initial = new();
|
||||
public List<bool> isColorRecursives_initial = new();
|
||||
|
||||
static VFoldersPalette palette => VFolders.palette;
|
||||
static VFoldersData data => VFolders.data;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static void CreateInstance(Vector2 position)
|
||||
{
|
||||
instance = ScriptableObject.CreateInstance<VFoldersPaletteWindow>();
|
||||
|
||||
instance.ShowPopup();
|
||||
|
||||
instance.position = instance.position.SetPos(position).SetSize(200, 300);
|
||||
instance.targetPosition = position;
|
||||
|
||||
}
|
||||
|
||||
public static VFoldersPaletteWindow instance;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public class FolderDataWrapper
|
||||
{
|
||||
public string iconNameOrGuid
|
||||
{
|
||||
get
|
||||
{
|
||||
if (folderData != null && folderData.iconNameOrGuid != "")
|
||||
if (folderData.iconNameOrGuid == "none") return "";
|
||||
else return folderData.iconNameOrGuid ?? "";
|
||||
|
||||
else if (VFoldersMenu.autoIconsEnabled && folderState.autoIconName != "")
|
||||
return folderState.autoIconName;
|
||||
|
||||
else return "";
|
||||
|
||||
}
|
||||
set
|
||||
{
|
||||
if (VFoldersMenu.autoIconsEnabled && folderState.autoIconName != "")
|
||||
if (value == folderState.autoIconName && !folderData.isIconRecursive)
|
||||
folderData.iconNameOrGuid = "";
|
||||
else if (value == "")
|
||||
folderData.iconNameOrGuid = "none";
|
||||
else
|
||||
folderData.iconNameOrGuid = value;
|
||||
|
||||
|
||||
else folderData.iconNameOrGuid = value;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
public bool isIconRecursive { get => folderData.isIconRecursive; set => folderData.isIconRecursive = value; }
|
||||
|
||||
public int colorIndex { get => folderData.colorIndex; set => folderData.colorIndex = value; }
|
||||
public bool isColorRecursive { get => folderData.isColorRecursive; set => folderData.isColorRecursive = value; }
|
||||
|
||||
|
||||
public FolderDataWrapper(string guid)
|
||||
{
|
||||
folderData = VFolders.GetFolderData(guid, createDataIfDoesntExist: true);
|
||||
folderState = VFolders.GetFolderState(guid);
|
||||
}
|
||||
|
||||
public FolderData folderData;
|
||||
public FolderState folderState;
|
||||
|
||||
|
||||
// used as an interlayer between folderData and palette window to account for automatic icons
|
||||
// it's the only structural difference between vFolders' PaletteWindow and vHierarchy's
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 68011e63381a84f3bacee6e5ee9e0b82
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dd2b9e231b0ec4a9f97e258072ae2b33
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 520b2a02f70c04615b08281be020f305
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "VHierarchy",
|
||||
"rootNamespace": "",
|
||||
"references": [],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2c3f48364a5004fd3a152fbdf5fea703
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 67e949be20d3641adbc9494ed5bd764e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,61 @@
|
||||
#if UNITY_EDITOR
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.ShortcutManagement;
|
||||
using System.Reflection;
|
||||
using System.Linq;
|
||||
using UnityEngine.UIElements;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEditor.SceneManagement;
|
||||
using Type = System.Type;
|
||||
using static VHierarchy.VHierarchyData;
|
||||
using static VHierarchy.Libs.VUtils;
|
||||
using static VHierarchy.Libs.VGUI;
|
||||
// using static VTools.VDebug;
|
||||
|
||||
|
||||
namespace VHierarchy
|
||||
{
|
||||
[FilePath("Library/vHierarchy Cache.asset", FilePathAttribute.Location.ProjectFolder)]
|
||||
public class VHierarchyCache : ScriptableSingleton<VHierarchyCache>
|
||||
{
|
||||
// used for finding SceneData and SceneIdMap for objects that were moved out of their original scene
|
||||
public SerializableDictionary<int, string> originalSceneGuids_byInstanceId = new();
|
||||
|
||||
// used as cache for converting GlobalID to InstanceID and as a way to find GameObjectData for prefabs in playmode (when prefabs produce invalid GlobalIDs)
|
||||
public SerializableDictionary<string, SceneIdMap> sceneIdMaps_bySceneGuid = new();
|
||||
|
||||
// used for fetching icons set inside prefab instances in playmode (when prefabs produce invalid GlobalIDs)
|
||||
public SerializableDictionary<int, GlobalID> prefabInstanceGlobalIds_byInstanceIds = new SerializableDictionary<int, GlobalID>();
|
||||
|
||||
|
||||
|
||||
[System.Serializable]
|
||||
public class SceneIdMap
|
||||
{
|
||||
public SerializableDictionary<int, GlobalID> globalIds_byInstanceId = new();
|
||||
|
||||
public int instanceIdsHash;
|
||||
public int globalIdsHash;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static void Clear()
|
||||
{
|
||||
instance.originalSceneGuids_byInstanceId.Clear();
|
||||
instance.sceneIdMaps_bySceneGuid.Clear();
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3fd3b966dd497472d86df0d7c9271088
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,6 @@
|
||||
|
||||
|
||||
// this file was present in a previus version and is supposed to be deleted now
|
||||
// but asset store update delivery system doesn't allow deleting files
|
||||
// so instead this file is now emptied
|
||||
// feel free to delete it if you want
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d51d8117d96b64eaa9a83667bf4297d6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,599 @@
|
||||
#if UNITY_EDITOR
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.ShortcutManagement;
|
||||
using System.Reflection;
|
||||
using System.Linq;
|
||||
using UnityEngine.UIElements;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEditor.SceneManagement;
|
||||
using Type = System.Type;
|
||||
using static VHierarchy.VHierarchyData;
|
||||
using static VHierarchy.Libs.VUtils;
|
||||
using static VHierarchy.Libs.VGUI;
|
||||
// using static VTools.VDebug;
|
||||
|
||||
|
||||
namespace VHierarchy
|
||||
{
|
||||
public class VHierarchyComponentWindow : EditorWindow
|
||||
{
|
||||
|
||||
void OnGUI()
|
||||
{
|
||||
if (!component) component = EditorUtility.InstanceIDToObject(componentIid) as Component;
|
||||
if (!component) { Close(); return; }
|
||||
|
||||
if (!editor) Init(component);
|
||||
|
||||
|
||||
void background()
|
||||
{
|
||||
position.SetPos(0, 0).Draw(GUIColors.windowBackground);
|
||||
}
|
||||
void header()
|
||||
{
|
||||
var headerRect = ExpandWidthLabelRect(18).Resize(-1).AddWidthFromMid(6);
|
||||
var pinButtonRect = headerRect.SetWidthFromRight(17).SetHeightFromMid(17).Move(-21, .5f);
|
||||
var closeButtonRect = headerRect.SetWidthFromRight(16).SetHeightFromMid(16).Move(-3, .5f);
|
||||
|
||||
var backgroundColor = isDarkTheme ? Greyscale(.25f) : GUIColors.windowBackground;
|
||||
|
||||
void startDragging()
|
||||
{
|
||||
if (isResizingVertically) return;
|
||||
if (isResizingHorizontally) return;
|
||||
if (isDragged) return;
|
||||
if (!curEvent.isMouseDrag) return;
|
||||
if (!headerRect.IsHovered()) return;
|
||||
|
||||
|
||||
isDragged = true;
|
||||
|
||||
dragStartMousePos = EditorGUIUtility.GUIToScreenPoint(curEvent.mousePosition);
|
||||
dragStartWindowPos = position.position;
|
||||
|
||||
|
||||
isPinned = true;
|
||||
|
||||
if (floatingInstance == this)
|
||||
floatingInstance = null;
|
||||
|
||||
EditorApplication.RepaintHierarchyWindow();
|
||||
|
||||
|
||||
}
|
||||
void updateDragging()
|
||||
{
|
||||
if (!isDragged) return;
|
||||
|
||||
|
||||
var draggedPosition = dragStartWindowPos + EditorGUIUtility.GUIToScreenPoint(curEvent.mousePosition) - dragStartMousePos;
|
||||
|
||||
if (!curEvent.isRepaint)
|
||||
position = position.SetPos(draggedPosition);
|
||||
|
||||
|
||||
EditorGUIUtility.hotControl = EditorGUIUtility.GetControlID(FocusType.Passive);
|
||||
|
||||
}
|
||||
void stopDragging()
|
||||
{
|
||||
if (!isDragged) return;
|
||||
if (!curEvent.isMouseUp) return;
|
||||
|
||||
|
||||
isDragged = false;
|
||||
|
||||
EditorGUIUtility.hotControl = 0;
|
||||
|
||||
}
|
||||
|
||||
void background()
|
||||
{
|
||||
headerRect.Draw(backgroundColor);
|
||||
|
||||
headerRect.SetHeightFromBottom(1).Draw(isDarkTheme ? Greyscale(.2f) : Greyscale(.7f));
|
||||
|
||||
}
|
||||
void icon()
|
||||
{
|
||||
var iconRect = headerRect.SetWidth(20).MoveX(14).MoveY(-1);
|
||||
|
||||
GUI.Label(iconRect, VHierarchy.GetComponentIcon(component));
|
||||
|
||||
}
|
||||
void toggle()
|
||||
{
|
||||
var toggleRect = headerRect.MoveX(36).SetSize(20, 20);
|
||||
|
||||
|
||||
var pi_enabled = component.GetType().GetProperty("enabled") ??
|
||||
component.GetType().BaseType?.GetProperty("enabled") ??
|
||||
component.GetType().BaseType?.BaseType?.GetProperty("enabled") ??
|
||||
component.GetType().BaseType?.BaseType?.BaseType?.GetProperty("enabled");
|
||||
|
||||
|
||||
if (pi_enabled == null) return;
|
||||
|
||||
var enabled = (bool)pi_enabled.GetValue(component);
|
||||
|
||||
|
||||
if (GUI.Toggle(toggleRect, enabled, "") == enabled) return;
|
||||
|
||||
component.RecordUndo();
|
||||
pi_enabled.SetValue(component, !enabled);
|
||||
|
||||
}
|
||||
void name()
|
||||
{
|
||||
var nameRect = headerRect.MoveX(54).MoveY(-1);
|
||||
|
||||
var s = new GUIContent(EditorGUIUtility.ObjectContent(component, component.GetType())).text;
|
||||
s = s.Substring(s.LastIndexOf('(') + 1);
|
||||
s = s.Substring(0, s.Length - 1);
|
||||
|
||||
if (isPinned)
|
||||
s += " of " + component.gameObject.name;
|
||||
|
||||
|
||||
SetLabelBold();
|
||||
|
||||
GUI.Label(nameRect, s);
|
||||
|
||||
ResetLabelStyle();
|
||||
|
||||
}
|
||||
void nameCurtain()
|
||||
{
|
||||
var flatColorRect = headerRect.SetX(pinButtonRect.x + 3).SetXMax(headerRect.xMax);
|
||||
var gradientRect = headerRect.SetXMax(flatColorRect.x).SetWidthFromRight(30);
|
||||
|
||||
flatColorRect.Draw(backgroundColor);
|
||||
gradientRect.DrawCurtainLeft(backgroundColor);
|
||||
|
||||
}
|
||||
void pinButton()
|
||||
{
|
||||
if (!isPinned && closeButtonRect.IsHovered()) return;
|
||||
|
||||
|
||||
var normalColor = isDarkTheme ? Greyscale(.65f) : Greyscale(.8f);
|
||||
var hoveredColor = isDarkTheme ? Greyscale(.9f) : normalColor;
|
||||
var activeColor = Color.white;
|
||||
|
||||
|
||||
|
||||
SetGUIColor(isPinned ? activeColor : pinButtonRect.IsHovered() ? hoveredColor : normalColor);
|
||||
|
||||
GUI.Label(pinButtonRect, EditorGUIUtility.IconContent("pinned"));
|
||||
|
||||
ResetGUIColor();
|
||||
|
||||
|
||||
SetGUIColor(Color.clear);
|
||||
|
||||
var clicked = GUI.Button(pinButtonRect, "");
|
||||
|
||||
ResetGUIColor();
|
||||
|
||||
|
||||
if (!clicked) return;
|
||||
|
||||
isPinned = !isPinned;
|
||||
|
||||
if (isPinned && floatingInstance == this)
|
||||
floatingInstance = null;
|
||||
|
||||
if (!isPinned && !floatingInstance)
|
||||
floatingInstance = this;
|
||||
|
||||
EditorApplication.RepaintHierarchyWindow();
|
||||
|
||||
|
||||
}
|
||||
void closeButton()
|
||||
{
|
||||
|
||||
SetGUIColor(Color.clear);
|
||||
|
||||
if (GUI.Button(closeButtonRect, ""))
|
||||
Close();
|
||||
|
||||
ResetGUIColor();
|
||||
|
||||
|
||||
var normalColor = isDarkTheme ? Greyscale(.65f) : Greyscale(.35f);
|
||||
var hoveredColor = isDarkTheme ? Greyscale(.9f) : normalColor;
|
||||
|
||||
|
||||
SetGUIColor(closeButtonRect.IsHovered() ? hoveredColor : normalColor);
|
||||
|
||||
GUI.Label(closeButtonRect, EditorGUIUtility.IconContent("CrossIcon"));
|
||||
|
||||
ResetGUIColor();
|
||||
|
||||
|
||||
if (isPinned) return;
|
||||
|
||||
var escRect = closeButtonRect.Move(-22, -1).SetWidth(70);
|
||||
|
||||
SetGUIEnabled(false);
|
||||
|
||||
if (closeButtonRect.IsHovered())
|
||||
GUI.Label(escRect, "Esc");
|
||||
|
||||
ResetGUIEnabled();
|
||||
|
||||
}
|
||||
void rightClick()
|
||||
{
|
||||
if (!curEvent.isMouseDown) return;
|
||||
if (curEvent.mouseButton != 1) return;
|
||||
if (!headerRect.IsHovered()) return;
|
||||
|
||||
typeof(EditorUtility).InvokeMethod("DisplayObjectContextMenu", Rect.zero.SetPos(curEvent.mousePosition), component, 0);
|
||||
|
||||
}
|
||||
|
||||
startDragging();
|
||||
updateDragging();
|
||||
stopDragging();
|
||||
|
||||
background();
|
||||
icon();
|
||||
toggle();
|
||||
name();
|
||||
nameCurtain();
|
||||
pinButton();
|
||||
closeButton();
|
||||
rightClick();
|
||||
|
||||
}
|
||||
void body()
|
||||
{
|
||||
EditorGUIUtility.labelWidth = (this.position.width * .4f).Max(120);
|
||||
|
||||
|
||||
scrollPosition = EditorGUILayout.BeginScrollView(Vector2.up * scrollPosition).y;
|
||||
BeginIndent(17);
|
||||
|
||||
|
||||
editor?.OnInspectorGUI();
|
||||
|
||||
updateHeight();
|
||||
|
||||
|
||||
EndIndent(1);
|
||||
EditorGUILayout.EndScrollView();
|
||||
|
||||
|
||||
EditorGUIUtility.labelWidth = 0;
|
||||
|
||||
}
|
||||
void outline()
|
||||
{
|
||||
if (Application.platform == RuntimePlatform.OSXEditor) return;
|
||||
|
||||
position.SetPos(0, 0).DrawOutline(Greyscale(.1f));
|
||||
|
||||
}
|
||||
|
||||
void updateHeight()
|
||||
{
|
||||
|
||||
ExpandWidthLabelRect(height: -5);
|
||||
|
||||
if (!curEvent.isRepaint) return;
|
||||
if (isResizingVertically) return;
|
||||
|
||||
|
||||
targetHeight = lastRect.y + 30;
|
||||
|
||||
position = position.SetHeight(targetHeight.Min(maxHeight));
|
||||
|
||||
|
||||
prevHeight = position.height;
|
||||
|
||||
}
|
||||
void updatePosition()
|
||||
{
|
||||
if (!curEvent.isLayout) return;
|
||||
|
||||
void calcDeltaTime()
|
||||
{
|
||||
deltaTime = (float)(EditorApplication.timeSinceStartup - lastLayoutTime);
|
||||
|
||||
if (deltaTime > .05f)
|
||||
deltaTime = .0166f;
|
||||
|
||||
lastLayoutTime = EditorApplication.timeSinceStartup;
|
||||
|
||||
}
|
||||
void resetCurPos()
|
||||
{
|
||||
if (currentPosition != default && !isPinned) return;
|
||||
|
||||
currentPosition = position.position; // position.position is always int, which can't be used for lerping
|
||||
|
||||
}
|
||||
void lerpCurPos()
|
||||
{
|
||||
if (isPinned) return;
|
||||
|
||||
var speed = 9;
|
||||
|
||||
MathUtil.SmoothDamp(ref currentPosition, targetPosition, speed, ref positionDeriv, deltaTime);
|
||||
// MathfUtils.Lerp(ref currentPosition, targetPosition, speed, deltaTime);
|
||||
|
||||
}
|
||||
void setCurPos()
|
||||
{
|
||||
if (isPinned) return;
|
||||
|
||||
position = position.SetPos(currentPosition);
|
||||
|
||||
}
|
||||
|
||||
calcDeltaTime();
|
||||
resetCurPos();
|
||||
lerpCurPos();
|
||||
setCurPos();
|
||||
|
||||
}
|
||||
void closeOnEscape()
|
||||
{
|
||||
if (isPinned) return;
|
||||
if (!curEvent.isKeyDown) return;
|
||||
if (curEvent.keyCode != KeyCode.Escape) return;
|
||||
|
||||
Close();
|
||||
}
|
||||
|
||||
void horizontalResize()
|
||||
{
|
||||
var showingScrollbar = targetHeight > maxHeight;
|
||||
|
||||
var resizeArea = this.position.SetPos(0, 0).SetWidthFromRight(showingScrollbar ? 3 : 5).AddHeightFromBottom(-20);
|
||||
|
||||
void startResize()
|
||||
{
|
||||
if (isDragged) return;
|
||||
if (isResizingHorizontally) return;
|
||||
if (!curEvent.isMouseDown && !curEvent.isMouseDrag) return;
|
||||
if (!resizeArea.IsHovered()) return;
|
||||
|
||||
isResizingHorizontally = true;
|
||||
|
||||
resizeStartMousePos = curEvent.mousePosition_screenSpace;
|
||||
resizeStartWindowSize = this.position.size;
|
||||
|
||||
}
|
||||
void updateResize()
|
||||
{
|
||||
if (!isResizingHorizontally) return;
|
||||
|
||||
|
||||
var resizedWidth = resizeStartWindowSize.x + curEvent.mousePosition_screenSpace.x - resizeStartMousePos.x;
|
||||
|
||||
var width = resizedWidth.Max(300);
|
||||
|
||||
if (!curEvent.isRepaint)
|
||||
position = position.SetWidth(width);
|
||||
|
||||
|
||||
EditorGUIUtility.hotControl = EditorGUIUtility.GetControlID(FocusType.Passive);
|
||||
// GUI.focused
|
||||
|
||||
}
|
||||
void stopResize()
|
||||
{
|
||||
if (!isResizingHorizontally) return;
|
||||
if (!curEvent.isMouseUp) return;
|
||||
|
||||
isResizingHorizontally = false;
|
||||
|
||||
EditorGUIUtility.hotControl = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
EditorGUIUtility.AddCursorRect(resizeArea, MouseCursor.ResizeHorizontal);
|
||||
|
||||
startResize();
|
||||
updateResize();
|
||||
stopResize();
|
||||
|
||||
}
|
||||
void verticalResize()
|
||||
{
|
||||
var resizeArea = this.position.SetPos(0, 0).SetHeightFromBottom(5);
|
||||
|
||||
void startResize()
|
||||
{
|
||||
if (isDragged) return;
|
||||
if (isResizingVertically) return;
|
||||
if (!curEvent.isMouseDown && !curEvent.isMouseDrag) return;
|
||||
if (!resizeArea.IsHovered()) return;
|
||||
|
||||
isResizingVertically = true;
|
||||
|
||||
resizeStartMousePos = curEvent.mousePosition_screenSpace;
|
||||
resizeStartWindowSize = this.position.size;
|
||||
|
||||
}
|
||||
void updateResize()
|
||||
{
|
||||
if (!isResizingVertically) return;
|
||||
|
||||
|
||||
var resizedHeight = resizeStartWindowSize.y + curEvent.mousePosition_screenSpace.y - resizeStartMousePos.y;
|
||||
|
||||
var height = resizedHeight.Min(targetHeight).Max(50);
|
||||
|
||||
if (!curEvent.isRepaint)
|
||||
position = position.SetHeight(height);
|
||||
|
||||
maxHeight = height;
|
||||
|
||||
|
||||
EditorGUIUtility.hotControl = EditorGUIUtility.GetControlID(FocusType.Passive);
|
||||
// GUI.focused
|
||||
|
||||
}
|
||||
void stopResize()
|
||||
{
|
||||
if (!isResizingVertically) return;
|
||||
if (!curEvent.isMouseUp) return;
|
||||
|
||||
isResizingVertically = false;
|
||||
|
||||
EditorGUIUtility.hotControl = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
EditorGUIUtility.AddCursorRect(resizeArea, MouseCursor.ResizeVertical);
|
||||
|
||||
startResize();
|
||||
updateResize();
|
||||
stopResize();
|
||||
|
||||
}
|
||||
|
||||
|
||||
background();
|
||||
|
||||
horizontalResize();
|
||||
verticalResize();
|
||||
|
||||
|
||||
header();
|
||||
|
||||
Space(3);
|
||||
body();
|
||||
outline();
|
||||
|
||||
Space(7);
|
||||
|
||||
|
||||
updatePosition();
|
||||
closeOnEscape();
|
||||
|
||||
|
||||
if (!isPinned)
|
||||
Repaint();
|
||||
|
||||
EditorApplication.delayCall -= Repaint;
|
||||
EditorApplication.delayCall += Repaint;
|
||||
|
||||
}
|
||||
|
||||
public Vector2 targetPosition;
|
||||
public Vector2 currentPosition;
|
||||
Vector2 positionDeriv;
|
||||
float deltaTime;
|
||||
double lastLayoutTime;
|
||||
|
||||
bool isDragged;
|
||||
Vector2 dragStartMousePos;
|
||||
Vector2 dragStartWindowPos;
|
||||
|
||||
public bool isResizingHorizontally;
|
||||
public bool isResizingVertically;
|
||||
public Vector2 resizeStartMousePos;
|
||||
public Vector2 resizeStartWindowSize;
|
||||
|
||||
public float scrollPosition;
|
||||
|
||||
public float targetHeight;
|
||||
public float maxHeight;
|
||||
public float prevHeight;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void OnLostFocus()
|
||||
{
|
||||
if (isPinned) return;
|
||||
|
||||
if (curEvent.holdingAlt && EditorWindow.focusedWindow.GetType().Name == "SceneHierarchyWindow")
|
||||
CloseNextFrameIfNotRefocused();
|
||||
else
|
||||
Close();
|
||||
|
||||
}
|
||||
|
||||
void CloseNextFrameIfNotRefocused()
|
||||
{
|
||||
EditorApplication.delayCall += () => { if (EditorWindow.focusedWindow != this) Close(); };
|
||||
}
|
||||
|
||||
public bool isPinned;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void Init(Component component)
|
||||
{
|
||||
if (editor)
|
||||
editor.DestroyImmediate();
|
||||
|
||||
this.component = component;
|
||||
this.componentIid = component.GetInstanceID();
|
||||
this.editor = Editor.CreateEditor(component);
|
||||
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
editor?.DestroyImmediate();
|
||||
|
||||
editor = null;
|
||||
component = null;
|
||||
|
||||
EditorPrefs.SetFloat("vHierarchy-componentWindowWidth", position.width);
|
||||
|
||||
}
|
||||
|
||||
public Component component;
|
||||
public Editor editor;
|
||||
|
||||
public int componentIid;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static void CreateFloatingInstance(Vector2 position)
|
||||
{
|
||||
floatingInstance = ScriptableObject.CreateInstance<VHierarchyComponentWindow>();
|
||||
|
||||
floatingInstance.ShowPopup();
|
||||
|
||||
|
||||
floatingInstance.maxHeight = EditorGUIUtility.GetMainWindowPosition().height * .7f;
|
||||
|
||||
|
||||
var savedWidth = EditorPrefs.GetFloat("vHierarchy-componentWindowWidth", minWidth);
|
||||
|
||||
var width = savedWidth.Max(minWidth);
|
||||
|
||||
floatingInstance.position = Rect.zero.SetPos(position).SetWidth(width).SetHeight(200);
|
||||
floatingInstance.prevHeight = floatingInstance.position.height;
|
||||
|
||||
floatingInstance.targetPosition = position;
|
||||
|
||||
}
|
||||
|
||||
public static VHierarchyComponentWindow floatingInstance;
|
||||
|
||||
public static float minWidth => 300;
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4b48d49a631ab443990f28938cbdedb8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,511 @@
|
||||
#if UNITY_EDITOR
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.ShortcutManagement;
|
||||
using UnityEngine.UIElements;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEditor.IMGUI.Controls;
|
||||
using Type = System.Type;
|
||||
using static VHierarchy.Libs.VUtils;
|
||||
using static VHierarchy.Libs.VGUI;
|
||||
// using static VTools.VDebug;
|
||||
using static VHierarchy.VHierarchy;
|
||||
using static VHierarchy.VHierarchyData;
|
||||
using static VHierarchy.VHierarchyCache;
|
||||
|
||||
|
||||
|
||||
namespace VHierarchy
|
||||
{
|
||||
public class VHierarchyController
|
||||
{
|
||||
|
||||
public void UpdateExpandQueue()
|
||||
{
|
||||
if (treeViewAnimatesExpansion) return;
|
||||
|
||||
if (!expandQueue_toAnimate.Any())
|
||||
{
|
||||
if (!expandQueue_toCollapseAfterAnimation.Any()) return;
|
||||
|
||||
foreach (var r in expandQueue_toCollapseAfterAnimation)
|
||||
SetExpanded_withoutAnimation(r, false);
|
||||
|
||||
expandQueue_toCollapseAfterAnimation.Clear();
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
var id = expandQueue_toAnimate.First().id;
|
||||
var expand = expandQueue_toAnimate.First().expand;
|
||||
|
||||
|
||||
|
||||
var itemIndex = treeViewControllerData.InvokeMethod<int>("GetRow", id);
|
||||
var items = treeViewControllerData.GetMemberValue<List<TreeViewItem>>("m_Rows");
|
||||
|
||||
var stuckCollapsing = itemIndex != -1 && items[itemIndex].id != id; // happens when collapsing long hierarchies due to a bug in TreeViewController
|
||||
|
||||
if (stuckCollapsing) { window.SendEvent(new Event() { type = EventType.KeyDown, keyCode = KeyCode.None }); return; }
|
||||
|
||||
|
||||
|
||||
|
||||
if (expandedIds.Contains(id) != expand)
|
||||
SetExpanded_withAnimation(id, expand);
|
||||
|
||||
expandQueue_toAnimate.RemoveAt(0);
|
||||
|
||||
|
||||
window.Repaint();
|
||||
|
||||
|
||||
// must be called from gui because reflected methods rely on Event.current
|
||||
|
||||
}
|
||||
|
||||
public List<ExpandQueueEntry> expandQueue_toAnimate = new();
|
||||
public List<int> expandQueue_toCollapseAfterAnimation = new();
|
||||
|
||||
public struct ExpandQueueEntry { public int id; public bool expand; }
|
||||
|
||||
public bool animatingExpansion => expandQueue_toAnimate.Any() || expandQueue_toCollapseAfterAnimation.Any();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void UpdateScrollAnimation()
|
||||
{
|
||||
if (!animatingScroll) return;
|
||||
|
||||
|
||||
var lerpSpeed = 10;
|
||||
|
||||
var lerpedScrollPos = MathUtil.SmoothDamp(currentScrollPos, targetScrollPos, lerpSpeed, ref scrollPosDerivative, editorDeltaTime);
|
||||
|
||||
SetScrollPos(lerpedScrollPos);
|
||||
|
||||
window.Repaint();
|
||||
|
||||
|
||||
|
||||
if (lerpedScrollPos.DistanceTo(targetScrollPos) > .4f) return;
|
||||
|
||||
SetScrollPos(targetScrollPos);
|
||||
|
||||
animatingScroll = false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
public float targetScrollPos;
|
||||
public float scrollPosDerivative;
|
||||
|
||||
public bool animatingScroll;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void UpdateHighlightAnimation()
|
||||
{
|
||||
if (!animatingHighlight) return;
|
||||
|
||||
|
||||
var lerpSpeed = 1.3f;
|
||||
|
||||
MathUtil.SmoothDamp(ref highlightAmount, 0, lerpSpeed, ref highlightDerivative, editorDeltaTime);
|
||||
|
||||
window.Repaint();
|
||||
|
||||
|
||||
|
||||
if (highlightAmount > .05f) return;
|
||||
|
||||
highlightAmount = 0;
|
||||
|
||||
animatingHighlight = false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
public float highlightAmount;
|
||||
public float highlightDerivative;
|
||||
|
||||
public bool animatingHighlight;
|
||||
|
||||
public GameObject objectToHighlight;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void UpdateState()
|
||||
{
|
||||
var sceneHierarchy = window?.GetFieldValue("m_SceneHierarchy");
|
||||
|
||||
treeViewController = sceneHierarchy.GetFieldValue("m_TreeView");
|
||||
treeViewControllerData = treeViewController.GetMemberValue("data");
|
||||
|
||||
|
||||
|
||||
var treeViewControllerState = treeViewController?.GetPropertyValue<TreeViewState>("state");
|
||||
|
||||
currentScrollPos = treeViewControllerState?.scrollPos.y ?? 0;
|
||||
|
||||
expandedIds = treeViewControllerState?.expandedIDs ?? new List<int>();
|
||||
|
||||
|
||||
|
||||
var treeViewAnimator = treeViewController?.GetMemberValue("m_ExpansionAnimator");
|
||||
var treeViewAnimatorSetup = treeViewAnimator?.GetMemberValue("m_Setup");
|
||||
|
||||
treeViewAnimatesScroll = treeViewController?.GetMemberValue<UnityEditor.AnimatedValues.AnimFloat>("m_FramingAnimFloat").isAnimating ?? false;
|
||||
|
||||
treeViewAnimatesExpansion = treeViewAnimator?.GetMemberValue<bool>("isAnimating") ?? false;
|
||||
|
||||
}
|
||||
|
||||
object treeViewController;
|
||||
object treeViewControllerData;
|
||||
|
||||
public float currentScrollPos;
|
||||
|
||||
public List<int> expandedIds = new();
|
||||
|
||||
public bool treeViewAnimatesScroll;
|
||||
public bool treeViewAnimatesExpansion;
|
||||
|
||||
public int GetRowIndex(int instanceId)
|
||||
{
|
||||
return treeViewControllerData.InvokeMethod<int>("GetRow", instanceId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void ToggleExpanded(int id)
|
||||
{
|
||||
SetExpanded_withAnimation(id, !expandedIds.Contains(id));
|
||||
|
||||
window.Repaint();
|
||||
|
||||
}
|
||||
|
||||
public void CollapseAll()
|
||||
{
|
||||
var expandedRoots = new List<GameObject>();
|
||||
var expandedChildren = new List<GameObject>();
|
||||
|
||||
foreach (var iid in expandedIds)
|
||||
if (EditorUtility.InstanceIDToObject(iid) is GameObject expandedGo)
|
||||
if (expandedGo.transform.parent)
|
||||
expandedChildren.Add(expandedGo);
|
||||
else
|
||||
expandedRoots.Add(expandedGo);
|
||||
|
||||
|
||||
|
||||
expandQueue_toCollapseAfterAnimation = expandedChildren.Select(r => r.GetInstanceID()).ToList();
|
||||
|
||||
expandQueue_toAnimate = expandedRoots.Select(r => new ExpandQueueEntry { id = r.GetInstanceID(), expand = false })
|
||||
.OrderBy(r => GetRowIndex(r.id)).ToList();
|
||||
|
||||
StartScrollAnimation(targetScrollPos: 0);
|
||||
|
||||
|
||||
window.Repaint();
|
||||
|
||||
}
|
||||
|
||||
public void Isolate(int targetId)
|
||||
{
|
||||
|
||||
List<int> getParents(int id)
|
||||
{
|
||||
var parentIds = new List<int>();
|
||||
|
||||
if (EditorUtility.InstanceIDToObject(id) is not GameObject go) return parentIds;
|
||||
|
||||
|
||||
while (go.transform.parent)
|
||||
parentIds.Add((go = go.transform.parent.gameObject).GetInstanceID());
|
||||
|
||||
parentIds.Add(go.scene.handle);
|
||||
|
||||
|
||||
return parentIds;
|
||||
|
||||
}
|
||||
|
||||
var targetItemParents = getParents(targetId);
|
||||
|
||||
|
||||
|
||||
var itemsToCollapse = expandedIds.ToList();
|
||||
|
||||
itemsToCollapse.Remove(targetId);
|
||||
itemsToCollapse.RemoveAll(r => targetItemParents.Contains(r));
|
||||
itemsToCollapse.RemoveAll(r => itemsToCollapse.Intersect(getParents(r)).Any());
|
||||
|
||||
if (EditorUtility.InstanceIDToObject(targetId) is GameObject)
|
||||
itemsToCollapse.RemoveAll(r => EditorUtility.InstanceIDToObject(r) is not GameObject); // won't collapse scenes
|
||||
|
||||
|
||||
|
||||
|
||||
expandQueue_toAnimate = itemsToCollapse.Select(id => new ExpandQueueEntry { id = id, expand = false })
|
||||
.Append(new ExpandQueueEntry { id = targetId, expand = true })
|
||||
.OrderBy(r => GetRowIndex(r.id)).ToList();
|
||||
|
||||
|
||||
window.Repaint();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void StartExpandAnimation(List<int> targetExpandedIds)
|
||||
{
|
||||
|
||||
var toExpand = targetExpandedIds.Except(expandedIds).ToHashSet();
|
||||
var toCollapse = expandedIds.Except(targetExpandedIds).ToHashSet();
|
||||
|
||||
|
||||
|
||||
|
||||
// hanlde destroyed objects
|
||||
|
||||
var sceneIds = Enumerable.Range(0, EditorSceneManager.sceneCount).Select(i => EditorSceneManager.GetSceneAt(i).handle).ToHashSet();
|
||||
|
||||
var toExpand_destroyed = toExpand.Where(id => !sceneIds.Contains(id) && Resources.InstanceIDToObject(id) as GameObject == null).ToHashSet();
|
||||
var toCollapse_destroyed = toCollapse.Where(id => !sceneIds.Contains(id) && Resources.InstanceIDToObject(id) as GameObject == null).ToHashSet();
|
||||
|
||||
|
||||
foreach (var id in toExpand_destroyed)
|
||||
expandedIds.Add(id);
|
||||
|
||||
foreach (var id in toCollapse_destroyed)
|
||||
expandedIds.Remove(id);
|
||||
|
||||
|
||||
toExpand.ExceptWith(toExpand_destroyed);
|
||||
toCollapse.ExceptWith(toCollapse_destroyed);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// hanlde non-animated expansions/collapses
|
||||
|
||||
bool hasParentToCollapse(int id)
|
||||
{
|
||||
var go = Resources.InstanceIDToObject(id) as GameObject;
|
||||
|
||||
if (!go) return false;
|
||||
if (!go.transform.parent) return false;
|
||||
|
||||
|
||||
var parentId = go.transform.parent.gameObject.GetInstanceID();
|
||||
|
||||
return toCollapse.Contains(parentId)
|
||||
|| hasParentToCollapse(parentId);
|
||||
|
||||
}
|
||||
bool areAllParentsExpanded(int id)
|
||||
{
|
||||
var go = Resources.InstanceIDToObject(id) as GameObject;
|
||||
|
||||
if (!go) return true;
|
||||
if (!go.transform.parent) return true;
|
||||
|
||||
|
||||
var parentId = go.transform.parent.gameObject.GetInstanceID();
|
||||
|
||||
return expandedIds.Contains(parentId)
|
||||
&& areAllParentsExpanded(parentId);
|
||||
|
||||
}
|
||||
|
||||
var toExpand_beforeAnimation = toExpand.Where(id => !areAllParentsExpanded(id)).ToHashSet();
|
||||
var toCollapse_afterAnimation = toCollapse.Where(id => hasParentToCollapse(id)).ToHashSet();
|
||||
|
||||
|
||||
foreach (var id in toExpand_beforeAnimation)
|
||||
SetExpanded_withoutAnimation(id, true);
|
||||
|
||||
foreach (var id in toCollapse_afterAnimation)
|
||||
expandQueue_toCollapseAfterAnimation.Add(id);
|
||||
|
||||
|
||||
toExpand.ExceptWith(toExpand_beforeAnimation);
|
||||
toCollapse.ExceptWith(toCollapse_afterAnimation);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// setup animation
|
||||
|
||||
expandQueue_toAnimate = toCollapse.Select(id => new ExpandQueueEntry { id = id, expand = false })
|
||||
.Concat(toExpand.Select(id => new ExpandQueueEntry { id = id, expand = true }))
|
||||
.OrderBy(r => GetRowIndex(r.id)).ToList();
|
||||
|
||||
}
|
||||
|
||||
public void SetExpandedIds(List<int> targetExpandedIds)
|
||||
{
|
||||
treeViewControllerData.InvokeMethod("SetExpandedIDs", targetExpandedIds.ToArray());
|
||||
}
|
||||
public void SetExpanded_withAnimation(int instanceId, bool expanded)
|
||||
{
|
||||
treeViewController.InvokeMethod("ChangeFoldingForSingleItem", instanceId, expanded);
|
||||
}
|
||||
public void SetExpanded_withoutAnimation(int instanceId, bool expanded)
|
||||
{
|
||||
treeViewControllerData.InvokeMethod("SetExpanded", instanceId, expanded);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void StartScrollAnimation(float targetScrollPos)
|
||||
{
|
||||
if (targetScrollPos.DistanceTo(currentScrollPos) < .05f) return;
|
||||
|
||||
this.targetScrollPos = targetScrollPos;
|
||||
|
||||
animatingScroll = true;
|
||||
|
||||
}
|
||||
|
||||
public void SetScrollPos(float targetScrollPos)
|
||||
{
|
||||
window.GetMemberValue("m_SceneHierarchy").GetMemberValue<UnityEditor.IMGUI.Controls.TreeViewState>("m_TreeViewState").scrollPos = Vector2.up * targetScrollPos;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void RevealObject(GameObject go, bool expand, bool highlight, bool snapToTopMargin)
|
||||
{
|
||||
|
||||
var idsToExpand = new List<int>();
|
||||
|
||||
if (expand && go.transform.childCount > 0)
|
||||
idsToExpand.Add(go.GetInstanceID());
|
||||
|
||||
var cur = go.transform;
|
||||
while (cur = cur.parent)
|
||||
idsToExpand.Add(cur.gameObject.GetInstanceID());
|
||||
|
||||
idsToExpand.Add(go.scene.handle);
|
||||
|
||||
idsToExpand.RemoveAll(r => expandedIds.Contains(r));
|
||||
|
||||
|
||||
|
||||
|
||||
foreach (var id in idsToExpand.SkipLast(1))
|
||||
SetExpanded_withoutAnimation(id, true);
|
||||
|
||||
if (idsToExpand.Any())
|
||||
SetExpanded_withAnimation(idsToExpand.Last(), true);
|
||||
|
||||
|
||||
|
||||
|
||||
var rowCount = treeViewControllerData.GetMemberValue<ICollection>("m_Rows").Count;
|
||||
var maxScrollPos = rowCount * 16 - window.position.height + 26.9f;
|
||||
|
||||
var rowIndex = treeViewControllerData.InvokeMethod<int>("GetRow", go.GetInstanceID());
|
||||
var rowPos = rowIndex * 16f + 8;
|
||||
|
||||
var scrollAreaHeight = window.GetMemberValue<Rect>("treeViewRect").height;
|
||||
|
||||
|
||||
|
||||
|
||||
var margin = 48;
|
||||
|
||||
var targetScrollPos = 0f;
|
||||
|
||||
if (expand)
|
||||
targetScrollPos = (rowPos - margin).Min(maxScrollPos)
|
||||
.Max(0);
|
||||
else
|
||||
targetScrollPos = currentScrollPos.Min(rowPos - margin)
|
||||
.Max(rowPos - scrollAreaHeight + margin)
|
||||
.Min(maxScrollPos)
|
||||
.Max(0);
|
||||
if (targetScrollPos < 25)
|
||||
targetScrollPos = 0;
|
||||
|
||||
|
||||
|
||||
StartScrollAnimation(targetScrollPos);
|
||||
|
||||
|
||||
|
||||
|
||||
if (!highlight) return;
|
||||
|
||||
highlightAmount = 2.2f;
|
||||
|
||||
animatingHighlight = true;
|
||||
|
||||
objectToHighlight = go;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public VHierarchyController(EditorWindow window) => this.window = window;
|
||||
|
||||
public EditorWindow window;
|
||||
|
||||
public VHierarchyGUI gui => VHierarchy.guis_byWindow[window];
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3513d7b44a8b94c8d800e841067bf035
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,227 @@
|
||||
#if UNITY_EDITOR
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.ShortcutManagement;
|
||||
using System.Reflection;
|
||||
using System.Linq;
|
||||
using UnityEngine.UIElements;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEditor.SceneManagement;
|
||||
using Type = System.Type;
|
||||
using static VHierarchy.VHierarchyCache;
|
||||
using static VHierarchy.Libs.VUtils;
|
||||
using static VHierarchy.Libs.VGUI;
|
||||
// using static VTools.VDebug;
|
||||
|
||||
|
||||
namespace VHierarchy
|
||||
{
|
||||
public class VHierarchyData : ScriptableObject, ISerializationCallbackReceiver
|
||||
{
|
||||
|
||||
public SerializableDictionary<string, SceneData> sceneDatas_byGuid = new();
|
||||
|
||||
|
||||
[System.Serializable]
|
||||
public class SceneData
|
||||
{
|
||||
public SerializableDictionary<GlobalID, GameObjectData> goDatas_byGlobalId = new();
|
||||
}
|
||||
|
||||
|
||||
[System.Serializable]
|
||||
public class GameObjectData
|
||||
{
|
||||
public int colorIndex;
|
||||
public string iconNameOrGuid = "";
|
||||
|
||||
public bool isIconRecursive;
|
||||
public bool isColorRecursive;
|
||||
|
||||
|
||||
[System.NonSerialized]
|
||||
public SceneData sceneData; // set in GetGameObjectData
|
||||
|
||||
}
|
||||
|
||||
public void OnBeforeSerialize() => VHierarchy.OnDataSerialization();
|
||||
public void OnAfterDeserialize() { }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public List<Bookmark> bookmarks = new();
|
||||
|
||||
[System.Serializable]
|
||||
public class Bookmark
|
||||
{
|
||||
|
||||
public GameObject go
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_go == null)
|
||||
if (!failedToLoadSceneObject) // to prevent continuous GlobalID.GetObjects() calls if object is deleted
|
||||
VHierarchy.unloadedSceneBookmarks_sceneGuids.Add(globalId.guid);
|
||||
|
||||
return _go;
|
||||
|
||||
}
|
||||
}
|
||||
public GameObject _go;
|
||||
|
||||
[System.NonSerialized]
|
||||
public bool failedToLoadSceneObject;
|
||||
|
||||
|
||||
|
||||
public bool isLoadable => go != null;
|
||||
|
||||
public bool isDeleted
|
||||
{
|
||||
get
|
||||
{
|
||||
if (isLoadable)
|
||||
return false;
|
||||
|
||||
if (!AssetDatabase.LoadAssetAtPath<SceneAsset>(globalId.guid.ToPath()))
|
||||
return true;
|
||||
|
||||
for (int i = 0; i < EditorSceneManager.sceneCount; i++)
|
||||
if (EditorSceneManager.GetSceneAt(i).path == globalId.guid.ToPath())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public string assetPath => globalId.guid.ToPath();
|
||||
|
||||
public string name => go ? go.name : "Can't load object";
|
||||
|
||||
|
||||
|
||||
public Bookmark(GameObject o)
|
||||
{
|
||||
globalId = o.GetGlobalID();
|
||||
|
||||
_go = o;
|
||||
|
||||
}
|
||||
|
||||
public GlobalID globalId;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public List<string> bookmarkedScenePaths = new();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[CustomEditor(typeof(VHierarchyData))]
|
||||
class Editor : UnityEditor.Editor
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
var style = new GUIStyle(EditorStyles.label) { wordWrap = true };
|
||||
|
||||
void normal()
|
||||
{
|
||||
if (teamModeEnabled) return;
|
||||
|
||||
SetGUIEnabled(false);
|
||||
BeginIndent(0);
|
||||
|
||||
Space(10);
|
||||
EditorGUILayout.LabelField("This file stores data about which icons and colors are assigned to objects, along with bookmarks from navigation bar and scene selector.", style);
|
||||
|
||||
Space(6);
|
||||
GUILayout.Label("If there are multiple people working on the project, you might want to store icon/color data in scenes to avoid merge conflicts. To do that, click the ⋮ button at the top right corner and enable Team Mode.", style);
|
||||
|
||||
EndIndent(10);
|
||||
ResetGUIEnabled();
|
||||
}
|
||||
void teamMode()
|
||||
{
|
||||
if (!teamModeEnabled) return;
|
||||
|
||||
SetGUIEnabled(false);
|
||||
BeginIndent(0);
|
||||
|
||||
Space(10);
|
||||
EditorGUILayout.LabelField("Now that Team Mode is enabled, create an empty script that inherits from VHierarchy.VHierarchyDataComponent and add it to any object in a scene.", style);
|
||||
|
||||
Space(6);
|
||||
GUILayout.Label("If such a script is present in a scene - all icon/color data for that scene will be serialized in that script, otherwise icon/color data for the scene will end up in this file.", style);
|
||||
|
||||
EndIndent(10);
|
||||
ResetGUIEnabled();
|
||||
}
|
||||
|
||||
normal();
|
||||
teamMode();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static bool teamModeEnabled { get => EditorPrefsCached.GetBool("vHierarchy-teamModeEnabled", false); set => EditorPrefsCached.SetBool("vHierarchy-teamModeEnabled", value); }
|
||||
|
||||
|
||||
|
||||
[ContextMenu("Enable Team Mode", isValidateFunction: false, priority: 1)]
|
||||
public void EnableTeamMode()
|
||||
{
|
||||
var option = EditorUtility.DisplayDialogComplex("Licensing notice",
|
||||
"To use vHierarchy 2 within a team, licenses must be purchased for each individual user as per the Asset Store EULA.\n\n Sharing one license across the team is illegal and considered piracy.",
|
||||
"Acknowledge",
|
||||
"Cancel",
|
||||
"Purchase more seats");
|
||||
if (option == 2)
|
||||
Application.OpenURL("https://prf.hn/click/camref:1100lGLBn/pubref:teammode/destination:https://assetstore.unity.com/packages/tools/utilities/vhierarchy-2-253397");
|
||||
// Application.OpenURL("https://assetstore.unity.com/packages/slug/253397");
|
||||
|
||||
|
||||
|
||||
if (option != 0) return;
|
||||
|
||||
teamModeEnabled = true;
|
||||
|
||||
VHierarchy.goInfoCache.Clear();
|
||||
VHierarchy.goDataCache.Clear();
|
||||
|
||||
EditorApplication.RepaintHierarchyWindow();
|
||||
|
||||
}
|
||||
|
||||
[ContextMenu("Disable Team Mode", isValidateFunction: false, priority: 2)]
|
||||
public void DisableTeamMode()
|
||||
{
|
||||
teamModeEnabled = false;
|
||||
|
||||
VHierarchy.goInfoCache.Clear();
|
||||
VHierarchy.goDataCache.Clear();
|
||||
|
||||
EditorApplication.RepaintHierarchyWindow();
|
||||
|
||||
}
|
||||
|
||||
[ContextMenu("Enable Team Mode", isValidateFunction: true, priority: 1)] bool asd() => !teamModeEnabled;
|
||||
[ContextMenu("Disable Team Mode", isValidateFunction: true, priority: 2)] bool ads() => teamModeEnabled;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3a9752b0c8e144801967e6897679604b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,142 @@
|
||||
#if UNITY_EDITOR
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.ShortcutManagement;
|
||||
using System.Reflection;
|
||||
using System.Linq;
|
||||
using UnityEngine.UIElements;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEditor.Experimental.SceneManagement;
|
||||
using Type = System.Type;
|
||||
using static VHierarchy.VHierarchyData;
|
||||
using static VHierarchy.Libs.VUtils;
|
||||
using static VHierarchy.Libs.VGUI;
|
||||
// using static VTools.VDebug;
|
||||
|
||||
|
||||
namespace VHierarchy
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
public abstract class VHierarchyDataComponent : MonoBehaviour, ISerializationCallbackReceiver
|
||||
{
|
||||
public void Awake()
|
||||
{
|
||||
void register()
|
||||
{
|
||||
VHierarchy.dataComponents_byScene[gameObject.scene] = this;
|
||||
}
|
||||
void handleSceneDuplication()
|
||||
{
|
||||
if (sceneData == null) return;
|
||||
if (!sceneData.goDatas_byGlobalId.Any()) return;
|
||||
|
||||
|
||||
var curSceneGuid = gameObject.scene.path.ToGuid();
|
||||
var dataSceneGuid = sceneData.goDatas_byGlobalId.Keys.First().guid;
|
||||
|
||||
if (curSceneGuid == dataSceneGuid) return;
|
||||
|
||||
|
||||
var newDic = new SerializableDictionary<GlobalID, GameObjectData>();
|
||||
|
||||
foreach (var kvp in sceneData.goDatas_byGlobalId)
|
||||
newDic[new GlobalID(kvp.Key.ToString().Replace(dataSceneGuid, curSceneGuid))] = kvp.Value;
|
||||
|
||||
|
||||
sceneData.goDatas_byGlobalId = newDic;
|
||||
|
||||
|
||||
EditorSceneManager.MarkSceneDirty(gameObject.scene);
|
||||
EditorSceneManager.SaveScene(gameObject.scene);
|
||||
|
||||
}
|
||||
|
||||
register();
|
||||
handleSceneDuplication();
|
||||
|
||||
}
|
||||
|
||||
|
||||
public SceneData sceneData;
|
||||
|
||||
|
||||
public void OnBeforeSerialize() => VHierarchy.goDataCache.Clear();
|
||||
public void OnAfterDeserialize() => VHierarchy.goDataCache.Clear();
|
||||
|
||||
|
||||
|
||||
[CustomEditor(typeof(VHierarchyDataComponent), true)]
|
||||
class Editor : UnityEditor.Editor
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
var style = new GUIStyle(EditorStyles.label) { wordWrap = true };
|
||||
|
||||
|
||||
void teamModeOn()
|
||||
{
|
||||
if (!VHierarchyData.teamModeEnabled) return;
|
||||
|
||||
SetGUIEnabled(false);
|
||||
BeginIndent(0);
|
||||
|
||||
Space(4);
|
||||
EditorGUILayout.LabelField("This component stores vHierarchy's data about which icons and colors are assigned to objects in this scene", style);
|
||||
|
||||
// Space(6);
|
||||
// EditorGUILayout.LabelField("You can disable Team Mode to store icon/color data in vHierarchy Data scriptable object, as it is done by default", style);
|
||||
|
||||
|
||||
Space(2);
|
||||
|
||||
EndIndent(10);
|
||||
ResetGUIEnabled();
|
||||
|
||||
|
||||
|
||||
|
||||
// Space(10);
|
||||
|
||||
// if (!GUILayout.Button("Disable Team Mode", GUILayout.Height(27))) return;
|
||||
|
||||
// VHierarchy.data?.DisableTeamMode();
|
||||
|
||||
}
|
||||
void teamModeOff()
|
||||
{
|
||||
if (VHierarchyData.teamModeEnabled) return;
|
||||
|
||||
SetGUIEnabled(false);
|
||||
BeginIndent(0);
|
||||
|
||||
Space(4);
|
||||
EditorGUILayout.LabelField("Enable Team Mode to store icon/color data for this scene in this component", style);
|
||||
|
||||
Space(2);
|
||||
|
||||
EndIndent(10);
|
||||
ResetGUIEnabled();
|
||||
|
||||
|
||||
|
||||
Space(4);
|
||||
|
||||
if (!GUILayout.Button("Enable Team Mode", GUILayout.Height(27))) return;
|
||||
|
||||
VHierarchy.data?.EnableTeamMode();
|
||||
|
||||
}
|
||||
|
||||
teamModeOn();
|
||||
teamModeOff();
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9e20c7ea1a24b4a899ba82e98ad2b375
|
||||
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,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 879081410e5ee4ddcb0145a4a9937193
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,6 @@
|
||||
|
||||
|
||||
// this file was present in a previus version and is supposed to be deleted now
|
||||
// but asset store update delivery system doesn't allow deleting files
|
||||
// so instead this file is now emptied
|
||||
// feel free to delete it if you want
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8710ada63f66c4909ab73d206f31e954
|
||||
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,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cd278e4ae9a8649f59f016c7d739ce1a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,6 @@
|
||||
|
||||
|
||||
// this file was present in a previus version and is supposed to be deleted now
|
||||
// but asset store update delivery system doesn't allow deleting files
|
||||
// so instead this file is now emptied
|
||||
// feel free to delete it if you want
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 25324ddc1ebdc4ee5b1d9902a8efafa7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,159 @@
|
||||
#if UNITY_EDITOR
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using static VHierarchy.Libs.VUtils;
|
||||
using static VHierarchy.Libs.VGUI;
|
||||
// using static VTools.VDebug;
|
||||
|
||||
|
||||
namespace VHierarchy
|
||||
{
|
||||
class VHierarchyMenu
|
||||
{
|
||||
|
||||
public static bool navigationBarEnabled { get => EditorPrefsCached.GetBool("vHierarchy-navigationBarEnabled", false); set => EditorPrefsCached.SetBool("vHierarchy-navigationBarEnabled", value); }
|
||||
public static bool sceneSelectorEnabled { get => EditorPrefsCached.GetBool("vHierarchy-sceneSelectorEnabled", false); set => EditorPrefsCached.SetBool("vHierarchy-sceneSelectorEnabled", value); }
|
||||
public static bool componentMinimapEnabled { get => EditorPrefsCached.GetBool("vHierarchy-componentMinimapEnabled", false); set => EditorPrefsCached.SetBool("vHierarchy-componentMinimapEnabled", value); }
|
||||
public static bool activationToggleEnabled { get => EditorPrefsCached.GetBool("vHierarchy-acctivationToggleEnabled", false); set => EditorPrefsCached.SetBool("vHierarchy-acctivationToggleEnabled", value); }
|
||||
public static bool hierarchyLinesEnabled { get => EditorPrefsCached.GetBool("vHierarchy-hierarchyLinesEnabled", false); set => EditorPrefsCached.SetBool("vHierarchy-hierarchyLinesEnabled", value); }
|
||||
public static bool minimalModeEnabled { get => EditorPrefsCached.GetBool("vHierarchy-minimalModeEnabled", false); set => EditorPrefsCached.SetBool("vHierarchy-minimalModeEnabled", value); }
|
||||
public static bool zebraStripingEnabled { get => EditorPrefsCached.GetBool("vHierarchy-zebraStripingEnabled", false); set => EditorPrefsCached.SetBool("vHierarchy-zebraStripingEnabled", value); }
|
||||
|
||||
public static bool toggleActiveEnabled { get => EditorPrefsCached.GetBool("vHierarchy-toggleActiveEnabled", true); set => EditorPrefsCached.SetBool("vHierarchy-toggleActiveEnabled", value); }
|
||||
public static bool focusEnabled { get => EditorPrefsCached.GetBool("vHierarchy-focusEnabled", true); set => EditorPrefsCached.SetBool("vHierarchy-focusEnabled", value); }
|
||||
public static bool deleteEnabled { get => EditorPrefsCached.GetBool("vHierarchy-deleteEnabled", true); set => EditorPrefsCached.SetBool("vHierarchy-deleteEnabled", value); }
|
||||
public static bool toggleExpandedEnabled { get => EditorPrefsCached.GetBool("vHierarchy-toggleExpandedEnabled", true); set => EditorPrefsCached.SetBool("vHierarchy-toggleExpandedEnabled", value); }
|
||||
public static bool isolateEnabled { get => EditorPrefsCached.GetBool("vHierarchy-collapseEverythingElseEnabled", true); set => EditorPrefsCached.SetBool("vHierarchy-collapseEverythingElseEnabled", value); }
|
||||
public static bool collapseEverythingEnabled { get => EditorPrefsCached.GetBool("vHierarchy-collapseEverythingEnabled", true); set => EditorPrefsCached.SetBool("vHierarchy-collapseEverythingEnabled", value); }
|
||||
public static bool setDefaultParentEnabled { get => EditorPrefsCached.GetBool("vHierarchy-setDefaultParentEnabled", true); set => EditorPrefsCached.SetBool("vHierarchy-setDefaultParentEnabled", value); }
|
||||
|
||||
public static bool pluginDisabled { get => EditorPrefsCached.GetBool("vHierarchy-pluginDisabled", false); set => EditorPrefsCached.SetBool("vHierarchy-pluginDisabled", value); }
|
||||
|
||||
|
||||
|
||||
|
||||
const string dir = "Tools/vHierarchy/";
|
||||
|
||||
const string navigationBar = dir + "Navigation bar";
|
||||
const string sceneSelector = dir + "Scene selector";
|
||||
const string componentMinimap = dir + "Component minimap";
|
||||
const string activationToggle = dir + "Activation toggle";
|
||||
const string hierarchyLines = dir + "Hierarchy lines";
|
||||
const string zebraStriping = dir + "Zebra striping";
|
||||
const string minimalMode = dir + "Minimal mode";
|
||||
|
||||
const string toggleActive = dir + "A to toggle active";
|
||||
const string focus = dir + "F to focus";
|
||||
const string delete = dir + "X to delete";
|
||||
const string toggleExpanded = dir + "E to expand or collapse";
|
||||
const string isolate = dir + "Shift-E to isolate";
|
||||
const string collapseEverything = dir + "Ctrl-Shift-E to collapse all";
|
||||
const string setDefaultParent = dir + "D to set default parent";
|
||||
|
||||
const string disablePlugin = dir + "Disable vHierarchy";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[MenuItem(dir + "Features", false, 1)] static void daasddsas() { }
|
||||
[MenuItem(dir + "Features", true, 1)] static bool dadsdasas123() => false;
|
||||
|
||||
[MenuItem(navigationBar, false, 2)] static void dadsaadsdsadasdsadadsas() { navigationBarEnabled = !navigationBarEnabled; EditorApplication.RepaintHierarchyWindow(); }
|
||||
[MenuItem(navigationBar, true, 2)] static bool dadsaddasdsasadadsdasadsas() { Menu.SetChecked(navigationBar, navigationBarEnabled); return !pluginDisabled; }
|
||||
|
||||
[MenuItem(sceneSelector, false, 3)] static void dadsaadsdsadassddsadadsas() { sceneSelectorEnabled = !sceneSelectorEnabled; EditorApplication.RepaintHierarchyWindow(); }
|
||||
[MenuItem(sceneSelector, true, 3)] static bool dadsaddasdsasadsdadsdasadsas() { Menu.SetChecked(sceneSelector, sceneSelectorEnabled); return !pluginDisabled; }
|
||||
|
||||
[MenuItem(componentMinimap, false, 4)] static void daadsdsadasdadsas() { componentMinimapEnabled = !componentMinimapEnabled; EditorApplication.RepaintHierarchyWindow(); }
|
||||
[MenuItem(componentMinimap, true, 4)] static bool dadsadasddasadsas() { Menu.SetChecked(componentMinimap, componentMinimapEnabled); return !pluginDisabled; }
|
||||
|
||||
[MenuItem(activationToggle, false, 5)] static void daadsdsadadsasdadsas() { activationToggleEnabled = !activationToggleEnabled; EditorApplication.RepaintHierarchyWindow(); }
|
||||
[MenuItem(activationToggle, true, 5)] static bool dadsadasdsaddasadsas() { Menu.SetChecked(activationToggle, activationToggleEnabled); return !pluginDisabled; }
|
||||
|
||||
[MenuItem(hierarchyLines, false, 6)] static void dadsadadsadadasss() { hierarchyLinesEnabled = !hierarchyLinesEnabled; EditorApplication.RepaintHierarchyWindow(); }
|
||||
[MenuItem(hierarchyLines, true, 6)] static bool dadsaddasdasaasddsas() { Menu.SetChecked(hierarchyLines, hierarchyLinesEnabled); return !pluginDisabled; }
|
||||
|
||||
[MenuItem(zebraStriping, false, 7)] static void dadsadadadssadsadass() { zebraStripingEnabled = !zebraStripingEnabled; EditorApplication.RepaintHierarchyWindow(); }
|
||||
[MenuItem(zebraStriping, true, 7)] static bool dadsaddadaadsssadsaasddsas() { Menu.SetChecked(zebraStriping, zebraStripingEnabled); return !pluginDisabled; }
|
||||
|
||||
[MenuItem(minimalMode, false, 8)] static void dadsadadasdsdasadadasss() { minimalModeEnabled = !minimalModeEnabled; EditorApplication.RepaintHierarchyWindow(); }
|
||||
[MenuItem(minimalMode, true, 8)] static bool dadsaddadsasdadsasaasddsas() { Menu.SetChecked(minimalMode, minimalModeEnabled); return !pluginDisabled; }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[MenuItem(dir + "Shortcuts", false, 101)] static void dadsas() { }
|
||||
[MenuItem(dir + "Shortcuts", true, 101)] static bool dadsas123() => false;
|
||||
|
||||
|
||||
|
||||
[MenuItem(setDefaultParent, false, 102)] static void dadsadasdsdasadasdsadadsas() => setDefaultParentEnabled = !setDefaultParentEnabled;
|
||||
[MenuItem(setDefaultParent, true, 102)] static bool dadsadsdadssdaasadadsdasadsas() { Menu.SetChecked(setDefaultParent, setDefaultParentEnabled); return !pluginDisabled; }
|
||||
|
||||
|
||||
[MenuItem(toggleActive, false, 103)] static void dadsadadsas() => toggleActiveEnabled = !toggleActiveEnabled;
|
||||
[MenuItem(toggleActive, true, 103)] static bool dadsaddasadsas() { Menu.SetChecked(toggleActive, toggleActiveEnabled); return !pluginDisabled; }
|
||||
|
||||
[MenuItem(focus, false, 104)] static void dadsadasdadsas() => focusEnabled = !focusEnabled;
|
||||
[MenuItem(focus, true, 104)] static bool dadsadsaddasadsas() { Menu.SetChecked(focus, focusEnabled); return !pluginDisabled; }
|
||||
|
||||
[MenuItem(delete, false, 105)] static void dadsadsadasdadsas() => deleteEnabled = !deleteEnabled;
|
||||
[MenuItem(delete, true, 105)] static bool dadsaddsasaddasadsas() { Menu.SetChecked(delete, deleteEnabled); return !pluginDisabled; }
|
||||
|
||||
[MenuItem(toggleExpanded, false, 106)] static void dadsadsadasdsadadsas() => toggleExpandedEnabled = !toggleExpandedEnabled;
|
||||
[MenuItem(toggleExpanded, true, 106)] static bool dadsaddsasadadsdasadsas() { Menu.SetChecked(toggleExpanded, toggleExpandedEnabled); return !pluginDisabled; }
|
||||
|
||||
[MenuItem(isolate, false, 107)] static void dadsadsasdadasdsadadsas() => isolateEnabled = !isolateEnabled;
|
||||
[MenuItem(isolate, true, 107)] static bool dadsaddsdasasadadsdasadsas() { Menu.SetChecked(isolate, isolateEnabled); return !pluginDisabled; }
|
||||
|
||||
[MenuItem(collapseEverything, false, 108)] static void dadsadsdasadasdsadadsas() => collapseEverythingEnabled = !collapseEverythingEnabled;
|
||||
[MenuItem(collapseEverything, true, 108)] static bool dadsaddssdaasadadsdasadsas() { Menu.SetChecked(collapseEverything, collapseEverythingEnabled); return !pluginDisabled; }
|
||||
|
||||
|
||||
|
||||
|
||||
[MenuItem(dir + "More", false, 1001)] static void daasadsddsas() { }
|
||||
[MenuItem(dir + "More", true, 1001)] static bool dadsadsdasas123() => false;
|
||||
|
||||
|
||||
[MenuItem(dir + "Open manual", false, 1002)]
|
||||
static void dadadssadsas() => Application.OpenURL("https://kubacho-lab.gitbook.io/vhierarchy-2");
|
||||
|
||||
[MenuItem(dir + "Join our Discord", false, 1003)]
|
||||
static void dadasdsas() => Application.OpenURL("https://discord.gg/pUektnZeJT");
|
||||
|
||||
|
||||
|
||||
|
||||
[MenuItem(dir + "Deals ending soon/Get vFolders 2 at 50% off", false, 1004)]
|
||||
static void dadadssadasdsas() => Application.OpenURL("https://assetstore.unity.com/packages/slug/255470?aid=1100lGLBn&pubref=deal50menu");
|
||||
|
||||
[MenuItem(dir + "Deals ending soon/Get vInspector 2 at 50% off", false, 1005)]
|
||||
static void dadadssasddsas() => Application.OpenURL("https://assetstore.unity.com/packages/slug/252297?aid=1100lGLBn&pubref=deal50menu");
|
||||
|
||||
[MenuItem(dir + "Deals ending soon/Get vTabs 2 at 50% off", false, 1006)]
|
||||
static void dadadadsssadsas() => Application.OpenURL("https://assetstore.unity.com/packages/slug/253396?aid=1100lGLBn&pubref=deal50menu");
|
||||
|
||||
[MenuItem(dir + "Deals ending soon/Get vFavorites 2 at 50% off", false, 1007)]
|
||||
static void dadadadsssadsadsas() => Application.OpenURL("https://assetstore.unity.com/packages/slug/263643?aid=1100lGLBn&pubref=deal50menu");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[MenuItem(disablePlugin, false, 10001)] static void dadsadsdasadasdasdsadadsas() { pluginDisabled = !pluginDisabled; UnityEditor.Compilation.CompilationPipeline.RequestScriptCompilation(); }
|
||||
[MenuItem(disablePlugin, true, 10001)] static bool dadsaddssdaasadsadadsdasadsas() { Menu.SetChecked(disablePlugin, pluginDisabled); return true; }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4d7f0448bdeda4aad9cfdd9e7c7ee27f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,6 @@
|
||||
|
||||
|
||||
// this file was present in a previus version and is supposed to be deleted now
|
||||
// but asset store update delivery system doesn't allow deleting files
|
||||
// so instead this file is now emptied
|
||||
// feel free to delete it if you want
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9ddf1decb62f94768bcaec3173017c87
|
||||
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,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b0951d821533c4f9486bb1430540ef3b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,221 @@
|
||||
#if UNITY_EDITOR
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.ShortcutManagement;
|
||||
using System.Reflection;
|
||||
using System.Linq;
|
||||
using UnityEngine.UIElements;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEditorInternal;
|
||||
using static VHierarchy.Libs.VUtils;
|
||||
using static VHierarchy.Libs.VGUI;
|
||||
// using static VTools.VDebug;
|
||||
|
||||
|
||||
namespace VHierarchy
|
||||
{
|
||||
public class VHierarchyPalette : ScriptableObject
|
||||
{
|
||||
public List<Color> colors = new();
|
||||
|
||||
public bool colorsEnabled;
|
||||
|
||||
public float colorSaturation = 1;
|
||||
public float colorBrightness = 1;
|
||||
public bool colorGradientsEnabled = true;
|
||||
|
||||
public void ResetColors()
|
||||
{
|
||||
colors.Clear();
|
||||
|
||||
for (int i = 0; i < colorsCount; i++)
|
||||
colors.Add(GetDefaultColor(i));
|
||||
|
||||
colorsEnabled = true;
|
||||
|
||||
this.Dirty();
|
||||
|
||||
}
|
||||
|
||||
public static Color GetDefaultColor(int colorIndex)
|
||||
{
|
||||
Color color = default;
|
||||
|
||||
void grey()
|
||||
{
|
||||
if (colorIndex >= greyColorsCount) return;
|
||||
|
||||
#if UNITY_2022_1_OR_NEWER
|
||||
color = Greyscale(isDarkTheme ? .16f : .9f);
|
||||
#else
|
||||
color = Greyscale(isDarkTheme ? .315f : .9f);
|
||||
#endif
|
||||
|
||||
}
|
||||
void rainbowDarkTheme()
|
||||
{
|
||||
if (colorIndex < greyColorsCount) return;
|
||||
if (!isDarkTheme) return;
|
||||
|
||||
color = ColorUtils.HSLToRGB((colorIndex - greyColorsCount.ToFloat()) / rainbowColorsCount, .45f, .35f);
|
||||
|
||||
if (colorIndex == 1)
|
||||
color *= 1.2f;
|
||||
|
||||
if (colorIndex == 2)
|
||||
color *= 1.1f;
|
||||
|
||||
if (colorIndex == 6)
|
||||
color *= 1.35f;
|
||||
|
||||
if (colorIndex == 7)
|
||||
color *= 1.3f;
|
||||
|
||||
if (colorIndex == 8)
|
||||
color *= 1.05f;
|
||||
|
||||
|
||||
color.a = .1f;
|
||||
|
||||
}
|
||||
void rainbowLightTheme()
|
||||
{
|
||||
if (colorIndex < greyColorsCount) return;
|
||||
if (isDarkTheme) return;
|
||||
|
||||
color = ColorUtils.HSLToRGB((colorIndex - greyColorsCount.ToFloat()) / rainbowColorsCount, .62f, .8f);
|
||||
|
||||
color.a = .1f;
|
||||
|
||||
}
|
||||
|
||||
grey();
|
||||
rainbowDarkTheme();
|
||||
rainbowLightTheme();
|
||||
|
||||
return color;
|
||||
|
||||
}
|
||||
|
||||
public static int greyColorsCount = 1;
|
||||
public static int rainbowColorsCount = 8;
|
||||
public static int colorsCount => greyColorsCount + rainbowColorsCount;
|
||||
|
||||
|
||||
|
||||
|
||||
public List<IconRow> iconRows = new();
|
||||
|
||||
[System.Serializable]
|
||||
public class IconRow
|
||||
{
|
||||
public List<string> builtinIcons = new(); // names
|
||||
public List<string> customIcons = new(); // names or guids
|
||||
|
||||
public bool enabled = true;
|
||||
|
||||
public bool isCustom => !builtinIcons.Any() || customIcons.Any();
|
||||
public bool isEmpty => !builtinIcons.Any() && !customIcons.Any();
|
||||
public int iconCount => builtinIcons.Count + customIcons.Count;
|
||||
|
||||
public IconRow(string[] builtinIcons) => this.builtinIcons = builtinIcons.ToList();
|
||||
public IconRow() { }
|
||||
|
||||
}
|
||||
|
||||
public void ResetIcons()
|
||||
{
|
||||
iconRows.Clear();
|
||||
|
||||
iconRows.Add(new IconRow(new[]
|
||||
{
|
||||
"Folder Icon",
|
||||
"Canvas Icon",
|
||||
"AvatarMask On Icon",
|
||||
"cs Script Icon",
|
||||
"StandaloneInputModule Icon",
|
||||
"EventSystem Icon",
|
||||
"Terrain Icon",
|
||||
"ScriptableObject Icon",
|
||||
|
||||
}));
|
||||
iconRows.Add(new IconRow(new[]
|
||||
{
|
||||
"Camera Icon",
|
||||
"ParticleSystem Icon",
|
||||
"TrailRenderer Icon",
|
||||
"Material Icon",
|
||||
"ReflectionProbe Icon",
|
||||
|
||||
}));
|
||||
iconRows.Add(new IconRow(new[]
|
||||
{
|
||||
"Light Icon",
|
||||
"DirectionalLight Icon",
|
||||
"LightmapParameters Icon",
|
||||
"LightProbes Icon",
|
||||
|
||||
}));
|
||||
iconRows.Add(new IconRow(new[]
|
||||
{
|
||||
"Rigidbody Icon",
|
||||
"BoxCollider Icon",
|
||||
"SphereCollider Icon",
|
||||
"CapsuleCollider Icon",
|
||||
"WheelCollider Icon",
|
||||
"MeshCollider Icon",
|
||||
|
||||
}));
|
||||
iconRows.Add(new IconRow(new[]
|
||||
{
|
||||
"AudioSource Icon",
|
||||
"AudioClip Icon",
|
||||
"AudioListener Icon",
|
||||
"AudioEchoFilter Icon",
|
||||
"AudioReverbZone Icon",
|
||||
|
||||
}));
|
||||
iconRows.Add(new IconRow(new[]
|
||||
{
|
||||
"PreMatCube",
|
||||
"PreMatSphere",
|
||||
"PreMatCylinder",
|
||||
"PreMatQuad",
|
||||
"Favorite",
|
||||
#if UNITY_2021_3_OR_NEWER
|
||||
"Settings Icon",
|
||||
#endif
|
||||
|
||||
}));
|
||||
|
||||
this.Dirty();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
[ContextMenu("Export palette")]
|
||||
public void Export()
|
||||
{
|
||||
var packagePath = EditorUtility.SaveFilePanel("Export vHierarchy Palette", "", this.GetPath().GetFilename(withExtension: false), "unitypackage");
|
||||
|
||||
var iconPaths = iconRows.SelectMany(r => r.customIcons).Select(r => r.ToPath()).Where(r => !r.IsNullOrEmpty());
|
||||
|
||||
AssetDatabase.ExportPackage(iconPaths.Append(this.GetPath()).ToArray(), packagePath);
|
||||
|
||||
EditorUtility.RevealInFinder(packagePath);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Reset() { ResetColors(); ResetIcons(); }
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 61290d425f1c94a8cbfb56f754ca6757
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user