首次提交

This commit is contained in:
Bob.Song
2026-03-05 18:07:55 +08:00
commit e125bb869e
4534 changed files with 563920 additions and 0 deletions

Binary file not shown.

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 5bc65026e2b5e458b838d06e4ef39409
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,14 @@
{
"name": "VInspector",
"rootNamespace": "",
"references": [],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: de13f8b1675b449e6a6af1cc0f7842ec
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cb0378825d0df482cb66e646e57e5153
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,104 @@
Shader "Hidden/VInspectorAssetPreview"
{
Properties
{
_MainTex ("Texture", Any) = "white" {}
[HDR] _Color ("Tint", Color) = (1,1,1,1)
}
CGINCLUDE
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata_t
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 texcoord : TEXCOORD0;
float2 clipUV : TEXCOORD1;
};
sampler2D _MainTex;
sampler2D _GUIClipTexture;
bool _ManualTex2SRGB;
float4 _MainTex_ST;
float4 _Color;
float4x4 unity_GUIClipTextureMatrix;
v2f vert (appdata_t v)
{
v2f o;
UNITY_SETUP_INSTANCE_ID(v);
o.vertex = UnityObjectToClipPos(v.vertex);
float3 eyePos = UnityObjectToViewPos(v.vertex);
o.clipUV = mul(unity_GUIClipTextureMatrix, float4(eyePos.xy, 0, 1.0));
o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
float4 c = tex2D(_MainTex, i.texcoord);
#ifndef UNITY_COLORSPACE_GAMMA
c.rgb = LinearToGammaSpace(c.rgb);
#endif
#ifndef UNITY_COLORSPACE_GAMMA
float backgroundGreyscale = 0.32178620999; // linear
#else
float backgroundGreyscale = 0.32156862319; // gamma
#endif
if(c.r == c.g && c.r == c.b && c.a == 1)
if(c.r == backgroundGreyscale)
c = float4(backgroundGreyscale, backgroundGreyscale, backgroundGreyscale, 0);
c *= _Color;
c.a *= tex2D(_GUIClipTexture, i.clipUV).a;
return c;
}
ENDCG
SubShader
{
Blend SrcAlpha OneMinusSrcAlpha, One One
Cull Off
ZWrite Off
ZTest Always
Pass
{
CGPROGRAM
ENDCG
}
}
SubShader
{
Blend SrcAlpha OneMinusSrcAlpha
Cull Off
ZWrite Off
ZTest Always
Pass
{
CGPROGRAM
ENDCG
}
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 913b985f9895c47cbb23d4dabc002788
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,128 @@
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System;
using UnityEngine;
#if UNITY_EDITOR
using static VInspector.Libs.VUtils;
#endif
namespace VInspector
{
public class FoldoutAttribute : Attribute
{
public string name;
public FoldoutAttribute(string name) => this.name = name;
}
public class EndFoldoutAttribute : Attribute { }
public class TabAttribute : Attribute
{
public string name;
public TabAttribute(string name) => this.name = name;
}
public class EndTabAttribute : Attribute { }
public class ButtonAttribute : Attribute
{
public string name = "";
public int size = 30;
public int space = 0;
public string color = "Grey";
public ButtonAttribute() => this.name = "";
public ButtonAttribute(string name) => this.name = name;
}
public class VariantsAttribute : PropertyAttribute
{
public object[] variants;
public VariantsAttribute(params object[] variants) => this.variants = variants;
}
public abstract class IfAttribute : Attribute
{
public string variableName;
public object variableValue;
#if UNITY_EDITOR
public bool Evaluate(object target)
{
if (target.GetType().GetFieldInfo(variableName) == null &&
target.GetType().GetPropertyInfo(variableName) == null)
return false;
var curValue = target.GetMemberValue(variableName);
return object.Equals(curValue, variableValue);
}
#endif
public IfAttribute(string boolName) { this.variableName = boolName; this.variableValue = true; }
public IfAttribute(string variableName, object variableValue) { this.variableName = variableName; this.variableValue = variableValue; }
}
public class EndIfAttribute : Attribute { }
public class HideIfAttribute : IfAttribute
{
public HideIfAttribute(string boolName) : base(boolName) { }
public HideIfAttribute(string variableName, object variableValue) : base(variableName, variableValue) { }
}
public class ShowIfAttribute : IfAttribute
{
public ShowIfAttribute(string boolName) : base(boolName) { }
public ShowIfAttribute(string variableName, object variableValue) : base(variableName, variableValue) { }
}
public class EnableIfAttribute : IfAttribute
{
public EnableIfAttribute(string boolName) : base(boolName) { }
public EnableIfAttribute(string variableName, object variableValue) : base(variableName, variableValue) { }
}
public class DisableIfAttribute : IfAttribute
{
public DisableIfAttribute(string boolName) : base(boolName) { }
public DisableIfAttribute(string variableName, object variableValue) : base(variableName, variableValue) { }
}
public class ReadOnlyAttribute : Attribute { }
public class ShowInInspectorAttribute : Attribute { }
[AttributeUsage(AttributeTargets.Method)]
public class OnValueChangedAttribute : Attribute
{
public string[] variableNames;
public OnValueChangedAttribute(string variableName) => this.variableNames = new[] { variableName };
public OnValueChangedAttribute(params string[] variableNames) => this.variableNames = variableNames;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c8d83838ee14b4445a0abac264bf08d8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9ee37a1072bf4467d923d9ef51a0e63d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,206 @@
#if UNITY_EDITOR
using UnityEngine;
using UnityEngine.UIElements;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.ShortcutManagement;
using System.Reflection;
using System.Linq;
using System.Text.RegularExpressions;
using Type = System.Type;
using static VInspector.Libs.VUtils;
using static VInspector.Libs.VGUI;
namespace VInspector
{
public class VInspectorComponentClipboard : ScriptableSingleton<VInspectorComponentClipboard>
{
public static void CopyComponent(Component component)
{
instance.RecordUndo();
if (instance.copiedComponetDatas.FirstOrDefault(r => r.sourceComponent == component) is ComponentData alreadyCopiedData)
{
instance.discardedComponentDatas.Add(alreadyCopiedData);
instance.copiedComponetDatas.Remove(alreadyCopiedData);
}
else
instance.copiedComponetDatas.Add(GetComponentData(component));
instance.Dirty();
}
public static void PasteComponentValues(ComponentData data, Component component)
{
component.RecordUndo();
ApplyComponentData(data, component);
component.Dirty();
instance.RecordUndo();
instance.copiedComponetDatas.Remove(data);
instance.discardedComponentDatas.Add(data);
instance.Dirty();
}
public static void PasteComponentAsNew(ComponentData data, GameObject gameObject)
{
var addedComponent = Undo.AddComponent(gameObject, data.sourceComponent.GetType());
ApplyComponentData(data, addedComponent);
}
public static void ClearCopiedDatas()
{
instance.RecordUndo();
instance.discardedComponentDatas.AddRange(instance.copiedComponetDatas);
instance.copiedComponetDatas.Clear();
instance.Dirty();
}
public static bool CanComponentsBePastedTo(IEnumerable<GameObject> targetGos)
{
if (!targetGos.Any()) return false;
foreach (var copiedData in instance.copiedComponetDatas)
if (nonDuplicableComponentTypes.Contains(copiedData.sourceComponent.GetType()))
if (targetGos.Any(r => r.TryGetComponent(copiedData.sourceComponent.GetType(), out _)))
return false;
return true;
}
static Type[] nonDuplicableComponentTypes = new[]
{
typeof(Transform),
typeof(RectTransform),
typeof(MeshFilter),
typeof(MeshRenderer),
typeof(SkinnedMeshRenderer),
typeof(Camera),
typeof(AudioListener),
typeof(Rigidbody),
typeof(Rigidbody2D),
typeof(Light),
typeof(Canvas),
typeof(Animation),
typeof(Animator),
typeof(AudioSource),
typeof(ParticleSystem),
typeof(TrailRenderer),
typeof(LineRenderer),
typeof(LensFlare),
typeof(Projector),
typeof(AudioReverbZone),
typeof(AudioEchoFilter),
typeof(Terrain),
typeof(TerrainCollider),
};
[SerializeReference] public List<ComponentData> copiedComponetDatas = new();
[SerializeReference] public List<ComponentData> discardedComponentDatas = new(); // removed datas get stashed here so they can be restored on undo/redo
public static void SaveComponent(Component component)
{
instance.RecordUndo();
if (instance.savedComponentDatas.FirstOrDefault(r => r.sourceComponent == component) is ComponentData alreadySavedData)
{
instance.discardedComponentDatas.Add(alreadySavedData);
instance.savedComponentDatas.Remove(alreadySavedData);
}
else
instance.savedComponentDatas.Add(GetComponentData(component));
instance.Dirty();
}
public static void OnPlaymodeStateChanged(PlayModeStateChange state)
{
if (state != PlayModeStateChange.EnteredEditMode) return;
foreach (var data in instance.savedComponentDatas)
if (EditorUtility.InstanceIDToObject(data.sourceComponent.GetInstanceID()) is Component sourceComponent)
ApplyComponentData(data, sourceComponent);
instance.savedComponentDatas.Clear();
}
[SerializeReference] public List<ComponentData> savedComponentDatas = new();
public static ComponentData GetComponentData(Component component)
{
var data = new ComponentData();
data.sourceComponent = component;
var property = new SerializedObject(component).GetIterator();
if (!property.Next(true)) return data;
do data.serializedPropertyValues_byPath[property.propertyPath] = property.GetBoxedValue();
while (property.NextVisible(true));
return data;
}
public static void ApplyComponentData(ComponentData componentData, Component targetComponent)
{
foreach (var kvp in componentData.serializedPropertyValues_byPath)
{
var so = new SerializedObject(targetComponent);
var property = so.FindProperty(kvp.Key);
so.Update();
property.SetBoxedValue(kvp.Value);
so.ApplyModifiedProperties();
targetComponent.Dirty();
}
}
[System.Serializable]
public class ComponentData { public Component sourceComponent; public Dictionary<string, object> serializedPropertyValues_byPath = new(); }
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b4a601d21911941c9b6aa75950470764
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,573 @@
#if UNITY_EDITOR
using System.Collections;
using System.Linq;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
using UnityEditor.UIElements;
using System.Reflection;
using UnityEditor;
using static VInspector.Libs.VUtils;
using static VInspector.Libs.VGUI;
namespace VInspector
{
public class VInspectorComponentHeader
{
void OnGUI()
{
void masks()
{
Color backgroundColor;
float buttonMask_xMin;
float buttonMask_xMax;
void set_backgroundColor()
{
var hovered = EditorGUIUtility.isProSkin ? Greyscale(.28f) : Greyscale(.84f);
var normal = EditorGUIUtility.isProSkin ? Greyscale(.244f) : Greyscale(.8f);
backgroundColor = normal;
if (headerRect.IsHovered() && !mousePressedOnBackground && EditorWindow.mouseOverWindow == window)
backgroundColor = hovered;
}
void set_buttonMaskSize()
{
var defaultButtonCount = VInspectorMenu.componentButtons_defaultButtonsCount;
var customButtonCount = 0;
if (VInspectorMenu.copyPasteButtonsEnabled)
customButtonCount++;
if (VInspectorMenu.saveInPlaymodeButtonEnabled && Application.isPlaying)
customButtonCount++;
if (VInspectorMenu.minimalModeEnabled && !headerRect.IsHovered())
defaultButtonCount = customButtonCount = 0;
buttonMask_xMax = headerRect.xMax - buttonsOffsetRight - defaultButtonCount * buttonSize;
buttonMask_xMin = headerRect.xMax - buttonsOffsetRight - (defaultButtonCount + customButtonCount).Max(3) * buttonSize;
}
void hideArrow()
{
if (headerRect.IsHovered()) return;
if (!VInspectorMenu.minimalModeEnabled) return;
// headerRect.SetWidth(17).MoveX(3).AddHeightFromMid(-2).Draw(backgroundColor);
headerRect.SetWidth(17).MoveX(-2).AddHeightFromMid(-2).AddWidthFromRight(-4).Draw(backgroundColor);
}
void hideDefaultButtons_()
{
var rect = headerRect.AddHeightFromMid(-2).SetX(buttonMask_xMin).SetXMax(buttonMask_xMax);
rect.Draw(backgroundColor);
}
void hideScriptText()
{
if (component is not MonoBehaviour) return;
if (!VInspectorMenu.minimalModeEnabled) return;
var name = component.GetType().Name.Decamelcase();
var rect = headerRect.AddHeightFromMid(-2).SetWidth(60).MoveX(name.GetLabelWidth(fontSize: 12, isBold: true) + 60 - 3);
rect.xMax = rect.xMax.Min(buttonMask_xMin).Max(rect.xMin);
rect.Draw(backgroundColor);
}
void tintScriptIcon()
{
if (component is not MonoBehaviour) return;
if (!mousePressedOnScriptIcon) return;
var iconRect = headerRect.MoveX(18).SetWidth(22);
iconRect.Draw(backgroundColor.SetAlpha(EditorGUIUtility.isProSkin ? .3f : .45f));
}
void nameCurtain()
{
var rect = headerRect.AddHeightFromMid(-2).SetXMax(buttonMask_xMin + 2).SetWidthFromRight(18);
rect.DrawCurtainLeft(backgroundColor);
}
set_backgroundColor();
set_buttonMaskSize();
hideArrow();
hideDefaultButtons_();
hideScriptText();
tintScriptIcon();
nameCurtain();
}
void scriptIconClicks()
{
if (component is not MonoBehaviour) return;
if (curEvent.mouseButton != 0) return;
if (!VInspectorMenu.hideScriptFieldEnabled) return;
var iconRect = headerRect.MoveX(18).SetWidth(22);
void mosueDown()
{
if (!curEvent.isMouseDown) return;
if (!iconRect.IsHovered()) return;
mousePressedOnScriptIcon = true;
mousePressedOnScriptIcon_initPos = curEvent.mousePosition;
var script = MonoScript.FromMonoBehaviour(component as MonoBehaviour);
// if (curEvent.holdingAlt)
if (curEvent.clickCount == 2)
AssetDatabase.OpenAsset(script);
curEvent.Use();
}
void mouseUp()
{
if (!curEvent.isMouseUp) return;
if (!mousePressedOnScriptIcon) return;
var script = MonoScript.FromMonoBehaviour(component as MonoBehaviour);
if (curEvent.clickCount == 1)
PingObject(script);
mousePressedOnScriptIcon = false;
window.Repaint();
curEvent.Use();
}
void startDrag()
{
if (!curEvent.isMouseDrag) return;
if (!mousePressedOnScriptIcon) return;
if ((mousePressedOnScriptIcon_initPos - curEvent.mousePosition).magnitude < 2) return;
DragAndDrop.PrepareStartDrag();
DragAndDrop.objectReferences = new[] { component };
DragAndDrop.StartDrag(component.ToString());
mousePressedOnScriptIcon = false;
mousePressedOnBackground = false;
}
mosueDown();
mouseUp();
startDrag();
}
void copyPasteButton()
{
if (VInspectorMenu.minimalModeEnabled && !headerRect.IsHovered()) return;
if (!VInspectorMenu.copyPasteButtonsEnabled) return;
var copiedData = VInspectorComponentClipboard.instance.copiedComponetDatas.FirstOrDefault(r => r.sourceComponent == component);
var pastableData = VInspectorComponentClipboard.instance.copiedComponetDatas.FirstOrDefault(r => r.sourceComponent.GetType() == component.GetType());
var isCopied = copiedData != null;
var canValuesBePasted = !isCopied && pastableData != null;
var buttonRect = headerRect.SetWidthFromRight(buttonSize).MoveX(-buttonsOffsetRight - VInspectorMenu.componentButtons_defaultButtonsCount * buttonSize);
var iconName = canValuesBePasted ? "Paste values" : isCopied ? "Copied" : "Copy";
var iconSize = 16;
var color = Greyscale(isDarkTheme ? .78f : .49f);
var colorHovered = Greyscale(isDarkTheme ? 1f : .2f);
var colorPressed = Greyscale(isDarkTheme ? .8f : .6f);
var colorDisabled = Greyscale(.52f);
deferredTooltips_byRect[buttonRect] = canValuesBePasted ? "Paste values" : isCopied ? "Copied" : "Copy component";
var disabled = editingMultiselection;
if (disabled) { IconButton(buttonRect, iconName, iconSize, colorDisabled, colorDisabled, colorDisabled); return; }
if (!IconButton(buttonRect, iconName, iconSize, color, colorHovered, colorPressed)) return;
if (canValuesBePasted)
VInspectorComponentClipboard.PasteComponentValues(pastableData, component);
else
VInspectorComponentClipboard.CopyComponent(component);
}
void saveInPlaymodeButton()
{
if (VInspectorMenu.minimalModeEnabled && !headerRect.IsHovered()) return;
if (!Application.isPlaying) return;
if (!VInspectorMenu.saveInPlaymodeButtonEnabled) return;
var savedData = VInspectorComponentClipboard.instance.savedComponentDatas.FirstOrDefault(r => r.sourceComponent == component);
var isSaved = savedData != null;
var buttonRect = headerRect.SetWidthFromRight(buttonSize).MoveX(-buttonsOffsetRight - (VInspectorMenu.componentButtons_defaultButtonsCount + (VInspectorMenu.copyPasteButtonsEnabled ? 1 : 0)) * buttonSize);
var iconName = isSaved ? "Saved" : "Save";
var iconSize = 16;
var color = Greyscale(isDarkTheme ? .8f : .46f);
var colorHovered = Greyscale(isDarkTheme ? 1f : .2f);
var colorPressed = Greyscale(isDarkTheme ? .8f : .6f);
deferredTooltips_byRect[buttonRect] = isSaved ? "Saved" : "Save in play mode";
if (!IconButton(buttonRect, iconName, iconSize, color, colorHovered, colorPressed)) return;
if (editingMultiselection)
foreach (var component in multiselectedComponents)
VInspectorComponentClipboard.SaveComponent(component);
else
VInspectorComponentClipboard.SaveComponent(component);
}
void expandWithAnimation()
{
if (!mousePressedOnBackground) return;
if (!curEvent.isMouseUp) return;
if (curEvent.mouseButton != 0) return;
if (headerRect.SetWidth(16).MoveX(40).IsHovered()) return; // enabled toggle
if (headerRect.SetWidthFromRight(64).IsHovered()) return; // right buttons
if (curEvent.holdingShift)
VInspector.CollapseOtherComponents(component, window);
else if (VInspectorMenu.componentAnimationsEnabled)
VInspector.ToggleComponentExpanded(component, window);
else return;
mousePressedOnBackground = false;
curEvent.Use();
EditorGUIUtility.hotControl = 0;
}
void createComponentWindow()
{
if (!mousePressedOnBackground) return;
if (!curEvent.isMouseDrag) return;
if (!curEvent.holdingAlt) return;
if (curEvent.mousePosition.DistanceTo(mousePressedOnBackground_initPos) < 2) return;
if (!VInspectorMenu.componentWindowsEnabled) return;
if (VInspectorComponentWindow.draggedInstance != null) return;
var position = EditorGUIUtility.GUIToScreenPoint(headerRect.position + (curEvent.mousePosition - mousePressedOnBackground_initPos));
VInspectorComponentWindow.CreateDraggedInstance(component, position, headerRect.width);
EditorGUIUtility.hotControl = 0;
mousePressedOnBackground = false;
}
void set_mousePressedOnBackground()
{
if (curEvent.isMouseDown)
{
mousePressedOnBackground = true;
mousePressedOnBackground_initPos = curEvent.mousePosition;
}
if (curEvent.isMouseUp || curEvent.isDragUpdate)
mousePressedOnBackground = false;
if (!imguiContainer.contentRect.IsHovered())
mousePressedOnBackground = false;
}
void set_hoveredComponentHeader()
{
if (!curEvent.isRepaint) return;
if (component is Transform)
VInspector.hoveredComponentHeader = null;
if (headerRect.IsHovered())
VInspector.hoveredComponentHeader = this;
}
void deferredTooltips()
{
foreach (var kvp in deferredTooltips_byRect)
GUI.Label(kvp.Key, new GUIContent("", kvp.Value));
deferredTooltips_byRect.Clear();
// tooltips should be drawn before defaultHeaderGUI to take precedence over default tooltips
// so in button functions we schedule them to be drawn first thing next repaint
// and here we do the drawing
}
void defaultHeaderGUI()
{
void initOffsets()
{
if (!VInspectorMenu.minimalModeEnabled) return;
if (headerContentStyle != null) return;
headerContentStyle = typeof(EditorStyles).GetMemberValue<GUIStyle>("inspectorTitlebar");
headerFoldoutStyle = typeof(EditorStyles).GetMemberValue<GUIStyle>("titlebarFoldout");
headerContentStyle_defaultLeftPadding = headerContentStyle.padding.left;
headerFoldoutStyle_defaultLeftMargin = headerFoldoutStyle.margin.left;
}
void setAdjustedOffsets()
{
if (!VInspectorMenu.minimalModeEnabled) return;
headerContentStyle.padding.left = headerContentStyle_defaultLeftPadding - 2;
headerFoldoutStyle.margin.left = headerFoldoutStyle_defaultLeftMargin - 1;
}
void setDefaultOffsets()
{
if (!VInspectorMenu.minimalModeEnabled) return;
headerContentStyle.padding.left = headerContentStyle_defaultLeftPadding;
headerFoldoutStyle.margin.left = headerFoldoutStyle_defaultLeftMargin;
}
initOffsets();
setAdjustedOffsets();
defaultHeaderGUIAction.Invoke();
setDefaultOffsets();
}
void preventKeyboardFocus()
{
if (!curEvent.isUsed) return;
if (!headerRect.IsHovered()) return;
GUIUtility.keyboardControl = 0;
// removes that annoying blue highlight after clicking on header
}
if (curEvent.isRepaint)
{
deferredTooltips();
defaultHeaderGUI();
}
masks();
scriptIconClicks();
copyPasteButton();
saveInPlaymodeButton();
createComponentWindow();
expandWithAnimation();
set_mousePressedOnBackground();
set_hoveredComponentHeader();
if (!curEvent.isRepaint)
{
defaultHeaderGUI();
preventKeyboardFocus();
}
}
public float buttonsOffsetRight = 3;
public float buttonSize = 20;
public bool mousePressedOnBackground;
public bool mousePressedOnScriptIcon;
public Vector2 mousePressedOnBackground_initPos;
public Vector2 mousePressedOnScriptIcon_initPos;
public Dictionary<Rect, string> deferredTooltips_byRect = new();
public Rect headerRect
{
get
{
var contentRect = imguiContainer.contentRect;
if (contentRect.height == 42) // with extra lines like "Multi-object editing not supported"
return contentRect.SetHeight(22);
else
return contentRect.SetHeightFromBottom(22); // fixes offset on transform header in 6000
}
}
static GUIStyle headerContentStyle;
static GUIStyle headerFoldoutStyle;
static int headerContentStyle_defaultLeftPadding;
static int headerFoldoutStyle_defaultLeftMargin;
public Vector2 mouseDownPos;
public void Update()
{
if (imguiContainer is VisualElement v && v.panel == null) { imguiContainer.onGUIHandler = defaultHeaderGUIAction; imguiContainer = null; }
if (imguiContainer != null && imguiContainer.onGUIHandler.Method.DeclaringType == typeof(VInspectorComponentHeader)) return;
if (typeof(ScriptableObject).IsAssignableFrom(component.GetType())) return;
if (editor.GetPropertyValue("propertyViewer") is not EditorWindow window) return;
this.window = window;
void fixWrongWindow_2022_3_26()
{
if (Application.unityVersion != "2022.3.26f1") return;
if (!window.hasFocus)
window = window.GetMemberValue("m_Parent")?.GetMemberValue<List<EditorWindow>>("m_Panes")?.FirstOrDefault(r => r.hasFocus) ?? window;
// in 2022.3.26 wrong inspector may be returned by propertyViewer when there are multiple inspectors
// also the same instance of an editor may be used on all inspectors
// here we fix it for cases when multiple inspectors are in the same dock area
}
void findHeader(VisualElement element)
{
if (element == null) return;
if (element.GetType().Name == "EditorElement")
{
IMGUIContainer curHeaderImguiContainer = null;
foreach (var child in element.Children())
{
curHeaderImguiContainer ??= new[] { child as IMGUIContainer }.FirstOrDefault(r => r != null && r.name.EndsWith("Header"));
if (curHeaderImguiContainer is null) continue;
if (child is not InspectorElement) continue;
if (child.GetFieldValue("m_Editor") is not Editor editor) continue;
if (editor.target != component) continue;
imguiContainer = curHeaderImguiContainer;
if (editingMultiselection = editor.targets.Count() > 1)
multiselectedComponents = editor.targets.Cast<Component>().ToList();
return;
}
}
foreach (var r in element.Children())
if (imguiContainer == null)
findHeader(r);
}
void setupGUICallbacks()
{
if (imguiContainer == null) return;
defaultHeaderGUIAction = imguiContainer.onGUIHandler;
imguiContainer.onGUIHandler = OnGUI;
}
fixWrongWindow_2022_3_26();
findHeader(window.rootVisualElement);
setupGUICallbacks();
}
public bool editingMultiselection;
public List<Component> multiselectedComponents;
IMGUIContainer imguiContainer;
System.Action defaultHeaderGUIAction;
EditorWindow window;
public VInspectorComponentHeader(Component component, Editor editor) { this.component = component; this.editor = editor; }
public Editor editor;
public Component component;
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 69daed4ccfde7447ba633e320119de35
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,390 @@
#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 VInspector.Libs.VUtils;
using static VInspector.Libs.VGUI;
namespace VInspector
{
public class VInspectorComponentWindow : EditorWindow
{
void OnGUI()
{
if (!component || !editor) { Close(); return; } // todo script components break on playmode
void background()
{
position.SetPos(0, 0).Draw(GUIColors.windowBackground);
}
void outline()
{
if (Application.platform == RuntimePlatform.OSXEditor) return;
position.SetPos(0, 0).DrawOutline(Greyscale(.1f));
}
void header()
{
var headerRect = ExpandWidthLabelRect(18).Resize(-1).AddWidthFromMid(6);
var closeButtonRect = headerRect.SetWidthFromRight(16).SetHeightFromMid(16).Move(-4, 0);
var backgroundColor = isDarkTheme ? Greyscale(.25f) : GUIColors.windowBackground;
void startDragging()
{
if (isResizing) return;
if (isDragged) return;
if (!curEvent.isMouseDrag) return;
if (!headerRect.IsHovered()) return;
draggedInstance = this;
dragStartMousePos = EditorGUIUtility.GUIToScreenPoint(curEvent.mousePosition);
dragStartWindowPos = position.position;
}
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.isMouseMove && !curEvent.isMouseUp) return;
draggedInstance = null;
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);
if (!componentIcons_byType.ContainsKey(component.GetType()))
componentIcons_byType[component.GetType()] = EditorGUIUtility.ObjectContent(component, component.GetType()).image;
GUI.Label(iconRect, componentIcons_byType[component.GetType()]);
}
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 (instances.Any(r => r.component.GetType() == component.GetType() && r.component != component))
s += " - " + component.gameObject.name;
SetLabelBold();
GUI.Label(nameRect, s);
ResetLabelStyle();
}
void nameCurtain()
{
var flatColorRect = headerRect.SetX(closeButtonRect.x + 3).SetXMax(headerRect.xMax);
var gradientRect = headerRect.SetXMax(flatColorRect.x).SetWidthFromRight(30);
flatColorRect.Draw(backgroundColor);
gradientRect.DrawCurtainLeft(backgroundColor);
}
void closeButton()
{
var iconName = "CrossIcon";
var iconSize = 14;
var color = isDarkTheme ? Greyscale(.65f) : Greyscale(.35f);
var colorHovered = isDarkTheme ? Greyscale(.9f) : color;
var colorPressed = color;
if (!IconButton(closeButtonRect, iconName, iconSize, color, colorHovered, colorPressed)) return;
Close();
EditorGUIUtility.ExitGUI();
}
void escHint()
{
if (!closeButtonRect.IsHovered()) return;
if (EditorWindow.focusedWindow != this) return;
var textRect = headerRect.SetWidthFromRight(42).MoveY(-.5f);
var fontSize = 11;
var color = Greyscale(.65f);
SetLabelFontSize(fontSize);
SetGUIColor(color);
GUI.Label(textRect, "Esc");
ResetGUIColor();
ResetLabelStyle();
}
startDragging();
updateDragging();
stopDragging();
background();
icon();
toggle();
name();
nameCurtain();
closeButton();
escHint();
}
void body()
{
EditorGUIUtility.labelWidth = (this.position.width * .4f).Max(120);
BeginIndent(17);
editor?.OnInspectorGUI();
EndIndent(1);
EditorGUIUtility.labelWidth = 0;
}
void updateHeight()
{
var r = ExpandWidthLabelRect();
if (curEvent.isRepaint)
position = position.SetHeight(lastRect.y);
}
void closeOnEscape()
{
if (!curEvent.isKeyDown) return;
if (curEvent.keyCode != KeyCode.Escape) return;
Close();
EditorGUIUtility.ExitGUI();
}
void horizontalResize()
{
var resizeArea = this.position.SetPos(0, 0).SetWidthFromRight(5).AddHeightFromBottom(-20);
void startResize()
{
if (isDragged) return;
if (isResizing) return;
if (!curEvent.isMouseDown && !curEvent.isMouseDrag) return;
if (!resizeArea.IsHovered()) return;
isResizing = true;
resizeStartMousePos = EditorGUIUtility.GUIToScreenPoint(curEvent.mousePosition);
resizeStartWindowSize = this.position.size;
}
void updateResize()
{
if (!isResizing) return;
var resizedWidth = resizeStartWindowSize.x + EditorGUIUtility.GUIToScreenPoint(curEvent.mousePosition).x - resizeStartMousePos.x;
var width = resizedWidth.Max(minWidth);
if (!curEvent.isRepaint)
position = position.SetWidth(width);
EditorGUIUtility.hotControl = EditorGUIUtility.GetControlID(FocusType.Passive);
// GUI.focused
}
void stopResize()
{
if (!isResizing) return;
if (!curEvent.isMouseUp) return;
isResizing = false;
EditorGUIUtility.hotControl = 0;
}
EditorGUIUtility.AddCursorRect(resizeArea, MouseCursor.ResizeHorizontal);
startResize();
updateResize();
stopResize();
}
background();
header();
outline();
Space(3);
body();
Space(7);
updateHeight();
closeOnEscape();
horizontalResize();
if (isDragged)
Repaint();
}
public bool isDragged => draggedInstance == this;
public Vector2 dragStartMousePos;
public Vector2 dragStartWindowPos;
public bool isResizing;
public Vector2 resizeStartMousePos;
public Vector2 resizeStartWindowSize;
static Dictionary<System.Type, Texture> componentIcons_byType = new();
public void Init(Component component)
{
if (editor)
editor.DestroyImmediate();
this.component = component;
this.editor = Editor.CreateEditor(component);
if (!instances.Contains(this))
instances.Add(this);
}
void OnDestroy()
{
editor?.DestroyImmediate();
if (instances.Contains(this))
instances.Remove(this);
}
public Component component;
public Editor editor;
public static List<VInspectorComponentWindow> instances = new();
public static void CreateDraggedInstance(Component component, Vector2 windowPosition, float windowWidth)
{
draggedInstance = ScriptableObject.CreateInstance<VInspectorComponentWindow>();
draggedInstance.ShowPopup();
draggedInstance.Init(component);
draggedInstance.Focus();
draggedInstance.wantsMouseMove = true;
draggedInstance.position = Rect.zero.SetPos(windowPosition).SetWidth(windowWidth).SetHeight(200);
draggedInstance.dragStartMousePos = curEvent.mousePosition_screenSpace;
draggedInstance.dragStartWindowPos = windowPosition;
}
public static VInspectorComponentWindow draggedInstance;
public static float minWidth => 300;
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 295e0a9b2039246c59fbe00423b2723e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,185 @@
#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 VInspector.VInspectorState;
using static VInspector.Libs.VUtils;
using static VInspector.Libs.VGUI;
namespace VInspector
{
public class VInspectorData : ScriptableObject, ISerializationCallbackReceiver
{
public List<Item> items = new();
[System.Serializable]
public class Item
{
public GlobalID globalId;
public Type type => Type.GetType(_typeString) ?? typeof(DefaultAsset);
public string _typeString;
public Object obj
{
get
{
if (_obj == null && !isSceneGameObject)
_obj = globalId.GetObject();
return _obj;
// updating scene objects here using globalId.GetObject() could cause performance issues on large scenes
// so instead they are batch updated in VInspector.UpdateBookmarkedObjectsForScene()
}
}
public Object _obj;
public bool isSceneGameObject;
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();
id = Random.value.GetHashCode();
isSceneGameObject = o is GameObject go && go.scene.rootCount != 0;
isAsset = !isSceneGameObject;
_typeString = o.GetType().AssemblyQualifiedName;
_name = o.name;
_obj = o;
}
public float width => VInspectorNavbar.expandedItemWidth;
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 ItemState state
{
get
{
if (!VInspectorState.instance.itemStates_byItemId.ContainsKey(id))
VInspectorState.instance.itemStates_byItemId[id] = new ItemState();
return VInspectorState.instance.itemStates_byItemId[id];
}
}
public int id;
}
public void OnAfterDeserialize() => VInspectorNavbar.repaintNeededAfterUndoRedo = true;
public void OnBeforeSerialize() { }
[CustomEditor(typeof(VInspectorData))]
class Editor : UnityEditor.Editor
{
public override void OnInspectorGUI()
{
var style = EditorStyles.label;
style.wordWrap = true;
SetGUIEnabled(false);
BeginIndent(0);
Space(10);
EditorGUILayout.LabelField("This file stores bookmarks from vInspector's navigation bar", style);
EndIndent(10);
ResetGUIEnabled();
// Space(15);
// base.OnInspectorGUI();
}
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b7915df4cd4da490ab52fc8fa9ee9127
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,318 @@
#if UNITY_EDITOR
using System.Collections;
using System.Linq;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
using UnityEditor.UIElements;
using System.Reflection;
using UnityEditor;
using UnityEditorInternal;
using Type = System.Type;
using Attribute = System.Attribute;
using static VInspector.VInspectorState;
using static VInspector.Libs.VUtils;
using static VInspector.Libs.VGUI;
namespace VInspector
{
[CustomPropertyDrawer(typeof(SerializedDictionary<,>), true)]
public class SerializedDictionaryDrawer : PropertyDrawer
{
public override void OnGUI(Rect rect, SerializedProperty prop, GUIContent label)
{
var indentedRect = EditorGUI.IndentedRect(rect);
void header()
{
var headerRect = indentedRect.SetHeight(EditorGUIUtility.singleLineHeight);
void foldout()
{
var fullHeaderRect = headerRect.MoveX(3).AddWidthFromRight(17);
if (fullHeaderRect.IsHovered())
fullHeaderRect.Draw(Greyscale(1, .07f));
SetGUIColor(Color.clear);
SetGUIEnabled(true);
if (GUI.Button(fullHeaderRect.AddWidth(-50), ""))
prop.isExpanded = !prop.isExpanded;
ResetGUIColor();
ResetGUIEnabled();
var triangleRect = rect.SetHeight(EditorGUIUtility.singleLineHeight);
SetGUIEnabled(true);
EditorGUI.Foldout(triangleRect, prop.isExpanded, "");
ResetGUIEnabled();
}
void label()
{
SetLabelBold();
SetLabelFontSize(12);
SetGUIColor(Greyscale(.9f));
SetGUIEnabled(true);
GUI.Label(headerRect, prop.displayName);
ResetGUIEnabled();
ResetGUIColor();
ResetLabelStyle();
}
void count()
{
kvpsProp.arraySize = EditorGUI.DelayedIntField(headerRect.SetWidthFromRight(48 + EditorGUI.indentLevel * 15), kvpsProp.arraySize);
}
void repeatedKeysWarning()
{
if (!curEvent.isRepaint) return;
var hasRepeated = false;
for (int i = 0; i < kvpsProp.arraySize; i++)
hasRepeated |= kvpsProp.GetArrayElementAtIndex(i).FindPropertyRelative("isKeyRepeated").boolValue;
if (!hasRepeated) return;
var warningRect = headerRect.AddWidthFromRight(-prop.displayName.GetLabelWidth(isBold: true));
GUI.Label(warningRect.SetHeightFromMid(20).SetWidth(20), EditorGUIUtility.IconContent("Warning"));
SetGUIColor(new Color(1, .9f, .03f) * 1.1f);
GUI.Label(warningRect.MoveX(16), "Repeated keys");
ResetGUIColor();
}
foldout();
label();
count();
repeatedKeysWarning();
}
void list_()
{
if (!prop.isExpanded) return;
SetupList(prop);
list.DoList(indentedRect.AddHeightFromBottom(-EditorGUIUtility.singleLineHeight - 3));
}
SetupProps(prop);
header();
list_();
}
public override float GetPropertyHeight(SerializedProperty prop, GUIContent label)
{
SetupProps(prop);
var height = EditorGUIUtility.singleLineHeight;
if (prop.isExpanded)
{
SetupList(prop);
height += list.GetHeight() + 3;
}
return height;
}
float GetListElementHeight(int index)
{
var kvpProp = kvpsProp.GetArrayElementAtIndex(index);
var keyProp = kvpProp.FindPropertyRelative("Key");
var valueProp = kvpProp.FindPropertyRelative("Value");
float propHeight(SerializedProperty prop)
{
// var height = typeof(Editor).Assembly.GetType("UnityEditor.ScriptAttributeUtility").InvokeMethod("GetHandler", prop).InvokeMethod<float>("GetHeight", prop, GUIContent.none, true);
var height = EditorGUI.GetPropertyHeight(prop);
if (!IsSingleLine(prop))
height -= 10;
return height;
}
return Mathf.Max(propHeight(keyProp), propHeight(valueProp));
}
void DrawListElement(Rect rect, int index, bool isActive, bool isFocused)
{
Rect keyRect;
Rect valueRect;
Rect dividerRect;
var kvpProp = kvpsProp.GetArrayElementAtIndex(index);
var keyProp = kvpProp.FindPropertyRelative("Key");
var valueProp = kvpProp.FindPropertyRelative("Value");
void drawProp(Rect rect, SerializedProperty prop)
{
if (IsSingleLine(prop)) { EditorGUI.PropertyField(rect.SetHeight(EditorGUIUtility.singleLineHeight), prop, GUIContent.none); return; }
prop.isExpanded = true;
GUI.BeginGroup(rect);
EditorGUI.PropertyField(rect.SetPos(0, -20), prop, true);
GUI.EndGroup();
}
void rects()
{
var dividerWidh = 6f;
var dividerPos = dividerPosProp.floatValue.Clamp(.2f, .8f);
var fullRect = rect.AddWidthFromRight(-1).AddHeightFromMid(-2);
keyRect = fullRect.SetWidth(fullRect.width * dividerPos - dividerWidh / 2);
valueRect = fullRect.SetWidthFromRight(fullRect.width * (1 - dividerPos) - dividerWidh / 2);
dividerRect = fullRect.MoveX(fullRect.width * dividerPos - dividerWidh / 2).SetWidth(dividerWidh).Resize(-1);
}
void key()
{
drawProp(keyRect, keyProp);
if (kvpProp.FindPropertyRelative("isKeyRepeated").boolValue)
GUI.Label(keyRect.SetWidthFromRight(20).SetHeight(20).MoveY(-1), EditorGUIUtility.IconContent("Warning"));
}
void value()
{
drawProp(valueRect, valueProp);
}
void divider()
{
EditorGUIUtility.AddCursorRect(dividerRect, MouseCursor.ResizeHorizontal);
if (!rect.IsHovered()) return;
if (dividerRect.IsHovered())
{
if (curEvent.isMouseDown)
isDividerDragged = true;
if (curEvent.isMouseUp || curEvent.isMouseMove || curEvent.isMouseLeaveWindow)
isDividerDragged = false;
}
if (isDividerDragged && curEvent.isMouseDrag)
dividerPosProp.floatValue += curEvent.mouseDelta.x / rect.width;
}
rects();
key();
value();
divider();
}
void DrawDictionaryIsEmpty(Rect rect) => GUI.Label(rect, "Dictionary is empty");
IEnumerable<SerializedProperty> GetChildren(SerializedProperty prop, bool enterVisibleGrandchildren)
{
var startPath = prop.propertyPath;
var enterVisibleChildren = true;
while (prop.NextVisible(enterVisibleChildren) && prop.propertyPath.StartsWith(startPath))
{
yield return prop;
enterVisibleChildren = enterVisibleGrandchildren;
}
}
bool IsSingleLine(SerializedProperty prop) => prop.propertyType != SerializedPropertyType.Generic || !prop.hasVisibleChildren;
public void SetupList(SerializedProperty prop)
{
if (list != null) return;
SetupProps(prop);
this.list = new ReorderableList(kvpsProp.serializedObject, kvpsProp, true, false, true, true);
this.list.drawElementCallback = DrawListElement;
this.list.elementHeightCallback = GetListElementHeight;
this.list.drawNoneElementCallback = DrawDictionaryIsEmpty;
}
ReorderableList list;
bool isDividerDragged;
public void SetupProps(SerializedProperty prop)
{
if (this.prop != null) return;
this.prop = prop;
this.kvpsProp = prop.FindPropertyRelative("serializedKvps");
this.dividerPosProp = prop.FindPropertyRelative("dividerPos");
}
SerializedProperty prop;
SerializedProperty kvpsProp;
SerializedProperty dividerPosProp;
}
[CustomPropertyDrawer(typeof(VariantsAttribute))]
public class VariantsAttributeDrawer : PropertyDrawer
{
public override void OnGUI(Rect rect, SerializedProperty prop, GUIContent label)
{
var variants = ((VariantsAttribute)attribute).variants;
EditorGUI.BeginProperty(rect, label, prop);
var iCur = prop.hasMultipleDifferentValues ? -1 : variants.ToList().IndexOf(prop.GetBoxedValue());
var iNew = EditorGUI.IntPopup(rect, label.text, iCur, variants.Select(r => r.ToString()).ToArray(), Enumerable.Range(0, variants.Length).ToArray());
if (iNew != -1)
prop.SetBoxedValue(variants[iNew]);
else if (!prop.hasMultipleDifferentValues)
prop.SetBoxedValue(variants[0]);
EditorGUI.EndProperty();
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 481331f9e0bfe494f98ee0fc8ebfeb84
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4a8eec962d2dd440196b02dca0f62e3e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 077bd88e5e3a2421b8bd152c5b813ea2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,180 @@
#if UNITY_EDITOR
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEditor;
using UnityEditor.Compilation;
using static VInspector.Libs.VUtils;
using static VInspector.Libs.VGUI;
namespace VInspector
{
class VInspectorMenu
{
public static bool navigationBarEnabled { get => EditorPrefs.GetBool("vInspector-navigationBarEnabled", false); set => EditorPrefs.SetBool("vInspector-navigationBarEnabled", value); }
public static bool copyPasteButtonsEnabled { get => EditorPrefs.GetBool("vInspector-copyPasteButtonsEnabled", false); set => EditorPrefs.SetBool("vInspector-copyPasteButtonsEnabled", value); }
public static bool saveInPlaymodeButtonEnabled { get => EditorPrefs.GetBool("vInspector-saveInPlaymodeButtonEnabled", false); set => EditorPrefs.SetBool("vInspector-saveInPlaymodeButtonEnabled", value); }
public static bool componentWindowsEnabled { get => EditorPrefs.GetBool("vInspector-componentWindowsEnabled", false); set => EditorPrefs.SetBool("vInspector-componentWindowsEnabled", value); }
public static bool componentAnimationsEnabled { get => EditorPrefs.GetBool("vInspector-componentAnimationsEnabled", false); set => EditorPrefs.SetBool("vInspector-componentAnimationsEnabled", value); }
public static bool minimalModeEnabled { get => EditorPrefs.GetBool("vInspector-minimalModeEnabled", false); set => EditorPrefs.SetBool("vInspector-minimalModeEnabled", value); }
public static bool attributesEnabled { get => EditorPrefs.GetBool("vInspector-attributesEnabled", false); set => EditorPrefs.SetBool("vInspector-attributesEnabled", value); }
public static bool resettableVariablesEnabled { get => EditorPrefs.GetBool("vInspector-resettableVariablesEnabled", false); set => EditorPrefs.SetBool("vInspector-resettableVariablesEnabled", value); }
public static bool hideScriptFieldEnabled { get => EditorPrefs.GetBool("vInspector-hideScriptFieldEnabled", false); set => EditorPrefs.SetBool("vInspector-hideScriptFieldEnabled", value); }
public static bool hideHelpButtonEnabled { get => !helpButtonEnabled; set => helpButtonEnabled = !value; }
public static bool hidePresetsButtonEnabled { get => !presetsButtonEnabled; set => presetsButtonEnabled = !value; }
public static bool toggleActiveEnabled { get => EditorPrefs.GetBool("vInspector-toggleActiveEnabled", true); set => EditorPrefs.SetBool("vInspector-toggleActiveEnabled", value); }
public static bool deleteEnabled { get => EditorPrefs.GetBool("vInspector-deleteEnabled", true); set => EditorPrefs.SetBool("vInspector-deleteEnabled", value); }
public static bool toggleExpandedEnabled { get => EditorPrefs.GetBool("vInspector-toggleExpandedEnabled", true); set => EditorPrefs.SetBool("vInspector-toggleExpandedEnabled", value); }
public static bool collapseEverythingElseEnabled { get => EditorPrefs.GetBool("vInspector-collapseEverythingElseEnabled", true); set => EditorPrefs.SetBool("vInspector-collapseEverythingElseEnabled", value); }
public static bool collapseEverythingEnabled { get => EditorPrefs.GetBool("vInspector-collapseEverythingEnabled", true); set => EditorPrefs.SetBool("vInspector-collapseEverythingEnabled", value); }
public static bool attributesDisabled { get => IsSymbolDefinedInAsmdef(nameof(VInspector), "VINSPECTOR_ATTRIBUTES_DISABLED"); set => SetSymbolDefinedInAsmdef(nameof(VInspector), "VINSPECTOR_ATTRIBUTES_DISABLED", value); }
public static bool pluginDisabled { get => EditorPrefs.GetBool("vInspector-pluginDisabled-" + GetProjectId(), false); set => EditorPrefs.SetBool("vInspector-pluginDisabled-" + GetProjectId(), value); }
public static int componentButtons_defaultButtonsCount { get => EditorPrefs.GetInt("vInspector-componentButtons_defaultButtonsCount", 3); set => EditorPrefs.SetInt("vInspector-componentButtons_defaultButtonsCount", value); }
public static bool menuButtonEnabled { get => componentButtons_defaultButtonsCount >= 1; set => componentButtons_defaultButtonsCount = value ? 1 : 0; }
public static bool presetsButtonEnabled { get => componentButtons_defaultButtonsCount >= 2; set => componentButtons_defaultButtonsCount = value ? 2 : 1; }
public static bool helpButtonEnabled { get => componentButtons_defaultButtonsCount >= 3; set => componentButtons_defaultButtonsCount = value ? 3 : 2; }
public static void RepaintInspectors()
{
Resources.FindObjectsOfTypeAll(typeof(Editor).Assembly.GetType("UnityEditor.InspectorWindow"))
.Cast<EditorWindow>()
.ForEach(r => r.Repaint());
Resources.FindObjectsOfTypeAll(typeof(Editor).Assembly.GetType("UnityEditor.PropertyEditor"))
.Where(r => r.GetType().BaseType == typeof(EditorWindow))
.Cast<EditorWindow>()
.ForEach(r => r.Repaint());
}
const string dir = "Tools/vInspector/";
#if UNITY_EDITOR_OSX
const string cmd = "Cmd";
#else
const string cmd = "Ctrl";
#endif
const string navigationBar = dir + "Navigation bar";
const string copyPasteButtons = dir + "Copy \u2215 Paste components";
const string saveInPlaymodeButton = dir + "Save in play mode";
const string componentWindows = dir + "Component windows";
const string componentAnimations = dir + "Component animations";
const string minimalMode = dir + "Minimal mode";
const string resettableVariables = dir + "Resettable variables";
const string hideScriptField = dir + "Hide script field";
const string hideHelpButton = dir + "Hide help button";
const string hidePresetsButton = dir + "Hide presets button";
const string toggleActive = dir + "A to toggle component active";
const string delete = dir + "X to delete component";
const string toggleExpanded = dir + "E to expand \u2215 collapse component";
const string collapseEverythingElse = dir + "Shift-E to expand only one component";
const string collapseEverything = dir + "Ctrl-Shift-E to expand \u2215 collapse all components";
const string disableAttributes = dir + "Disable attributes";
const string disablePlugin = dir + "Disable vInspector";
[MenuItem(dir + "Features", false, 1)] static void dadsas() { }
[MenuItem(dir + "Features", true, 1)] static bool dadsas123() => false;
[MenuItem(navigationBar, false, 2)] static void dadsadsadasdsadadsas() { navigationBarEnabled = !navigationBarEnabled; RepaintInspectors(); }
[MenuItem(navigationBar, true, 2)] static bool dadsaddsasadadsdasadsas() { Menu.SetChecked(navigationBar, navigationBarEnabled); return !pluginDisabled; }
[MenuItem(copyPasteButtons, false, 3)] static void dadsaasddsadaasdsdsadadsas() { copyPasteButtonsEnabled = !copyPasteButtonsEnabled; RepaintInspectors(); }
[MenuItem(copyPasteButtons, true, 3)] static bool dadsaddasdsasaasddadsdasadsas() { Menu.SetChecked(copyPasteButtons, copyPasteButtonsEnabled); return !pluginDisabled; }
[MenuItem(saveInPlaymodeButton, false, 4)] static void dadsadsadaasasdsdsadadsas() { saveInPlaymodeButtonEnabled = !saveInPlaymodeButtonEnabled; RepaintInspectors(); }
[MenuItem(saveInPlaymodeButton, true, 4)] static bool dadsaddsasaadsasddadsdasadsas() { Menu.SetChecked(saveInPlaymodeButton, saveInPlaymodeButtonEnabled); return !pluginDisabled; }
[MenuItem(componentWindows, false, 5)] static void dadsadsadaasdsdsadadsas() { componentWindowsEnabled = !componentWindowsEnabled; RepaintInspectors(); }
[MenuItem(componentWindows, true, 5)] static bool dadsaddsasaasddadsdasadsas() { Menu.SetChecked(componentWindows, componentWindowsEnabled); return !pluginDisabled; }
[MenuItem(componentAnimations, false, 6)] static void dadsadsadsadaasdsdsadadsas() { componentAnimationsEnabled = !componentAnimationsEnabled; RepaintInspectors(); }
[MenuItem(componentAnimations, true, 6)] static bool dadsadddsasasaasddadsdasadsas() { Menu.SetChecked(componentAnimations, componentAnimationsEnabled); return !pluginDisabled; }
[MenuItem(minimalMode, false, 7)] static void dadsadsadsadsadasdsadadsas() { minimalModeEnabled = !minimalModeEnabled; RepaintInspectors(); }
[MenuItem(minimalMode, true, 7)] static bool dadsadasdasddsasadadsdasadsas() { Menu.SetChecked(minimalMode, minimalModeEnabled); return !pluginDisabled; }
[MenuItem(resettableVariables, false, 8)] static void dadsadsadsadasdsadadsas() { resettableVariablesEnabled = !resettableVariablesEnabled; RepaintInspectors(); }
[MenuItem(resettableVariables, true, 8)] static bool dadsadasddsasadadsdasadsas() { Menu.SetChecked(resettableVariables, resettableVariablesEnabled); return !pluginDisabled; }
[MenuItem(hideScriptField, false, 9)] static void dadsadsdsaadsadsadasdsadadsas() { hideScriptFieldEnabled = !hideScriptFieldEnabled; RepaintInspectors(); }
[MenuItem(hideScriptField, true, 9)] static bool dadsadasadsdasddsasadadsdasadsas() { Menu.SetChecked(hideScriptField, hideScriptFieldEnabled); return !pluginDisabled; }
[MenuItem(hideHelpButton, false, 10)] static void dadsadsadsdsaadsadsadasdsadadsas() { hideHelpButtonEnabled = !hideHelpButtonEnabled; RepaintInspectors(); }
[MenuItem(hideHelpButton, true, 10)] static bool dadsaadsdasadsdasddsasadadsdasadsas() { Menu.SetChecked(hideHelpButton, hideHelpButtonEnabled); return !pluginDisabled; }
[MenuItem(hidePresetsButton, false, 11)] static void dadsadsdsaadssdadsadasdsadadsas() { hidePresetsButtonEnabled = !hidePresetsButtonEnabled; RepaintInspectors(); }
[MenuItem(hidePresetsButton, true, 11)] static bool dadsadasadsddsasddsasadadsdasadsas() { Menu.SetChecked(hidePresetsButton, hidePresetsButtonEnabled); return !pluginDisabled; }
[MenuItem(dir + "Shortcuts", false, 1001)] static void dadsadsas() { }
[MenuItem(dir + "Shortcuts", true, 1001)] static bool dadsadsas123() => false;
[MenuItem(toggleActive, false, 1002)] static void dadsadadsas() => toggleActiveEnabled = !toggleActiveEnabled;
[MenuItem(toggleActive, true, 1002)] static bool dadsaddasadsas() { Menu.SetChecked(toggleActive, toggleActiveEnabled); return !pluginDisabled; }
[MenuItem(delete, false, 1003)] static void dadsadsadasdadsas() => deleteEnabled = !deleteEnabled;
[MenuItem(delete, true, 1003)] static bool dadsaddsasaddasadsas() { Menu.SetChecked(delete, deleteEnabled); return !pluginDisabled; }
[MenuItem(toggleExpanded, false, 1004)] static void dadsaddsasadasdsadadsas() => toggleExpandedEnabled = !toggleExpandedEnabled;
[MenuItem(toggleExpanded, true, 1004)] static bool dadsaddsdsasadadsdasadsas() { Menu.SetChecked(toggleExpanded, toggleExpandedEnabled); return !pluginDisabled; }
[MenuItem(collapseEverythingElse, false, 1005)] static void dadsadsasdadasdsadadsas() => collapseEverythingElseEnabled = !collapseEverythingElseEnabled;
[MenuItem(collapseEverythingElse, true, 1005)] static bool dadsaddsdasasadadsdasadsas() { Menu.SetChecked(collapseEverythingElse, collapseEverythingElseEnabled); return !pluginDisabled; }
[MenuItem(collapseEverything, false, 1006)] static void dadsadsdasadasdsadadsas() => collapseEverythingEnabled = !collapseEverythingEnabled;
[MenuItem(collapseEverything, true, 1006)] static bool dadsaddssdaasadadsdasadsas() { Menu.SetChecked(collapseEverything, collapseEverythingEnabled); 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() => Application.OpenURL("https://kubacho-lab.gitbook.io/vinspector2");
[MenuItem(dir + "Join our Discord", false, 10003)]
static void dadasdsas() => Application.OpenURL("https://discord.gg/pUektnZeJT");
// [MenuItem(dir + "Clear state", false, 5555)] static void dassaadsasddc() { VInspectorState.Clear(); VInspector.firstAttrStateCacheLayer.Clear(); RepaintInspectors(); }
// [MenuItem(dir + "Clear state", true, 5555)] static bool dassaadsadsasddc() { return !pluginDisabled; }
// [MenuItem(dir + "Save state", false, 5556)] static void dassaaasddsasddc() { VInspectorState.Save(); }
// [MenuItem(dir + "Save state", true, 5556)] static bool dassaadsaasddsasddc() { return !pluginDisabled; }
// [MenuItem(disableAttributes, false, 5557)] static void dadsadsdasadasdasdsadadsas() { attributesDisabled = !attributesDisabled; }
// [MenuItem(disableAttributes, true, 5557)] static bool dadsaddssdaasadsadadsdasadsas() { Menu.SetChecked(disableAttributes, attributesDisabled); return !pluginDisabled; }
[MenuItem(disablePlugin, false, 100001)] static void dadsadsdsdasadasdasdsadadsas() { pluginDisabled = !pluginDisabled; if (!pluginDisabled) EditorPrefs.SetBool("vInspector-pluginWasReenabled", true); attributesDisabled = pluginDisabled; }
[MenuItem(disablePlugin, true, 100001)] static bool dadsaddssdsdaasadsadadsdasadsas() { Menu.SetChecked(disablePlugin, pluginDisabled); return true; }
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 07852b6b534474f7fb57529201e123e0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f27f798b17a724efc8b05c54e23eff97
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,173 @@
#if UNITY_EDITOR
using System.Collections;
using System.Linq;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using UnityEngine;
using UnityEngine.UIElements;
using UnityEditor.UIElements;
using System.Reflection;
using UnityEditor;
using Type = System.Type;
using static VInspector.VInspectorState;
using static VInspector.Libs.VUtils;
using static VInspector.Libs.VGUI;
namespace VInspector
{
static class VInspectorResettableVariables
{
public static void ResetButtonGUI(Rect fieldRect, SerializedProperty property, FieldInfo fieldInfo, IEnumerable<object> targets)
{
// if (!fieldRect.IsHovered()) return;
object targetWithDefaultValues = GetTargetWithDefaulValues(targets.First().GetType());
bool isResetted(object target)
{
if (property.isInstantiatedPrefab) return !property.prefabOverride;
if (targetWithDefaultValues as object == null) return true;
var currentValue = fieldInfo.GetValue(target);
var defaultValue = fieldInfo.GetValue(targetWithDefaultValues);
var isResetted = object.Equals(currentValue, defaultValue);
if (typeof(Object).IsAssignableFrom(fieldInfo.FieldType))
isResetted |= (defaultValue == null) && !(bool)(Object)currentValue;
if (fieldInfo.FieldType == typeof(string))
isResetted |= fieldInfo.FieldType == typeof(string) && (object.Equals(currentValue, "") && object.Equals(defaultValue, null));
return isResetted;
}
if (targets.All(r => isResetted(r))) return;
var iconSize = 12;
var colorNormal = Greyscale(.41f);
var colorHovered = Greyscale(isDarkTheme ? .9f : .0f);
var colorPressed = Greyscale(isDarkTheme ? .65f : .6f);
var buttonRect = fieldRect.SetWidthFromRight(20).MoveX(typeof(Object).IsAssignableFrom(fieldInfo.FieldType) ? -18 : 1);
EditorGUIUtility.AddCursorRect(buttonRect, MouseCursor.CustomCursor);
if (!IconButton(buttonRect, "CrossIcon", iconSize, colorNormal, colorHovered, colorPressed)) return;
if (property.isInstantiatedPrefab)
{
foreach (var target in property.serializedObject.targetObjects)
target.RecordUndo();
PrefabUtility.RevertPropertyOverride(property, InteractionMode.AutomatedAction);
}
else
property.SetBoxedValue(fieldInfo.GetValue(targetWithDefaultValues));
GUI.changed = true;
GUI.FocusControl(null);
}
static object GetTargetWithDefaulValues(Type targetType)
{
if (targetWithDefaulValues_byType.TryGetValue(targetType, out var cachedResult)) return cachedResult;
object targetWithDefaultValues = null;
void script_2023plus()
{
#if UNITY_2023_2_OR_NEWER
if (!typeof(MonoBehaviour).IsAssignableFrom(targetType)) return;
if (Application.isPlaying || TypeCache.GetTypesWithAttribute<ExecuteInEditMode>().Contains(targetType) || TypeCache.GetTypesWithAttribute<ExecuteAlways>().Contains(targetType))
if ((targetType.GetMethodInfo("Awake") ?? targetType.GetMethodInfo("OnEnable") ?? targetType.GetMethodInfo("OnDisable") ?? targetType.GetMethodInfo("OnDestroy")) != null) return; // to avoid executing user code
var tempGo = EditorUtility.CreateGameObjectWithHideFlags("Dummy object for fetching default variable values for vInspector's resettable variables feature", HideFlags.HideAndDontSave, targetType);
try { targetWithDefaultValues = tempGo.GetComponent(targetType); }
finally { Object.DestroyImmediate(tempGo); }
#endif
}
void script_olderVersions()
{
#if !UNITY_2023_2_OR_NEWER
if (!typeof(MonoBehaviour).IsAssignableFrom(targetType)) return;
targetWithDefaultValues = ScriptableObject.CreateInstance(targetType);
#endif
}
void scriptableObject()
{
if (!typeof(ScriptableObject).IsAssignableFrom(targetType)) return;
targetWithDefaultValues = ScriptableObject.CreateInstance(targetType);
}
void customClass()
{
if (typeof(MonoBehaviour).IsAssignableFrom(targetType)) return;
if (typeof(ScriptableObject).IsAssignableFrom(targetType)) return;
if (targetType.GetConstructor(System.Type.EmptyTypes) == null) return;
targetWithDefaultValues = System.Activator.CreateInstance(targetType);
}
script_2023plus();
script_olderVersions();
scriptableObject();
customClass();
return targetWithDefaulValues_byType[targetType] = targetWithDefaultValues;
}
static Dictionary<Type, object> targetWithDefaulValues_byType = new();
public static bool IsResettable(FieldInfo fieldInfo)
{
if (!VInspectorMenu.resettableVariablesEnabled) return false;
if (Application.isPlaying) return false;
if (System.Attribute.IsDefined(fieldInfo, typeof(VariantsAttribute))) return false;
if (typeof(Object).IsAssignableFrom(fieldInfo.FieldType)) return true;
if (fieldInfo.FieldType == typeof(int)) return true;
if (fieldInfo.FieldType == typeof(float)) return true;
if (fieldInfo.FieldType == typeof(double)) return true;
if (fieldInfo.FieldType == typeof(string)) return true;
return false;
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4efb7d95707f0459ba76cac7fa149875
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,125 @@
#if UNITY_EDITOR
using UnityEngine;
using UnityEngine.UIElements;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.ShortcutManagement;
using System.Reflection;
using System.Linq;
using System.Text.RegularExpressions;
using Type = System.Type;
using static VInspector.Libs.VUtils;
using static VInspector.Libs.VGUI;
namespace VInspector
{
public class VInspectorSelectionHistory : ScriptableSingleton<VInspectorSelectionHistory>
{
public void MoveBack()
{
var prevState = prevStates.Last();
instance.RecordUndo("VInspectorSelectionHistory.MoveBack");
prevStates.Remove(prevState);
nextStates.Add(curState);
curState = prevState;
ignoreThisSelectionChange = true;
prevState.selectedObjects.ToArray().SelectInInspector(frameInHierarchy: false, frameInProject: false);
}
public void MoveForward()
{
var nextState = nextStates.Last();
instance.RecordUndo("VInspectorSelectionHistory.MoveForward");
nextStates.Remove(nextState);
prevStates.Add(curState);
curState = nextState;
ignoreThisSelectionChange = true;
nextState.selectedObjects.ToArray().SelectInInspector(frameInHierarchy: false, frameInProject: false);
}
static void OnSelectionChange()
{
if (ignoreThisSelectionChange) { ignoreThisSelectionChange = false; return; }
if (curEvent.modifiers == EventModifiers.Command && curEvent.keyCode == KeyCode.Z) return;
if (curEvent.modifiers == (EventModifiers.Command | EventModifiers.Shift) && curEvent.keyCode == KeyCode.Z) return;
if (curEvent.modifiers == EventModifiers.Control && curEvent.keyCode == KeyCode.Z) return;
if (curEvent.modifiers == EventModifiers.Control && curEvent.keyCode == KeyCode.Y) return;
instance.RecordUndo(Undo.GetCurrentGroupName());
instance.prevStates.Add(instance.curState);
instance.curState = new SelectionState() { selectedObjects = Selection.objects.ToList() };
instance.nextStates.Clear();
if (instance.prevStates.Count > 50)
instance.prevStates.RemoveAt(0);
}
static bool ignoreThisSelectionChange;
public List<SelectionState> prevStates = new();
public List<SelectionState> nextStates = new();
public SelectionState curState;
[System.Serializable]
public class SelectionState { public List<Object> selectedObjects = new(); }
[InitializeOnLoadMethod]
static void Init()
{
Selection.selectionChanged -= OnSelectionChange;
Selection.selectionChanged += OnSelectionChange;
// var globalEventHandler = typeof(EditorApplication).GetFieldValue<EditorApplication.CallbackFunction>("globalEventHandler");
// typeof(EditorApplication).SetFieldValue("globalEventHandler", ClearHistories + (globalEventHandler - ClearHistories));
instance.curState = new SelectionState() { selectedObjects = Selection.objects.ToList() };
}
// static void ClearHistories() // just for debug
// {
// if (curEvent.holdingAnyModifierKey) return;
// if (!curEvent.isKeyDown || curEvent.keyCode != KeyCode.Y) return;
// VInspectorSelectionHistory.instance.prevStates.Clear();
// VInspectorSelectionHistory.instance.nextStates.Clear();
// Undo.ClearAll();
// VInspectorMenu.RepaintInspectors();
// }
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 76c5ee368a46a4167b845f6db32ad060
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,64 @@
using System.Collections;
using System.Linq;
using System.Collections.Generic;
using UnityEngine;
namespace VInspector
{
[System.Serializable]
public class SerializedDictionary<TKey, TValue> : Dictionary<TKey, TValue>, ISerializationCallbackReceiver
{
public List<SerializedKeyValuePair<TKey, TValue>> serializedKvps = new();
public float dividerPos = .33f;
public void OnBeforeSerialize()
{
foreach (var kvp in this)
if (serializedKvps.FirstOrDefault(r => this.Comparer.Equals(r.Key, kvp.Key)) is SerializedKeyValuePair<TKey, TValue> serializedKvp)
serializedKvp.Value = kvp.Value;
else
serializedKvps.Add(kvp);
serializedKvps.RemoveAll(r => !this.ContainsKey(r.Key));
for (int i = 0; i < serializedKvps.Count; i++)
serializedKvps[i].index = i;
}
public void OnAfterDeserialize()
{
this.Clear();
serializedKvps.RemoveAll(r => r.Key is null);
foreach (var serializedKvp in serializedKvps)
if (!(serializedKvp.isKeyRepeated = this.ContainsKey(serializedKvp.Key)))
this.Add(serializedKvp.Key, serializedKvp.Value);
}
[System.Serializable]
public class SerializedKeyValuePair<TKey_, TValue_>
{
public TKey_ Key;
public TValue_ Value;
public int index;
public bool isKeyRepeated;
public SerializedKeyValuePair(TKey_ key, TValue_ value) { this.Key = key; this.Value = value; }
public static implicit operator SerializedKeyValuePair<TKey_, TValue_>(KeyValuePair<TKey_, TValue_> kvp) => new(kvp.Key, kvp.Value);
public static implicit operator KeyValuePair<TKey_, TValue_>(SerializedKeyValuePair<TKey_, TValue_> kvp) => new(kvp.Key, kvp.Value);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 00ee9a38e8fee47c29efb5789be8458c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,66 @@
#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 VInspector.Libs.VUtils;
using static VInspector.Libs.VGUI;
namespace VInspector
{
[FilePath("Library/vInspector State.asset", FilePathAttribute.Location.ProjectFolder)]
public class VInspectorState : ScriptableSingleton<VInspectorState>
{
public SerializableDictionary<string, AttributesState> attributeStates_byScriptName = new();
[System.Serializable]
public class AttributesState
{
public SerializableDictionary<string, int> selectedSubtabIndexes_byTabPath = new();
public SerializableDictionary<string, bool> isExpandeds_byFoldoutPath = new();
public SerializableDictionary<string, bool> isExpandeds_byButtonPath = new();
}
public SerializableDictionary<int, ItemState> itemStates_byItemId = new();
[System.Serializable]
public class ItemState
{
public string _name;
public string sceneGameObjectIconName;
}
public static void Clear()
{
instance.attributeStates_byScriptName.Clear();
instance.itemStates_byItemId.Clear();
}
public static void Save() => instance.Save(true);
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6fcb471c750b741839863cd8a7ce5785
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,15 @@
%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: b7915df4cd4da490ab52fc8fa9ee9127, type: 3}
m_Name: vInspector Data
m_EditorClassIdentifier:
items: []

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ddfa531a68919e242bbdf2705511235c
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant: