Init
This commit is contained in:
@@ -0,0 +1,67 @@
|
|||||||
|
# Keep Unity's human-readable project files consistent across platforms.
|
||||||
|
* text=auto
|
||||||
|
.gitignore text eol=lf
|
||||||
|
.gitattributes text eol=lf
|
||||||
|
*.cs text eol=lf
|
||||||
|
*.shader text eol=lf
|
||||||
|
*.hlsl text eol=lf
|
||||||
|
*.cginc text eol=lf
|
||||||
|
*.compute text eol=lf
|
||||||
|
*.asmdef text eol=lf
|
||||||
|
*.asmref text eol=lf
|
||||||
|
*.json text eol=lf
|
||||||
|
*.xml text eol=lf
|
||||||
|
*.yaml text eol=lf
|
||||||
|
*.yml text eol=lf
|
||||||
|
*.uxml text eol=lf
|
||||||
|
*.uss text eol=lf
|
||||||
|
*.txt text eol=lf
|
||||||
|
*.md text eol=lf
|
||||||
|
*.meta text eol=lf
|
||||||
|
|
||||||
|
# Unity SmartMerge for YAML-serialized assets.
|
||||||
|
*.unity text eol=lf merge=unityyamlmerge
|
||||||
|
*.prefab text eol=lf merge=unityyamlmerge
|
||||||
|
*.asset text eol=lf merge=unityyamlmerge
|
||||||
|
*.mat text eol=lf merge=unityyamlmerge
|
||||||
|
*.anim text eol=lf merge=unityyamlmerge
|
||||||
|
*.controller text eol=lf merge=unityyamlmerge
|
||||||
|
*.overrideController text eol=lf merge=unityyamlmerge
|
||||||
|
*.playable text eol=lf merge=unityyamlmerge
|
||||||
|
*.mask text eol=lf merge=unityyamlmerge
|
||||||
|
*.spriteatlas text eol=lf merge=unityyamlmerge
|
||||||
|
*.physicsMaterial2D text eol=lf merge=unityyamlmerge
|
||||||
|
*.physicMaterial text eol=lf merge=unityyamlmerge
|
||||||
|
*.terrainlayer text eol=lf merge=unityyamlmerge
|
||||||
|
*.renderTexture text eol=lf merge=unityyamlmerge
|
||||||
|
*.lighting text eol=lf merge=unityyamlmerge
|
||||||
|
*.preset text eol=lf merge=unityyamlmerge
|
||||||
|
*.guiskin text eol=lf merge=unityyamlmerge
|
||||||
|
|
||||||
|
# Source-art and runtime media are binary and belong in Git LFS.
|
||||||
|
*.psd filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.psb filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.png filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.jpg filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.jpeg filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.tga filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.tif filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.tiff filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.exr filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.hdr filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.webp filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.fbx filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.blend filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.glb filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.wav filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.mp3 filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.ogg filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.aif filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.aiff filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.flac filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.mp4 filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.mov filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.avi filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.webm filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.ttf filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.otf filter=lfs diff=lfs merge=lfs -text
|
||||||
@@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
# Visual Studio cache directory
|
# Visual Studio cache directory
|
||||||
.vs/
|
.vs/
|
||||||
|
.vscode/
|
||||||
|
|
||||||
# Gradle cache directory
|
# Gradle cache directory
|
||||||
.gradle/
|
.gradle/
|
||||||
@@ -47,6 +48,8 @@ ExportedObj/
|
|||||||
*.mdb
|
*.mdb
|
||||||
*.opendb
|
*.opendb
|
||||||
*.VC.db
|
*.VC.db
|
||||||
|
*.VC.opendb
|
||||||
|
*.slnx
|
||||||
|
|
||||||
# Unity3D generated meta files
|
# Unity3D generated meta files
|
||||||
*.pidb.meta
|
*.pidb.meta
|
||||||
|
|||||||
@@ -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
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user