diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 0000000..94618b6
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,33 @@
+---
+name: Bug report
+about: Create a report to help us improve
+title: ''
+labels: ''
+assignees: ''
+
+---
+
+**Describe the bug**
+A clear and concise description of what the bug is.
+
+**To Reproduce**
+Steps to reproduce the behavior:
+1. Go to '...'
+2. Click on '....'
+3. Scroll down to '....'
+4. See error
+
+**Expected behavior**
+A clear and concise description of what you expected to happen.
+
+**Screenshots**
+If applicable, add screenshots to help explain your problem.
+
+**Desktop (please complete the following information):**
+ - OS: [e.g. Windows]
+
+**Unity (please complete the following information):**
+ - Version [e.g. 2021.3.2f1]
+
+**Additional context**
+Add any other context about the problem here.
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 0000000..bd16c81
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,20 @@
+---
+name: Feature request
+about: Suggest an idea for this project
+title: ''
+labels: ''
+assignees: Thundernerd
+
+---
+
+**Is your feature request related to a problem? Please describe.**
+A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
+
+**Describe the solution you'd like**
+A clear and concise description of what you want to happen.
+
+**Describe alternatives you've considered**
+A clear and concise description of any alternative solutions or features you've considered.
+
+**Additional context**
+Add any other context or screenshots about the feature request here.
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 0000000..6e03820
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,39 @@
+## Proposed changes
+
+Describe the big picture of your changes here to communicate to the maintainers why we should accept this pull request. If it fixes a bug or resolves a feature request, be sure to link to that issue.
+
+## Types of changes
+
+_Put an `x` in the boxes that apply._
+
+- [ ] Bugfix (non-breaking change which fixes an issue)
+- [ ] New feature (non-breaking change which adds functionality)
+- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
+- [ ] Refactoring (no functional changes, no api changes)
+- [ ] Code style update (formatting, renaming)
+- [ ] Build related changes (workflow changes)
+- [ ] Documentation Update (readme, changelog)
+- [ ] Other, please describe:
+
+
+## Issue
+Include a link to the issue if applicable, otherwise you can remove this section.
+
+## What is the current behavior?
+Please describe the current behavior that you are modifying.
+
+## What is the new behavior?
+Please describe the behavior or changes that are being added by this PR.
+
+## Checklist
+
+_Put an `x` in the boxes that apply._
+
+- [ ] The code compiles
+- [ ] I have tested that this doesn't break existing code (unless it is an explicit breaking change)
+- [ ] I have tested that the (new) functionality/fix works as intended
+- [ ] I have added necessary documentation (if appropriate)
+
+## Further comments
+
+If this is a relatively large or complex change, kick off the discussion by explaining why you chose the solution you did and what alternatives you considered, etc...
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d64f140..4032010 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,28 @@
+## [1.10.0](https://github.com/Thundernerd/Unity3D-SerializableInterface/compare/v1.9.0...v1.10.0) (2022-07-25)
+
+
+### Features
+
+* added methods for getting and setting values with serialized properties ([aba0c30](https://github.com/Thundernerd/Unity3D-SerializableInterface/commit/aba0c305b87ab843a3842d584a38d58487e61a89))
+* added passing serialized property to CustomObjectDrawer and Dropdown ([5913ab7](https://github.com/Thundernerd/Unity3D-SerializableInterface/commit/5913ab76e7759e2264a2979081972468dcae2f40))
+* added serialized property extensions for convenience ([547c892](https://github.com/Thundernerd/Unity3D-SerializableInterface/commit/547c89271c892ca1bfa14e30958437c379dc9853))
+
+### [1.9.0](https://github.com/Thundernerd/Unity3D-SerializableInterface/compare/v1.8.0...v1.9.0) (2202-07-23)
+
+
+### What's Changed
+* Added RawReferenceDrawer.Styles.cs + DrawLine - #41 by @marc-antoine-girard in https://github.com/Thundernerd/Unity3D-SerializableInterface/pull/42
+* ReferenceMode + AvoidDuplicateReferencesInArray by @marc-antoine-girard in https://github.com/Thundernerd/Unity3D-SerializableInterface/pull/43
+
+### [1.8.0](https://github.com/Thundernerd/Unity3D-SerializableInterface/compare/v1.7.3...v1.8.0) (2022-07-22)
+
+### What's Changed
+* fix: added null check to prevent null reference exception when clicking properties by @marc-antoine-girard in https://github.com/Thundernerd/Unity3D-SerializableInterface/pull/23
+* #24 add none option custom drawers by @marc-antoine-girard in https://github.com/Thundernerd/Unity3D-SerializableInterface/pull/26
+* Fixed Drag and Drop behaviour by @marc-antoine-girard in https://github.com/Thundernerd/Unity3D-SerializableInterface/pull/28
+* Fixes #25 SerializableInterface maintains instances when set by Inspector by @marc-antoine-girard in https://github.com/Thundernerd/Unity3D-SerializableInterface/pull/27
+* #34 add prefabs assets item builder by @marc-antoine-girard in https://github.com/Thundernerd/Unity3D-SerializableInterface/pull/35
+
### [1.7.3](https://github.com/Thundernerd/Unity3D-SerializableInterface/compare/v1.7.2...v1.7.3) (2022-07-22)
diff --git a/Editor/Drawers/CustomObjectDrawer.cs b/Editor/Drawers/CustomObjectDrawer.cs
index 5b6b27e..09697bb 100644
--- a/Editor/Drawers/CustomObjectDrawer.cs
+++ b/Editor/Drawers/CustomObjectDrawer.cs
@@ -5,13 +5,13 @@ namespace TNRD.Drawers
{
public partial class CustomObjectDrawer
{
- public delegate void ButtonClickedDelegate(Rect position);
+ public delegate void ButtonClickedDelegate(Rect position, SerializedProperty property);
- public delegate void ClickedDelegate();
+ public delegate void ClickedDelegate(SerializedProperty property);
- public delegate void DeletePressedDelegate();
+ public delegate void DeletePressedDelegate(SerializedProperty property);
- public delegate void PropertiesClickedDelegate();
+ public delegate void PropertiesClickedDelegate(SerializedProperty property);
private bool isSelected;
@@ -21,18 +21,18 @@ public partial class CustomObjectDrawer
public event ClickedDelegate Clicked;
public event DeletePressedDelegate DeletePressed;
public event PropertiesClickedDelegate PropertiesClicked;
-
- public void OnGUI(Rect position, GUIContent label, GUIContent content)
+
+ public void OnGUI(Rect position, GUIContent label, GUIContent content, SerializedProperty property)
{
Rect positionWithoutThumb = new Rect(position);
positionWithoutThumb.xMax -= 20;
position = DrawPrefixLabel(position, label);
DrawObjectField(position, content);
- DrawButton(position);
+ DrawButton(position, property);
- HandleMouseDown(position, positionWithoutThumb);
- HandleKeyDown();
+ HandleMouseDown(position, positionWithoutThumb, property);
+ HandleKeyDown(property);
}
private Rect DrawPrefixLabel(Rect position, GUIContent label)
@@ -66,7 +66,7 @@ private void ForceRepaintEditors()
}
}
- private void DrawButton(Rect position)
+ private void DrawButton(Rect position, SerializedProperty property)
{
Rect buttonRect = new Rect(position);
buttonRect.yMin += 1;
@@ -76,11 +76,11 @@ private void DrawButton(Rect position)
if (GUI.Button(buttonRect, string.Empty, "objectFieldButton"))
{
- ButtonClicked?.Invoke(position);
+ ButtonClicked?.Invoke(position, property);
}
}
- private void HandleMouseDown(Rect position, Rect positionWithoutThumb)
+ private void HandleMouseDown(Rect position, Rect positionWithoutThumb, SerializedProperty property)
{
if (Event.type != EventType.MouseDown)
return;
@@ -89,26 +89,26 @@ private void HandleMouseDown(Rect position, Rect positionWithoutThumb)
{
isSelected = positionWithoutThumb.Contains(Event.mousePosition);
ForceRepaintEditors();
- Clicked?.Invoke();
+ Clicked?.Invoke(property);
}
else if (Event.button == 1 && positionWithoutThumb.Contains(Event.mousePosition))
{
GenericMenu menu = new GenericMenu();
- menu.AddItem(new GUIContent("Clear"), false, () => { DeletePressed?.Invoke(); });
- menu.AddItem(new GUIContent("Properties..."), false, () => { PropertiesClicked?.Invoke(); });
+ menu.AddItem(new GUIContent("Clear"), false, () => { DeletePressed?.Invoke(property); });
+ menu.AddItem(new GUIContent("Properties..."), false, () => { PropertiesClicked?.Invoke(property); });
menu.DropDown(position);
Event.Use();
}
}
- private void HandleKeyDown()
+ private void HandleKeyDown(SerializedProperty property)
{
if (!isSelected)
return;
if (Event.type == EventType.KeyDown && Event.keyCode == KeyCode.Delete)
{
- DeletePressed?.Invoke();
+ DeletePressed?.Invoke(property);
}
}
}
diff --git a/Editor/Drawers/RawReferenceDrawer.cs b/Editor/Drawers/RawReferenceDrawer.cs
index 23b9348..6ff5eaf 100644
--- a/Editor/Drawers/RawReferenceDrawer.cs
+++ b/Editor/Drawers/RawReferenceDrawer.cs
@@ -45,7 +45,7 @@ public void OnGUI(Rect position)
? EditorGUIUtility.ObjectContent((MonoScript)null, typeof(MonoScript))
: new GUIContent(rawReferenceValue.GetType().Name, IconUtility.ScriptIcon);
- CustomObjectDrawer.OnGUI(objectFieldRect, label, content);
+ CustomObjectDrawer.OnGUI(objectFieldRect, label, content, Property);
HandleDragAndDrop(objectFieldRect);
@@ -79,13 +79,13 @@ private void DrawLine(Rect position)
EditorGUI.DrawRect(line, Styles.LineColor);
}
- protected override void PingObject()
+ protected override void PingObject(SerializedProperty property)
{
// No support for pinging raw objects for now (I guess this would ping the MonoScript?)
}
///
- protected override void OnPropertiesClicked()
+ protected override void OnPropertiesClicked(SerializedProperty property)
{
if (RawReferenceValue == null)
return;
diff --git a/Editor/Drawers/ReferenceDrawer.cs b/Editor/Drawers/ReferenceDrawer.cs
index 56456fd..85e4010 100644
--- a/Editor/Drawers/ReferenceDrawer.cs
+++ b/Editor/Drawers/ReferenceDrawer.cs
@@ -27,69 +27,28 @@ private enum DragAndDropMode
protected SerializedProperty Property { get; private set; }
protected Type GenericType { get; private set; }
- protected SerializedProperty ReferenceModeProperty => Property.FindPropertyRelative("mode");
- protected SerializedProperty RawReferenceProperty => Property.FindPropertyRelative("rawReference");
- protected SerializedProperty UnityReferenceProperty => Property.FindPropertyRelative("unityReference");
+ protected SerializedProperty ReferenceModeProperty => Property.ReferenceModeProperty();
+ protected SerializedProperty RawReferenceProperty => Property.RawReferenceProperty();
+ protected SerializedProperty UnityReferenceProperty => Property.UnityReferenceProperty();
protected FieldInfo FieldInfo { get; private set; }
protected ReferenceMode ModeValue
{
- get => (ReferenceMode)ReferenceModeProperty.enumValueIndex;
- set => ReferenceModeProperty.enumValueIndex = (int)value;
+ get => GetModeValue(Property);
+ set => SetModeValue(Property, value);
}
protected object RawReferenceValue
{
- get
- {
-#if UNITY_2021_1_OR_NEWER
- return RawReferenceProperty.managedReferenceValue;
-#else
- ISerializableInterface instance =
- (ISerializableInterface)FieldInfo.GetValue(Property.serializedObject.targetObject);
- return instance.GetRawReference();
-#endif
- }
- set
- {
-#if UNITY_2021_1_OR_NEWER
- RawReferenceProperty.managedReferenceValue = value;
-#else
- FieldInfo.SetValue(Property.serializedObject.targetObject, value);
-#endif
- }
+ get => GetRawReferenceValue(Property);
+ set => SetRawReferenceValue(Property, value);
}
protected object PropertyValue
{
- get
- {
- return ModeValue switch
- {
- ReferenceMode.Raw => RawReferenceValue,
- ReferenceMode.Unity => UnityReferenceProperty.objectReferenceValue,
- _ => throw new ArgumentOutOfRangeException()
- };
- }
- set
- {
- switch (ModeValue)
- {
- case ReferenceMode.Raw:
- RawReferenceValue = value;
- UnityReferenceProperty.objectReferenceValue = null;
- break;
- case ReferenceMode.Unity:
- UnityReferenceProperty.objectReferenceValue = GetUnityObject((Object)value);
- RawReferenceValue = null;
- break;
- default:
- throw new ArgumentOutOfRangeException();
- }
-
- Property.serializedObject.ApplyModifiedProperties();
- }
+ get => GetPropertyValue(Property);
+ set => SetPropertyValue(Property, value);
}
protected ReferenceDrawer()
@@ -108,18 +67,18 @@ protected void Initialize(SerializedProperty property, Type genericType, FieldIn
FieldInfo = fieldInfo;
}
- private void OnButtonClicked(Rect position)
+ private void OnButtonClicked(Rect position, SerializedProperty property)
{
AdvancedDropdownState state = new AdvancedDropdownState();
SerializableInterfaceAdvancedDropdown dropdown =
- new SerializableInterfaceAdvancedDropdown(state, GenericType, GetRelevantScene());
+ new SerializableInterfaceAdvancedDropdown(state, GenericType, GetRelevantScene(property), property);
dropdown.ItemSelectedEvent += OnItemSelected;
dropdown.Show(position);
}
- private Scene? GetRelevantScene()
+ private static Scene? GetRelevantScene(SerializedProperty property)
{
- Object target = Property.serializedObject.targetObject;
+ Object target = property.serializedObject.targetObject;
if (target is ScriptableObject)
return null;
@@ -131,30 +90,30 @@ private void OnButtonClicked(Rect position)
return null;
}
- private void OnClicked()
+ private void OnClicked(SerializedProperty property)
{
- PingObject();
+ PingObject(property);
}
- private void OnDeletePressed()
+ private void OnDeletePressed(SerializedProperty property)
{
- ModeValue = default;
- PropertyValue = null;
+ SetModeValue(property, default);
+ SetPropertyValue(property, null);
}
- private void OnItemSelected(ReferenceMode mode, object reference)
+ private void OnItemSelected(SerializedProperty property, ReferenceMode mode, object reference)
{
- ModeValue = mode;
- PropertyValue = reference;
+ SetModeValue(property, mode);
+ SetPropertyValue(property, reference);
}
- protected abstract void OnPropertiesClicked();
+ protected abstract void OnPropertiesClicked(SerializedProperty property);
protected void HandleDragAndDrop(Rect position)
{
if (!position.Contains(Event.current.mousePosition))
return;
-
+
if (Event.current.type == EventType.DragPerform)
{
HandleDragUpdated();
@@ -241,11 +200,80 @@ private void HandleDragPerform()
private Object GetUnityObject(Object objectReference)
{
- if(objectReference is GameObject gameObject)
+ if (objectReference is GameObject gameObject)
return gameObject.GetComponent(GenericType);
return objectReference;
}
- protected abstract void PingObject();
+ protected abstract void PingObject(SerializedProperty property);
+
+ protected ReferenceMode GetModeValue(SerializedProperty property)
+ {
+ return (ReferenceMode)property.ReferenceModeProperty().enumValueIndex;
+ }
+
+ protected void SetModeValue(SerializedProperty property, ReferenceMode mode)
+ {
+ property.ReferenceModeProperty().enumValueIndex = (int)mode;
+ }
+
+ protected object GetRawReferenceValue(SerializedProperty property)
+ {
+#if UNITY_2021_1_OR_NEWER
+ return property.RawReferenceProperty().managedReferenceValue;
+#else
+ ISerializableInterface instance =
+ (ISerializableInterface)FieldInfo.GetValue(property.serializedObject.targetObject);
+ return instance.GetRawReference();
+#endif
+ }
+
+ protected void SetRawReferenceValue(SerializedProperty property, object value)
+ {
+#if UNITY_2021_1_OR_NEWER
+ property.RawReferenceProperty().managedReferenceValue = value;
+#else
+ FieldInfo.SetValue(property.serializedObject.targetObject, value);
+#endif
+ }
+
+ protected Object GetUnityReferenceValue(SerializedProperty property)
+ {
+ return property.UnityReferenceProperty().objectReferenceValue;
+ }
+
+ protected void SetUnityReferenceValue(SerializedProperty property, object value)
+ {
+ property.UnityReferenceProperty().objectReferenceValue = GetUnityObject((Object)value);
+ }
+
+ protected object GetPropertyValue(SerializedProperty property)
+ {
+ return GetModeValue(property) switch
+ {
+ ReferenceMode.Raw => GetRawReferenceValue(property),
+ ReferenceMode.Unity => GetUnityReferenceValue(property),
+ _ => throw new ArgumentOutOfRangeException()
+ };
+ }
+
+ protected void SetPropertyValue(SerializedProperty property, object value)
+ {
+ switch (GetModeValue(property))
+ {
+ case ReferenceMode.Unity:
+ SetUnityReferenceValue(property, value);
+ SetRawReferenceValue(property, null);
+ break;
+ case ReferenceMode.Raw:
+ SetRawReferenceValue(property, value);
+ SetUnityReferenceValue(property, null);
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+
+ property.serializedObject.ApplyModifiedProperties();
+ }
}
}
diff --git a/Editor/Drawers/UnityReferenceDrawer.cs b/Editor/Drawers/UnityReferenceDrawer.cs
index 45a8893..3886f27 100644
--- a/Editor/Drawers/UnityReferenceDrawer.cs
+++ b/Editor/Drawers/UnityReferenceDrawer.cs
@@ -27,18 +27,18 @@ public void OnGUI(Rect position)
Object unityReference = UnityReferenceProperty.objectReferenceValue;
Type referenceType = unityReference == null ? typeof(Object) : unityReference.GetType();
GUIContent objectContent = EditorGUIUtility.ObjectContent(unityReference, referenceType);
- CustomObjectDrawer.OnGUI(position, label, objectContent);
+ CustomObjectDrawer.OnGUI(position, label, objectContent, Property);
HandleDragAndDrop(position);
}
- protected override void PingObject()
+ protected override void PingObject(SerializedProperty property)
{
- EditorGUIUtility.PingObject((Object)PropertyValue);
+ EditorGUIUtility.PingObject((Object)GetPropertyValue(property));
}
- protected override void OnPropertiesClicked()
+ protected override void OnPropertiesClicked(SerializedProperty property)
{
- PropertyEditorUtility.Show(UnityReferenceProperty.objectReferenceValue);
+ PropertyEditorUtility.Show(property.UnityReferenceProperty().objectReferenceValue);
}
}
}
diff --git a/Editor/Utilities/SerializableInterfaceAdvancedDropdown.cs b/Editor/Utilities/SerializableInterfaceAdvancedDropdown.cs
index 923d03a..bae1c81 100644
--- a/Editor/Utilities/SerializableInterfaceAdvancedDropdown.cs
+++ b/Editor/Utilities/SerializableInterfaceAdvancedDropdown.cs
@@ -3,6 +3,7 @@
using System.Reflection;
using TNRD.Builders;
using TNRD.Items;
+using UnityEditor;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
using UnityEngine.Assertions;
@@ -16,8 +17,9 @@ internal sealed class SerializableInterfaceAdvancedDropdown : AdvancedDropdown
private readonly MethodInfo sortChildrenMethod;
private readonly bool canSort;
private readonly Scene? relevantScene;
+ private readonly SerializedProperty property;
- public delegate void ItemSelectedDelegate(ReferenceMode mode, object reference);
+ public delegate void ItemSelectedDelegate(SerializedProperty property, ReferenceMode mode, object reference);
public event ItemSelectedDelegate ItemSelectedEvent; // Suffixed with Event because of the override
@@ -25,7 +27,8 @@ internal sealed class SerializableInterfaceAdvancedDropdown : AdvancedDropdown
public SerializableInterfaceAdvancedDropdown(
AdvancedDropdownState state,
Type interfaceType,
- Scene? relevantScene
+ Scene? relevantScene,
+ SerializedProperty property
)
: base(state)
{
@@ -38,6 +41,7 @@ public SerializableInterfaceAdvancedDropdown(
minimumSize = new Vector2(0, 300);
this.interfaceType = interfaceType;
this.relevantScene = relevantScene;
+ this.property = property;
}
///
@@ -52,7 +56,7 @@ protected override AdvancedDropdownItem BuildRoot()
{
dropdownItem.AddChild(new NoneDropdownItem());
}
-
+
if (canSort)
{
sortChildrenMethod.Invoke(item,
@@ -72,7 +76,7 @@ private int Sort(AdvancedDropdownItem a, AdvancedDropdownItem b)
return -1;
if (b is NoneDropdownItem)
return 1;
-
+
int childrenA = a.children.Count();
int childrenB = b.children.Count();
@@ -90,7 +94,7 @@ protected override void ItemSelected(AdvancedDropdownItem item)
{
if (item is IDropdownItem dropdownItem)
{
- ItemSelectedEvent?.Invoke(dropdownItem.Mode, dropdownItem.GetValue());
+ ItemSelectedEvent?.Invoke(property, dropdownItem.Mode, dropdownItem.GetValue());
}
}
}
diff --git a/Editor/Utilities/SerializedPropertyExtensions.cs b/Editor/Utilities/SerializedPropertyExtensions.cs
new file mode 100644
index 0000000..7043e2e
--- /dev/null
+++ b/Editor/Utilities/SerializedPropertyExtensions.cs
@@ -0,0 +1,22 @@
+using UnityEditor;
+
+namespace TNRD.Utilities
+{
+ internal static class SerializedPropertyExtensions
+ {
+ public static SerializedProperty ReferenceModeProperty(this SerializedProperty property)
+ {
+ return property.FindPropertyRelative("mode");
+ }
+
+ public static SerializedProperty RawReferenceProperty(this SerializedProperty property)
+ {
+ return property.FindPropertyRelative("rawReference");
+ }
+
+ public static SerializedProperty UnityReferenceProperty(this SerializedProperty property)
+ {
+ return property.FindPropertyRelative("unityReference");
+ }
+ }
+}
diff --git a/Editor/Utilities/SerializedPropertyExtensions.cs.meta b/Editor/Utilities/SerializedPropertyExtensions.cs.meta
new file mode 100644
index 0000000..f9fcc92
--- /dev/null
+++ b/Editor/Utilities/SerializedPropertyExtensions.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 8bfd876a31f9470b802c64d4f1a8dd37
+timeCreated: 1658567318
\ No newline at end of file
diff --git a/package.json b/package.json
index c6c90e6..2f8703a 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "net.tnrd.serializableinterface",
- "version": "1.9.0",
+ "version": "1.10.0",
"displayName": "Serializable Interface",
"unity": "2020.1",
"description": "A wrapper that allows serialization of interfaces that supports both UnityEngine.Object and regular object types",