Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Assets/Editor Toolbox/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
## 0.11.4 [17.07.2022]

### Added:
- ToolboxWizard, additional Toolbox-based equivalent for the ScriptableWizard class

### Changed:
- Fix caching FieldInfo for [SerializeReference] properties

## 0.11.3 [05.06.2022]

### Added:
Expand Down
3 changes: 3 additions & 0 deletions Assets/Editor Toolbox/Editor/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("Toolbox.Editor.Tests")]
11 changes: 11 additions & 0 deletions Assets/Editor Toolbox/Editor/AssemblyInfo.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 9 additions & 9 deletions Assets/Editor Toolbox/Editor/ToolboxDrawerModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,20 @@ internal static void InitializeModule()
}


private readonly static Type decoratorDrawerBase = typeof(ToolboxDecoratorDrawer<>);
private readonly static Type conditionDrawerBase = typeof(ToolboxConditionDrawer<>);
private readonly static Type selfPropertyDrawerBase = typeof(ToolboxSelfPropertyDrawer<>);
private readonly static Type listPropertyDrawerBase = typeof(ToolboxListPropertyDrawer<>);
private static readonly Type decoratorDrawerBase = typeof(ToolboxDecoratorDrawer<>);
private static readonly Type conditionDrawerBase = typeof(ToolboxConditionDrawer<>);
private static readonly Type selfPropertyDrawerBase = typeof(ToolboxSelfPropertyDrawer<>);
private static readonly Type listPropertyDrawerBase = typeof(ToolboxListPropertyDrawer<>);

private readonly static Dictionary<Type, ToolboxDecoratorDrawerBase> decoratorDrawers = new Dictionary<Type, ToolboxDecoratorDrawerBase>();
private readonly static Dictionary<Type, ToolboxConditionDrawerBase> conditionDrawers = new Dictionary<Type, ToolboxConditionDrawerBase>();
private readonly static Dictionary<Type, ToolboxPropertyDrawerBase> selfPropertyDrawers = new Dictionary<Type, ToolboxPropertyDrawerBase>();
private readonly static Dictionary<Type, ToolboxPropertyDrawerBase> listPropertyDrawers = new Dictionary<Type, ToolboxPropertyDrawerBase>();
private static readonly Dictionary<Type, ToolboxDecoratorDrawerBase> decoratorDrawers = new Dictionary<Type, ToolboxDecoratorDrawerBase>();
private static readonly Dictionary<Type, ToolboxConditionDrawerBase> conditionDrawers = new Dictionary<Type, ToolboxConditionDrawerBase>();
private static readonly Dictionary<Type, ToolboxPropertyDrawerBase> selfPropertyDrawers = new Dictionary<Type, ToolboxPropertyDrawerBase>();
private static readonly Dictionary<Type, ToolboxPropertyDrawerBase> listPropertyDrawers = new Dictionary<Type, ToolboxPropertyDrawerBase>();

/// <summary>
/// Collection of specific drawers mapped to selected (picked) object types.
/// </summary>
private readonly static Dictionary<Type, ToolboxTargetTypeDrawer> targetTypeDrawers = new Dictionary<Type, ToolboxTargetTypeDrawer>();
private static readonly Dictionary<Type, ToolboxTargetTypeDrawer> targetTypeDrawers = new Dictionary<Type, ToolboxTargetTypeDrawer>();

/// <summary>
/// Collection of currently cached handlers mapped to a unique property key.
Expand Down
30 changes: 22 additions & 8 deletions Assets/Editor Toolbox/Editor/Utilities/PropertyUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
using UnityEditor;
using Object = UnityEngine.Object;

[assembly: InternalsVisibleTo("Toolbox.Editor.Tests")]

namespace Toolbox.Editor
{
public static partial class PropertyUtility
Expand All @@ -27,7 +25,9 @@ internal static bool HasModifedProperties(this SerializedProperty property)
internal static string GetPropertyHashKey(this SerializedProperty property)
{
var hash = property.serializedObject.GetHashCode();
return string.Format("{0}.{1}", hash, property.propertyPath);
return property.propertyType != SerializedPropertyType.ManagedReference
? $"{hash}.{property.propertyPath}"
: $"{hash}.{property.propertyPath}.{property.managedReferenceFieldTypename}";
}

/// <summary>
Expand All @@ -36,7 +36,9 @@ internal static string GetPropertyHashKey(this SerializedProperty property)
internal static string GetPropertyTypeKey(this SerializedProperty property)
{
var type = property.serializedObject.targetObject.GetType();
return string.Format("{0}.{1}", type, property.propertyPath);
return property.propertyType != SerializedPropertyType.ManagedReference
? $"{type}.{property.propertyPath}"
: $"{type}.{property.propertyPath}.{property.managedReferenceFieldTypename}";
}

/// <summary>
Expand Down Expand Up @@ -253,7 +255,7 @@ internal static FieldInfo GetFieldInfo(this SerializedProperty property, out Typ

internal static FieldInfo GetFieldInfo(this SerializedProperty property, out Type propertyType, Object target)
{
return GetFieldInfoFromProperty(target.GetType(), property.propertyPath, out propertyType);
return GetFieldInfoFromProperty(property, out propertyType, target.GetType());
}

public static FieldInfo GetFieldInfoFromProperty(SerializedProperty property, out Type type)
Expand All @@ -265,14 +267,15 @@ public static FieldInfo GetFieldInfoFromProperty(SerializedProperty property, ou
return null;
}

return GetFieldInfoFromProperty(classType, property.propertyPath, out type);
return GetFieldInfoFromProperty(property, out type, classType);
}

public static FieldInfo GetFieldInfoFromProperty(Type host, string fieldPath, out Type type)
public static FieldInfo GetFieldInfoFromProperty(SerializedProperty property, out Type type, Type host)
{
FieldInfo field = null;
type = host;

var fieldPath = property.propertyPath;
var members = GetPropertyFieldTree(fieldPath, false);
for (var i = 0; i < members.Length; i++)
{
Expand All @@ -287,10 +290,21 @@ public static FieldInfo GetFieldInfoFromProperty(Type host, string fieldPath, ou
continue;
}

const BindingFlags fieldFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
FieldInfo foundField = null;
for (var currentType = type; foundField == null && currentType != null; currentType = currentType.BaseType)
{
foundField = currentType.GetField(member, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foundField = currentType.GetField(member, fieldFlags);
//NOTE: [SerializeReference] detected? If so we need to check dynamically cached type
if (foundField == null)
{
var parent = property.GetParent();
if (parent != null && parent.propertyType == SerializedPropertyType.ManagedReference)
{
TypeUtilities.TryGetTypeFromManagedReferenceFullTypeName(parent.managedReferenceFullTypename, out var parentType);
foundField = parentType.GetField(member, fieldFlags);
}
}
}

if (foundField == null)
Expand Down
8 changes: 8 additions & 0 deletions Assets/Editor Toolbox/Editor/Windows.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

93 changes: 93 additions & 0 deletions Assets/Editor Toolbox/Editor/Windows/ToolboxWizard.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
using UnityEditor;
using UnityEngine;

namespace Toolbox.Editor.Wizards
{
using Editor = UnityEditor.Editor;

public class ToolboxWizard : EditorWindow
{
private Editor targetEditor;

private Vector2 scrollPosition;

private void OnDestroy()
{
DestroyImmediate(targetEditor);
}

private void OnGUI()
{
using (var scrollView = new EditorGUILayout.ScrollViewScope(scrollPosition))
{
scrollPosition = scrollView.scrollPosition;
EditorGUI.BeginChangeCheck();
OnWizardGui();
if (EditorGUI.EndChangeCheck())
{
OnWizardUpdate();
}
}

using (new EditorGUILayout.VerticalScope())
{
GUILayout.FlexibleSpace();
using (new EditorGUILayout.HorizontalScope())
{
GUILayout.FlexibleSpace();
HandleOtherButtons();
GUI.enabled = IsValid;
if (HandleCreateButton())
{
OnWizardCreate();
Close();
GUIUtility.ExitGUI();
}

GUI.enabled = true;
}

GUILayout.Space(5);
}
}

private void PrepareEditor()
{
if (targetEditor != null)
{
return;
}

targetEditor = Editor.CreateEditor(this);
targetEditor.hideFlags = HideFlags.HideAndDontSave;
OnWizardUpdate();
}

protected virtual void OnWizardCreate()
{ }

protected virtual void OnWizardUpdate()
{ }

protected virtual void OnWizardGui()
{
PrepareEditor();
targetEditor.OnInspectorGUI();
}

protected virtual bool HandleCreateButton()
{
return GUILayout.Button("Create", GUILayout.MinWidth(100));
}

protected virtual void HandleOtherButtons()
{ }

public static T DisplayWizard<T>(string title) where T : ToolboxWizard
{
return GetWindow<T>(true, title);
}

protected bool IsValid { get; set; } = true;
}
}
11 changes: 11 additions & 0 deletions Assets/Editor Toolbox/Editor/Windows/ToolboxWizard.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Assets/Editor Toolbox/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "com.arimger.editor-toolbox",
"displayName": "Editor Toolbox",
"version": "0.11.3",
"version": "0.11.4",
"unity": "2018.1",
"description": "Tools, custom attributes, drawers, hierarchy overlay, and other extensions for the Unity Editor.",
"keywords": [
Expand Down
55 changes: 55 additions & 0 deletions Assets/Examples/Editor/SampleWizard.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using Toolbox.Editor.Wizards;

using UnityEditor;
using UnityEngine;

public class SampleWizard : ToolboxWizard
{
[SerializeField, InLineEditor]
private GameObject prefab;
[SerializeField]
private string targetName;

private bool hasInvalidName;

[MenuItem("GameObject/Sample Wizard")]
public static void CreateWizard()
{
DisplayWizard<SampleWizard>("Create GameObject");
}

protected override void OnWizardCreate()
{
GameObject go;
if (prefab != null)
{
go = Instantiate(prefab);
go.name = targetName;
}
else
{
go = new GameObject(targetName);
}

Selection.activeObject = go;
}

protected override void OnWizardUpdate()
{
hasInvalidName = string.IsNullOrEmpty(targetName);
}

protected override void OnWizardGui()
{
base.OnWizardGui();
if (hasInvalidName)
{
EditorGUILayout.HelpBox("Name is invalid", MessageType.Error, true);
}
}

protected override void HandleOtherButtons()
{
//you can draw more buttons here
}
}
11 changes: 11 additions & 0 deletions Assets/Examples/Editor/SampleWizard.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 10 additions & 3 deletions Assets/Examples/Scenes/SampleScene.unity
Original file line number Diff line number Diff line change
Expand Up @@ -584,14 +584,21 @@ MonoBehaviour:
references:
version: 1
00000000:
type: {class: SampleBehaviour6/Struct, ns: , asm: Assembly-CSharp}
type: {class: SampleBehaviour6/ClassWithInterface1, ns: , asm: Assembly-CSharp}
data:
var1: 1
var2: 1
go: {fileID: 977748987}
var1:
id: 2
00000001:
type: {class: SampleBehaviour6/ClassWithInterface2, ns: , asm: Assembly-CSharp}
data:
var1: 0
mat: {fileID: 2100000, guid: 7404c70251f9d0045a4aabaa49d83963, type: 2}
00000002:
type: {class: SampleBehaviour6/Struct, ns: , asm: Assembly-CSharp}
data:
var1: 1
var2: 0
--- !u!4 &752799893
Transform:
m_ObjectHideFlags: 2
Expand Down
5 changes: 5 additions & 0 deletions Assets/Examples/Scripts/SampleBehaviour6.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,19 @@ public abstract class ClassWithInterfaceBase : Interface1 { }
[Serializable]
public class ClassWithInterface1 : ClassWithInterfaceBase
{
[InLineEditor]
public GameObject go;
[SerializeReference, ReferencePicker]
public Interface1 var1;
}

[Serializable]
public class ClassWithInterface2 : ClassWithInterfaceBase
{
[LeftToggle]
public bool var1;
[InLineEditor]
public Material mat;
}

[Serializable]
Expand Down