mirror of
https://github.com/AnnulusGames/Alchemy.git
synced 2025-01-22 08:18:51 -05:00
Merge pull request #18 from AnnulusGames/feature-hierarchy-extensions
Feature: hierarchy extensions
This commit is contained in:
commit
43d241c0bd
42
Alchemy/Assets/Alchemy/Editor/AlchemySettings.cs
Normal file
42
Alchemy/Assets/Alchemy/Editor/AlchemySettings.cs
Normal file
@ -0,0 +1,42 @@
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using Alchemy.Hierarchy;
|
||||
|
||||
namespace Alchemy.Editor
|
||||
{
|
||||
public sealed class AlchemySettings : ScriptableObject
|
||||
{
|
||||
static readonly string SettingsPath = "ProjectSettings/AlchemySettings.json";
|
||||
|
||||
static AlchemySettings instance;
|
||||
public static AlchemySettings GetOrCreateSettings()
|
||||
{
|
||||
if (instance != null) return instance;
|
||||
|
||||
if (File.Exists(SettingsPath))
|
||||
{
|
||||
instance = CreateInstance<AlchemySettings>();
|
||||
JsonUtility.FromJsonOverwrite(File.ReadAllText(SettingsPath), instance);
|
||||
}
|
||||
else
|
||||
{
|
||||
instance = CreateInstance<AlchemySettings>();
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static void SaveSettings()
|
||||
{
|
||||
File.WriteAllText(SettingsPath, JsonUtility.ToJson(instance, true));
|
||||
}
|
||||
|
||||
[SerializeField] HierarchyObjectMode hierarchyObjectMode = HierarchyObjectMode.RemoveInBuild;
|
||||
[SerializeField] bool showHierarchyToggles;
|
||||
[SerializeField] bool showComponentIcons;
|
||||
|
||||
public HierarchyObjectMode HierarchyObjectMode => hierarchyObjectMode;
|
||||
public bool ShowHierarchyToggles => showHierarchyToggles;
|
||||
public bool ShowComponentIcons => showComponentIcons;
|
||||
}
|
||||
}
|
11
Alchemy/Assets/Alchemy/Editor/AlchemySettings.cs.meta
Normal file
11
Alchemy/Assets/Alchemy/Editor/AlchemySettings.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: be6c5afdb20ff4718b97d2eeeb1787e2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
47
Alchemy/Assets/Alchemy/Editor/AlchemySettingsProvider.cs
Normal file
47
Alchemy/Assets/Alchemy/Editor/AlchemySettingsProvider.cs
Normal file
@ -0,0 +1,47 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Alchemy.Editor
|
||||
{
|
||||
internal static class AlchemySettingsProvider
|
||||
{
|
||||
static readonly string MenuName = "Project/Alchemy";
|
||||
|
||||
[SettingsProvider]
|
||||
public static SettingsProvider CreateSettingsProvider()
|
||||
{
|
||||
return new SettingsProvider(MenuName, SettingsScope.Project)
|
||||
{
|
||||
label = "Alchemy",
|
||||
keywords = new HashSet<string>(new[] { "Alchemy, Inspector, Hierarchy" }),
|
||||
guiHandler = searchContext =>
|
||||
{
|
||||
var serializedObject = new SerializedObject(AlchemySettings.GetOrCreateSettings());
|
||||
|
||||
using (new EditorGUILayout.HorizontalScope())
|
||||
{
|
||||
GUILayout.Space(10f);
|
||||
using (new EditorGUILayout.VerticalScope())
|
||||
{
|
||||
EditorGUILayout.LabelField("Hierarchy", EditorStyles.boldLabel);
|
||||
|
||||
using (var changeCheck = new EditorGUI.ChangeCheckScope())
|
||||
{
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("hierarchyObjectMode"));
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("showHierarchyToggles"), new GUIContent("Show Toggles"));
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("showComponentIcons"));
|
||||
|
||||
if (changeCheck.changed)
|
||||
{
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
AlchemySettings.SaveSettings();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7430b79e486304556b32ebe13b6674b2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Alchemy/Assets/Alchemy/Editor/Hierarchy.meta
Normal file
8
Alchemy/Assets/Alchemy/Editor/Hierarchy.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7706aa48d1fdb4b70a5b1730f9a590b9
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
40
Alchemy/Assets/Alchemy/Editor/Hierarchy/HierarchyDrawer.cs
Normal file
40
Alchemy/Assets/Alchemy/Editor/Hierarchy/HierarchyDrawer.cs
Normal file
@ -0,0 +1,40 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Alchemy.Editor.Internal;
|
||||
|
||||
namespace Alchemy.Editor
|
||||
{
|
||||
public abstract class HierarchyDrawer
|
||||
{
|
||||
public abstract void OnGUI(int instanceID, Rect selectionRect);
|
||||
|
||||
protected static Rect GetBackgroundRect(Rect selectionRect)
|
||||
{
|
||||
return selectionRect.AddXMax(20f);
|
||||
}
|
||||
|
||||
protected static void DrawBackground(int instanceID, Rect selectionRect)
|
||||
{
|
||||
var backgroundRect = GetBackgroundRect(selectionRect);
|
||||
|
||||
Color backgroundColor;
|
||||
var e = Event.current;
|
||||
var isHover = backgroundRect.Contains(e.mousePosition);
|
||||
|
||||
if (Selection.Contains(instanceID))
|
||||
{
|
||||
backgroundColor = EditorColors.HighlightBackground;
|
||||
}
|
||||
else if (isHover)
|
||||
{
|
||||
backgroundColor = EditorColors.HighlightBackgroundInactive;
|
||||
}
|
||||
else
|
||||
{
|
||||
backgroundColor = EditorColors.WindowBackground;
|
||||
}
|
||||
|
||||
EditorGUI.DrawRect(backgroundRect, backgroundColor);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 99c62ee36c15445da9b11f082910fdfd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Alchemy.Editor
|
||||
{
|
||||
internal static class HierarchyDrawerInitializer
|
||||
{
|
||||
[InitializeOnLoadMethod]
|
||||
static void Init()
|
||||
{
|
||||
var drawers = TypeCache.GetTypesDerivedFrom<HierarchyDrawer>()
|
||||
.Where(x => !x.IsAbstract)
|
||||
.Select(x => (HierarchyDrawer)Activator.CreateInstance(x));
|
||||
|
||||
foreach (var drawer in drawers)
|
||||
{
|
||||
EditorApplication.hierarchyWindowItemOnGUI += drawer.OnGUI;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3b5afaf0d349640efa275f491f5caf46
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,34 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Alchemy.Hierarchy;
|
||||
|
||||
namespace Alchemy.Editor
|
||||
{
|
||||
public sealed class HierarchyHeaderDrawer : HierarchyDrawer
|
||||
{
|
||||
static Color HeaderColor => EditorGUIUtility.isProSkin ? new(0.45f, 0.45f, 0.45f, 0.5f) : new(0.55f, 0.55f, 0.55f, 0.5f);
|
||||
static GUIStyle labelStyle;
|
||||
|
||||
public override void OnGUI(int instanceID, Rect selectionRect)
|
||||
{
|
||||
if (labelStyle == null)
|
||||
{
|
||||
labelStyle = new GUIStyle(EditorStyles.boldLabel)
|
||||
{
|
||||
alignment = TextAnchor.MiddleCenter,
|
||||
fontSize = 11,
|
||||
};
|
||||
}
|
||||
|
||||
var gameObject = EditorUtility.InstanceIDToObject(instanceID) as GameObject;
|
||||
if (gameObject == null) return;
|
||||
if (!gameObject.TryGetComponent<HierarchyHeader>(out _)) return;
|
||||
|
||||
DrawBackground(instanceID, selectionRect);
|
||||
|
||||
var headerRect = selectionRect.AddXMax(14f).AddYMax(-1f);
|
||||
EditorGUI.DrawRect(headerRect, HeaderColor);
|
||||
EditorGUI.LabelField(headerRect, gameObject.name, labelStyle);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 21aad9026029c4fdfa791adb1c12777b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,29 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Alchemy.Hierarchy;
|
||||
|
||||
namespace Alchemy.Editor
|
||||
{
|
||||
internal static class HierarchyObjectCreationMenu
|
||||
{
|
||||
[MenuItem("GameObject/Alchemy/Header", false)]
|
||||
static void CreateHeader(MenuCommand menuCommand)
|
||||
{
|
||||
var obj = new GameObject("Header");
|
||||
obj.AddComponent<HierarchyHeader>();
|
||||
GameObjectUtility.SetParentAndAlign(obj, menuCommand.context as GameObject);
|
||||
Undo.RegisterCreatedObjectUndo(obj, "Create " + obj.name);
|
||||
Selection.activeObject = obj;
|
||||
}
|
||||
|
||||
[MenuItem("GameObject/Alchemy/Separator", false)]
|
||||
static void CreateSeparator(MenuCommand menuCommand)
|
||||
{
|
||||
var obj = new GameObject("Separator");
|
||||
obj.AddComponent<HierarchySeparator>();
|
||||
GameObjectUtility.SetParentAndAlign(obj, menuCommand.context as GameObject);
|
||||
Undo.RegisterCreatedObjectUndo(obj, "Create " + obj.name);
|
||||
Selection.activeObject = obj;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0a76950d5487d4ea9a206d592736591b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,26 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine.UIElements;
|
||||
using Alchemy.Hierarchy;
|
||||
using UnityEditor.UIElements;
|
||||
|
||||
namespace Alchemy.Editor
|
||||
{
|
||||
[CustomEditor(typeof(HierarchyObject), true)]
|
||||
[CanEditMultipleObjects]
|
||||
public sealed class HierarchyObjectEditor : UnityEditor.Editor
|
||||
{
|
||||
public override VisualElement CreateInspectorGUI()
|
||||
{
|
||||
var root = new VisualElement();
|
||||
var iterator = serializedObject.GetIterator();
|
||||
iterator.NextVisible(true);
|
||||
|
||||
while (iterator.NextVisible(false))
|
||||
{
|
||||
root.Add(new PropertyField(iterator));
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ad667e8cf560a44f7a8d1cfd5f79f2df
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,64 @@
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Build;
|
||||
using UnityEditor.Build.Reporting;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using Alchemy.Hierarchy;
|
||||
|
||||
namespace Alchemy.Editor
|
||||
{
|
||||
public sealed class HierarchyObjectProcessor : IProcessSceneWithReport
|
||||
{
|
||||
public int callbackOrder => 0;
|
||||
|
||||
public void OnProcessScene(Scene scene, BuildReport report)
|
||||
{
|
||||
var settings = AlchemySettings.GetOrCreateSettings();
|
||||
|
||||
var hierarchyObjects = scene.GetRootGameObjects()
|
||||
.SelectMany(x => x.GetComponentsInChildren<HierarchyObject>())
|
||||
.Where(x => x != null)
|
||||
.OrderByDescending(x => GetDepth(x.transform));
|
||||
|
||||
foreach (var obj in hierarchyObjects)
|
||||
{
|
||||
if (obj == null) continue;
|
||||
|
||||
switch (GetHierarchyObjectMode(obj))
|
||||
{
|
||||
case HierarchyObjectMode.None:
|
||||
break;
|
||||
case HierarchyObjectMode.RemoveInPlayMode:
|
||||
obj.transform.DetachChildren();
|
||||
Object.DestroyImmediate(obj.gameObject);
|
||||
break;
|
||||
case HierarchyObjectMode.RemoveInBuild:
|
||||
if (EditorApplication.isPlaying) break;
|
||||
obj.transform.DetachChildren();
|
||||
Object.DestroyImmediate(obj.gameObject);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static HierarchyObjectMode GetHierarchyObjectMode(HierarchyObject obj)
|
||||
{
|
||||
return obj.HierarchyObjectMode != HierarchyObject.Mode.UseSettings
|
||||
? (HierarchyObjectMode)(obj.HierarchyObjectMode - 1)
|
||||
: AlchemySettings.GetOrCreateSettings().HierarchyObjectMode;
|
||||
}
|
||||
|
||||
static int GetDepth(Transform transform)
|
||||
{
|
||||
var depth = 0;
|
||||
var parent = transform.parent;
|
||||
while (parent != null)
|
||||
{
|
||||
depth++;
|
||||
parent = parent.parent;
|
||||
}
|
||||
return depth;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 41689920aa3aa442ab979a1a81dd7568
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,23 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Alchemy.Hierarchy;
|
||||
|
||||
namespace Alchemy.Editor
|
||||
{
|
||||
public sealed class HierarchySeparatorDrawer : HierarchyDrawer
|
||||
{
|
||||
static Color SeparatorColor => new(0.5f, 0.5f, 0.5f);
|
||||
|
||||
public override void OnGUI(int instanceID, Rect selectionRect)
|
||||
{
|
||||
var gameObject = EditorUtility.InstanceIDToObject(instanceID) as GameObject;
|
||||
if (gameObject == null) return;
|
||||
if (!gameObject.TryGetComponent<HierarchySeparator>(out _)) return;
|
||||
|
||||
DrawBackground(instanceID, selectionRect);
|
||||
|
||||
var lineRect = selectionRect.AddY(selectionRect.height * 0.5f).AddXMax(14f).SetHeight(1f);
|
||||
EditorGUI.DrawRect(lineRect, SeparatorColor);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cf8a3062aab50494990244011aa1ec06
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,82 @@
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Alchemy.Hierarchy;
|
||||
using Alchemy.Editor.Internal;
|
||||
|
||||
namespace Alchemy.Editor
|
||||
{
|
||||
public sealed class HierarchyToggleDrawer : HierarchyDrawer
|
||||
{
|
||||
public override void OnGUI(int instanceID, Rect selectionRect)
|
||||
{
|
||||
var gameObject = EditorUtility.InstanceIDToObject(instanceID) as GameObject;
|
||||
if (gameObject == null) return;
|
||||
if (gameObject.TryGetComponent<HierarchyObject>(out _)) return;
|
||||
|
||||
var settings = AlchemySettings.GetOrCreateSettings();
|
||||
|
||||
if (settings.ShowHierarchyToggles)
|
||||
{
|
||||
var rect = selectionRect;
|
||||
rect.x = rect.xMax - 2.7f;
|
||||
rect.width = 16f;
|
||||
|
||||
var active = GUI.Toggle(rect, gameObject.activeSelf, string.Empty);
|
||||
if (active != gameObject.activeSelf)
|
||||
{
|
||||
Undo.RecordObject(gameObject, $"{(active ? "Activate" : "Deactivate")} GameObject '{gameObject.name}'");
|
||||
gameObject.SetActive(active);
|
||||
EditorUtility.SetDirty(gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
if (settings.ShowComponentIcons)
|
||||
{
|
||||
var rect = selectionRect;
|
||||
rect.x = rect.xMax - (settings.ShowHierarchyToggles ? 18.7f : 2.7f);
|
||||
rect.y += 1f;
|
||||
rect.width = 14f;
|
||||
rect.height = 14f;
|
||||
|
||||
var components = gameObject
|
||||
.GetComponents<Component>()
|
||||
.AsEnumerable()
|
||||
.Reverse();
|
||||
|
||||
var existsScriptIcon = false;
|
||||
foreach (var component in components)
|
||||
{
|
||||
var image = AssetPreview.GetMiniThumbnail(component);
|
||||
if (image == null) continue;
|
||||
|
||||
if (image == EditorIcons.CsScriptIcon.image)
|
||||
{
|
||||
if (existsScriptIcon) continue;
|
||||
existsScriptIcon = true;
|
||||
}
|
||||
|
||||
DrawIcon(ref rect, image, IsEnabled(component) ? Color.white : new(1f, 1f, 1f, 0.5f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void DrawIcon(ref Rect rect, Texture image, Color color)
|
||||
{
|
||||
var defaultColor = GUI.color;
|
||||
GUI.color = color;
|
||||
|
||||
GUI.DrawTexture(rect, image, ScaleMode.ScaleToFit);
|
||||
rect.x -= rect.width;
|
||||
|
||||
GUI.color = defaultColor;
|
||||
}
|
||||
|
||||
static bool IsEnabled(Component component)
|
||||
{
|
||||
var property = component.GetType().GetProperty("enabled", typeof(bool));
|
||||
return (bool)(property?.GetValue(component, null) ?? true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 527cfc72d81d34166ab175d08e86e0b5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
71
Alchemy/Assets/Alchemy/Editor/Internal/EditorColors.cs
Normal file
71
Alchemy/Assets/Alchemy/Editor/Internal/EditorColors.cs
Normal file
@ -0,0 +1,71 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System;
|
||||
|
||||
namespace Alchemy.Editor.Internal
|
||||
{
|
||||
// Rererence: https://www.foundations.unity.com/fundamentals/color-palette
|
||||
|
||||
internal static class EditorColors
|
||||
{
|
||||
static Color GetColor(string htmlColor)
|
||||
{
|
||||
if (!ColorUtility.TryParseHtmlString(htmlColor, out var color)) throw new ArgumentException();
|
||||
return color;
|
||||
}
|
||||
|
||||
public static Color DefaultBackground
|
||||
{
|
||||
get
|
||||
{
|
||||
if (EditorGUIUtility.isProSkin) return GetColor("#282828");
|
||||
else return GetColor("#A5A5A5");
|
||||
}
|
||||
}
|
||||
|
||||
public static Color HighlightBackgroundInactive
|
||||
{
|
||||
get
|
||||
{
|
||||
if (EditorGUIUtility.isProSkin) return GetColor("#4D4D4D");
|
||||
else return GetColor("#AEAEAE");
|
||||
}
|
||||
}
|
||||
|
||||
public static Color HighlightBackground
|
||||
{
|
||||
get
|
||||
{
|
||||
if (EditorGUIUtility.isProSkin) return GetColor("#2C5D87");
|
||||
else return GetColor("#3A72B0");
|
||||
}
|
||||
}
|
||||
|
||||
public static Color WindowBackground
|
||||
{
|
||||
get
|
||||
{
|
||||
if (EditorGUIUtility.isProSkin) return GetColor("#383838");
|
||||
else return GetColor("#C8C8C8");
|
||||
}
|
||||
}
|
||||
|
||||
public static Color InspectorTitlebarBorder
|
||||
{
|
||||
get
|
||||
{
|
||||
if (EditorGUIUtility.isProSkin) return GetColor("#1A1A1A");
|
||||
else return GetColor("#7F7F7F");
|
||||
}
|
||||
}
|
||||
|
||||
public static Color DefaultText
|
||||
{
|
||||
get
|
||||
{
|
||||
if (EditorGUIUtility.isProSkin) return GetColor("#D2D2D2");
|
||||
else return GetColor("#090909");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
Alchemy/Assets/Alchemy/Editor/Internal/EditorColors.cs.meta
Normal file
11
Alchemy/Assets/Alchemy/Editor/Internal/EditorColors.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e417a3e095b0d43a1b3d886d05d2b4c6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
78
Alchemy/Assets/Alchemy/Editor/Internal/RectHelper.cs
Normal file
78
Alchemy/Assets/Alchemy/Editor/Internal/RectHelper.cs
Normal file
@ -0,0 +1,78 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Alchemy.Editor
|
||||
{
|
||||
internal static class RectHelper
|
||||
{
|
||||
public static Rect Expand(this Rect rect, float value)
|
||||
{
|
||||
rect.xMin -= value;
|
||||
rect.xMax += value;
|
||||
rect.yMin -= value;
|
||||
rect.yMax += value;
|
||||
return rect;
|
||||
}
|
||||
|
||||
public static Rect ExpandX(this Rect rect, float value)
|
||||
{
|
||||
rect.xMin -= value;
|
||||
rect.xMax += value;
|
||||
return rect;
|
||||
}
|
||||
|
||||
public static Rect ExpandY(this Rect rect, float value)
|
||||
{
|
||||
rect.yMin -= value;
|
||||
rect.yMax += value;
|
||||
return rect;
|
||||
}
|
||||
|
||||
public static Rect AddX(this Rect rect, float value)
|
||||
{
|
||||
rect.x += value;
|
||||
return rect;
|
||||
}
|
||||
|
||||
public static Rect AddY(this Rect rect, float value)
|
||||
{
|
||||
rect.y += value;
|
||||
return rect;
|
||||
}
|
||||
|
||||
public static Rect AddXMin(this Rect rect, float value)
|
||||
{
|
||||
rect.xMin += value;
|
||||
return rect;
|
||||
}
|
||||
|
||||
public static Rect AddXMax(this Rect rect, float value)
|
||||
{
|
||||
rect.xMax += value;
|
||||
return rect;
|
||||
}
|
||||
|
||||
public static Rect AddYMin(this Rect rect, float value)
|
||||
{
|
||||
rect.yMin += value;
|
||||
return rect;
|
||||
}
|
||||
|
||||
public static Rect AddYMax(this Rect rect, float value)
|
||||
{
|
||||
rect.yMax += value;
|
||||
return rect;
|
||||
}
|
||||
|
||||
public static Rect SetWidth(this Rect rect, float value)
|
||||
{
|
||||
rect.width = value;
|
||||
return rect;
|
||||
}
|
||||
|
||||
public static Rect SetHeight(this Rect rect, float value)
|
||||
{
|
||||
rect.height = value;
|
||||
return rect;
|
||||
}
|
||||
}
|
||||
}
|
11
Alchemy/Assets/Alchemy/Editor/Internal/RectHelper.cs.meta
Normal file
11
Alchemy/Assets/Alchemy/Editor/Internal/RectHelper.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4ebc9adffd3924cb68c38dd5d6789d24
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Alchemy/Assets/Alchemy/Runtime/Hierarchy.meta
Normal file
8
Alchemy/Assets/Alchemy/Runtime/Hierarchy.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f1d5771148ed6492c9fb410ac314cb84
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,7 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Alchemy.Hierarchy
|
||||
{
|
||||
[AddComponentMenu("Alchemy/Hierarchy Header")]
|
||||
public sealed class HierarchyHeader : HierarchyObject { }
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f517a64d7c9c64b32922a42317242caf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
20
Alchemy/Assets/Alchemy/Runtime/Hierarchy/HierarchyObject.cs
Normal file
20
Alchemy/Assets/Alchemy/Runtime/Hierarchy/HierarchyObject.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Alchemy.Hierarchy
|
||||
{
|
||||
[DisallowMultipleComponent]
|
||||
[AddComponentMenu("Alchemy/Hierarchy Object")]
|
||||
public class HierarchyObject : MonoBehaviour
|
||||
{
|
||||
public enum Mode
|
||||
{
|
||||
UseSettings = 0,
|
||||
None = 1,
|
||||
RemoveInPlayMode = 2,
|
||||
RemoveInBuild = 3
|
||||
}
|
||||
|
||||
[SerializeField] Mode hierarchyObjectMode = Mode.UseSettings;
|
||||
public Mode HierarchyObjectMode => hierarchyObjectMode;
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3887b4614e88d4da584077c7dc0e6b90
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,9 @@
|
||||
namespace Alchemy.Hierarchy
|
||||
{
|
||||
public enum HierarchyObjectMode
|
||||
{
|
||||
None = 0,
|
||||
RemoveInPlayMode = 1,
|
||||
RemoveInBuild = 2
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ed6b9dff8345a4f5f91110010d6d7d54
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,7 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Alchemy.Hierarchy
|
||||
{
|
||||
[AddComponentMenu("Alchemy/Hierarchy Separator")]
|
||||
public sealed class HierarchySeparator : HierarchyObject { }
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 941cd1bade9ee428cbf8dc33883c67b8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
5
Alchemy/ProjectSettings/AlchemySettings.json
Normal file
5
Alchemy/ProjectSettings/AlchemySettings.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"hierarchyObjectMode": 2,
|
||||
"showHierarchyToggles": true,
|
||||
"showComponentIcons": true
|
||||
}
|
@ -6,7 +6,7 @@ QualitySettings:
|
||||
serializedVersion: 5
|
||||
m_CurrentQuality: 5
|
||||
m_QualitySettings:
|
||||
- serializedVersion: 2
|
||||
- serializedVersion: 3
|
||||
name: Very Low
|
||||
pixelLightCount: 0
|
||||
shadows: 0
|
||||
@ -18,17 +18,21 @@ QualitySettings:
|
||||
shadowCascade2Split: 0.33333334
|
||||
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
|
||||
shadowmaskMode: 0
|
||||
blendWeights: 1
|
||||
textureQuality: 1
|
||||
skinWeights: 1
|
||||
globalTextureMipmapLimit: 1
|
||||
textureMipmapLimitSettings: []
|
||||
anisotropicTextures: 0
|
||||
antiAliasing: 0
|
||||
softParticles: 0
|
||||
softVegetation: 0
|
||||
realtimeReflectionProbes: 0
|
||||
billboardsFaceCameraPosition: 0
|
||||
useLegacyDetailDistribution: 1
|
||||
vSyncCount: 0
|
||||
realtimeGICPUUsage: 25
|
||||
lodBias: 0.3
|
||||
maximumLODLevel: 0
|
||||
enableLODCrossFade: 1
|
||||
streamingMipmapsActive: 0
|
||||
streamingMipmapsAddAllCameras: 1
|
||||
streamingMipmapsMemoryBudget: 512
|
||||
@ -40,8 +44,18 @@ QualitySettings:
|
||||
asyncUploadBufferSize: 16
|
||||
asyncUploadPersistentBuffer: 1
|
||||
resolutionScalingFixedDPIFactor: 1
|
||||
customRenderPipeline: {fileID: 0}
|
||||
terrainQualityOverrides: 0
|
||||
terrainPixelError: 1
|
||||
terrainDetailDensityScale: 1
|
||||
terrainBasemapDistance: 1000
|
||||
terrainDetailDistance: 80
|
||||
terrainTreeDistance: 5000
|
||||
terrainBillboardStart: 50
|
||||
terrainFadeLength: 5
|
||||
terrainMaxTrees: 50
|
||||
excludedTargetPlatforms: []
|
||||
- serializedVersion: 2
|
||||
- serializedVersion: 3
|
||||
name: Low
|
||||
pixelLightCount: 0
|
||||
shadows: 0
|
||||
@ -53,17 +67,21 @@ QualitySettings:
|
||||
shadowCascade2Split: 0.33333334
|
||||
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
|
||||
shadowmaskMode: 0
|
||||
blendWeights: 2
|
||||
textureQuality: 0
|
||||
skinWeights: 2
|
||||
globalTextureMipmapLimit: 0
|
||||
textureMipmapLimitSettings: []
|
||||
anisotropicTextures: 0
|
||||
antiAliasing: 0
|
||||
softParticles: 0
|
||||
softVegetation: 0
|
||||
realtimeReflectionProbes: 0
|
||||
billboardsFaceCameraPosition: 0
|
||||
useLegacyDetailDistribution: 1
|
||||
vSyncCount: 0
|
||||
realtimeGICPUUsage: 25
|
||||
lodBias: 0.4
|
||||
maximumLODLevel: 0
|
||||
enableLODCrossFade: 1
|
||||
streamingMipmapsActive: 0
|
||||
streamingMipmapsAddAllCameras: 1
|
||||
streamingMipmapsMemoryBudget: 512
|
||||
@ -75,8 +93,18 @@ QualitySettings:
|
||||
asyncUploadBufferSize: 16
|
||||
asyncUploadPersistentBuffer: 1
|
||||
resolutionScalingFixedDPIFactor: 1
|
||||
customRenderPipeline: {fileID: 0}
|
||||
terrainQualityOverrides: 0
|
||||
terrainPixelError: 1
|
||||
terrainDetailDensityScale: 1
|
||||
terrainBasemapDistance: 1000
|
||||
terrainDetailDistance: 80
|
||||
terrainTreeDistance: 5000
|
||||
terrainBillboardStart: 50
|
||||
terrainFadeLength: 5
|
||||
terrainMaxTrees: 50
|
||||
excludedTargetPlatforms: []
|
||||
- serializedVersion: 2
|
||||
- serializedVersion: 3
|
||||
name: Medium
|
||||
pixelLightCount: 1
|
||||
shadows: 1
|
||||
@ -88,17 +116,21 @@ QualitySettings:
|
||||
shadowCascade2Split: 0.33333334
|
||||
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
|
||||
shadowmaskMode: 0
|
||||
blendWeights: 2
|
||||
textureQuality: 0
|
||||
skinWeights: 2
|
||||
globalTextureMipmapLimit: 0
|
||||
textureMipmapLimitSettings: []
|
||||
anisotropicTextures: 1
|
||||
antiAliasing: 0
|
||||
softParticles: 0
|
||||
softVegetation: 0
|
||||
realtimeReflectionProbes: 0
|
||||
billboardsFaceCameraPosition: 0
|
||||
useLegacyDetailDistribution: 1
|
||||
vSyncCount: 1
|
||||
realtimeGICPUUsage: 25
|
||||
lodBias: 0.7
|
||||
maximumLODLevel: 0
|
||||
enableLODCrossFade: 1
|
||||
streamingMipmapsActive: 0
|
||||
streamingMipmapsAddAllCameras: 1
|
||||
streamingMipmapsMemoryBudget: 512
|
||||
@ -110,8 +142,18 @@ QualitySettings:
|
||||
asyncUploadBufferSize: 16
|
||||
asyncUploadPersistentBuffer: 1
|
||||
resolutionScalingFixedDPIFactor: 1
|
||||
customRenderPipeline: {fileID: 0}
|
||||
terrainQualityOverrides: 0
|
||||
terrainPixelError: 1
|
||||
terrainDetailDensityScale: 1
|
||||
terrainBasemapDistance: 1000
|
||||
terrainDetailDistance: 80
|
||||
terrainTreeDistance: 5000
|
||||
terrainBillboardStart: 50
|
||||
terrainFadeLength: 5
|
||||
terrainMaxTrees: 50
|
||||
excludedTargetPlatforms: []
|
||||
- serializedVersion: 2
|
||||
- serializedVersion: 3
|
||||
name: High
|
||||
pixelLightCount: 2
|
||||
shadows: 2
|
||||
@ -123,17 +165,21 @@ QualitySettings:
|
||||
shadowCascade2Split: 0.33333334
|
||||
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
|
||||
shadowmaskMode: 1
|
||||
blendWeights: 2
|
||||
textureQuality: 0
|
||||
skinWeights: 2
|
||||
globalTextureMipmapLimit: 0
|
||||
textureMipmapLimitSettings: []
|
||||
anisotropicTextures: 1
|
||||
antiAliasing: 0
|
||||
softParticles: 0
|
||||
softVegetation: 1
|
||||
realtimeReflectionProbes: 1
|
||||
billboardsFaceCameraPosition: 1
|
||||
useLegacyDetailDistribution: 1
|
||||
vSyncCount: 1
|
||||
realtimeGICPUUsage: 50
|
||||
lodBias: 1
|
||||
maximumLODLevel: 0
|
||||
enableLODCrossFade: 1
|
||||
streamingMipmapsActive: 0
|
||||
streamingMipmapsAddAllCameras: 1
|
||||
streamingMipmapsMemoryBudget: 512
|
||||
@ -145,8 +191,18 @@ QualitySettings:
|
||||
asyncUploadBufferSize: 16
|
||||
asyncUploadPersistentBuffer: 1
|
||||
resolutionScalingFixedDPIFactor: 1
|
||||
customRenderPipeline: {fileID: 0}
|
||||
terrainQualityOverrides: 0
|
||||
terrainPixelError: 1
|
||||
terrainDetailDensityScale: 1
|
||||
terrainBasemapDistance: 1000
|
||||
terrainDetailDistance: 80
|
||||
terrainTreeDistance: 5000
|
||||
terrainBillboardStart: 50
|
||||
terrainFadeLength: 5
|
||||
terrainMaxTrees: 50
|
||||
excludedTargetPlatforms: []
|
||||
- serializedVersion: 2
|
||||
- serializedVersion: 3
|
||||
name: Very High
|
||||
pixelLightCount: 3
|
||||
shadows: 2
|
||||
@ -158,17 +214,21 @@ QualitySettings:
|
||||
shadowCascade2Split: 0.33333334
|
||||
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
|
||||
shadowmaskMode: 1
|
||||
blendWeights: 4
|
||||
textureQuality: 0
|
||||
skinWeights: 4
|
||||
globalTextureMipmapLimit: 0
|
||||
textureMipmapLimitSettings: []
|
||||
anisotropicTextures: 2
|
||||
antiAliasing: 2
|
||||
softParticles: 1
|
||||
softVegetation: 1
|
||||
realtimeReflectionProbes: 1
|
||||
billboardsFaceCameraPosition: 1
|
||||
useLegacyDetailDistribution: 1
|
||||
vSyncCount: 1
|
||||
realtimeGICPUUsage: 50
|
||||
lodBias: 1.5
|
||||
maximumLODLevel: 0
|
||||
enableLODCrossFade: 1
|
||||
streamingMipmapsActive: 0
|
||||
streamingMipmapsAddAllCameras: 1
|
||||
streamingMipmapsMemoryBudget: 512
|
||||
@ -180,8 +240,18 @@ QualitySettings:
|
||||
asyncUploadBufferSize: 16
|
||||
asyncUploadPersistentBuffer: 1
|
||||
resolutionScalingFixedDPIFactor: 1
|
||||
customRenderPipeline: {fileID: 0}
|
||||
terrainQualityOverrides: 0
|
||||
terrainPixelError: 1
|
||||
terrainDetailDensityScale: 1
|
||||
terrainBasemapDistance: 1000
|
||||
terrainDetailDistance: 80
|
||||
terrainTreeDistance: 5000
|
||||
terrainBillboardStart: 50
|
||||
terrainFadeLength: 5
|
||||
terrainMaxTrees: 50
|
||||
excludedTargetPlatforms: []
|
||||
- serializedVersion: 2
|
||||
- serializedVersion: 3
|
||||
name: Ultra
|
||||
pixelLightCount: 4
|
||||
shadows: 2
|
||||
@ -193,17 +263,21 @@ QualitySettings:
|
||||
shadowCascade2Split: 0.33333334
|
||||
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
|
||||
shadowmaskMode: 1
|
||||
blendWeights: 4
|
||||
textureQuality: 0
|
||||
skinWeights: 4
|
||||
globalTextureMipmapLimit: 0
|
||||
textureMipmapLimitSettings: []
|
||||
anisotropicTextures: 2
|
||||
antiAliasing: 2
|
||||
softParticles: 1
|
||||
softVegetation: 1
|
||||
realtimeReflectionProbes: 1
|
||||
billboardsFaceCameraPosition: 1
|
||||
useLegacyDetailDistribution: 1
|
||||
vSyncCount: 1
|
||||
realtimeGICPUUsage: 100
|
||||
lodBias: 2
|
||||
maximumLODLevel: 0
|
||||
enableLODCrossFade: 1
|
||||
streamingMipmapsActive: 0
|
||||
streamingMipmapsAddAllCameras: 1
|
||||
streamingMipmapsMemoryBudget: 512
|
||||
@ -215,7 +289,18 @@ QualitySettings:
|
||||
asyncUploadBufferSize: 16
|
||||
asyncUploadPersistentBuffer: 1
|
||||
resolutionScalingFixedDPIFactor: 1
|
||||
customRenderPipeline: {fileID: 0}
|
||||
terrainQualityOverrides: 0
|
||||
terrainPixelError: 1
|
||||
terrainDetailDensityScale: 1
|
||||
terrainBasemapDistance: 1000
|
||||
terrainDetailDistance: 80
|
||||
terrainTreeDistance: 5000
|
||||
terrainBillboardStart: 50
|
||||
terrainFadeLength: 5
|
||||
terrainMaxTrees: 50
|
||||
excludedTargetPlatforms: []
|
||||
m_TextureMipmapLimitGroupNames: []
|
||||
m_PerPlatformDefaultQuality:
|
||||
Android: 2
|
||||
Lumin: 5
|
||||
@ -223,6 +308,7 @@ QualitySettings:
|
||||
Nintendo Switch: 5
|
||||
PS4: 5
|
||||
PSP2: 2
|
||||
Server: 0
|
||||
Stadia: 5
|
||||
Standalone: 5
|
||||
WebGL: 3
|
||||
|
Loading…
Reference in New Issue
Block a user