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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ All package updates & migration steps will be listed in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [4.2.1] - 2024-11-19
### Fixed
- Issue where nested structs in scriptable object drawers have glitching UI.
- Disable autosaving toggle wasn't fully disabling.

## [4.2.0] - 2024-10-31
### Added
- Additional checks during parameter generation to ensure the generated code matches.
Expand Down
8 changes: 4 additions & 4 deletions Editor/Editor/InspectorAutoSave.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ private static void Update()

if (s_target != null)
{
if (s_dirtyStopWatch.IsRunning && s_dirtyStopWatch.ElapsedMilliseconds < SaveDelayMillis)
return;

SaveAsset();
if (s_dirtyStopWatch.IsRunning && s_dirtyStopWatch.ElapsedMilliseconds >= SaveDelayMillis)
{
SaveAsset();
}
}
}

Expand Down
36 changes: 34 additions & 2 deletions Editor/Editor/ParamProperty.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using UnityEditor;
using UnityEngine;
Expand Down Expand Up @@ -48,6 +49,8 @@ public ScriptableObject ScriptableObject
}
}

public SerializedObject SerializedScriptableObject => _serializedScriptableObject;

/// <summary>
/// Current position if the property is part of a list or array. Null otherwise.
/// </summary>
Expand All @@ -60,6 +63,20 @@ public ScriptableObject ScriptableObject

private readonly SerializedProperty _guidProperty;

/*
* Unity recommended we cache our SerializedObject to avoid GUI glitches.
*
* Unity's response:
* Regarding the issue of Serializable fields becoming unselectable originates from your custom
* property drawer. Our investigation revealed that parts of IMGUI, including the ReorderableList,
* are stateful. This means they retain data about the SerializedObject and SerializedProperties.
* In your property drawer, you are generating a new SerializedObject each time and disposing of it
* immediately. This process invalidates the state, causing multiple drawings of the list and
* disrupting input states.
*/
private readonly SerializedObject _serializedScriptableObject;
private static Dictionary<string, SerializedObject> s_serializedScriptableObjectByGuid = new ();

public ParamProperty(FieldInfo fieldInfo, SerializedProperty property)
{
Property = property;
Expand All @@ -86,14 +103,29 @@ public ParamProperty(FieldInfo fieldInfo, SerializedProperty property)

if (!string.IsNullOrWhiteSpace(GUID))
{
if (ScriptableObject == null)
var scriptableObject = ScriptableObject;
if (scriptableObject == null)
{
Error = $"Missing asset {GUID}";
}
else if (!InterfaceType.IsInstanceOfType(ScriptableObject))
else if (!InterfaceType.IsInstanceOfType(scriptableObject))
{
Error = $"Asset no longer matches generic type {InterfaceType}";
}
else
{
if (!s_serializedScriptableObjectByGuid.TryGetValue(GUID, out var serializedScriptableObject))
{
serializedScriptableObject = new SerializedObject(scriptableObject);
s_serializedScriptableObjectByGuid[GUID] = serializedScriptableObject;
}
else
{
// call to ensure the values are up to date with the target in case it was modified in another inspector/drawer
serializedScriptableObject.Update();
}
_serializedScriptableObject = serializedScriptableObject;
}
}
}
}
Expand Down
26 changes: 12 additions & 14 deletions Editor/Editor/ParameterReferenceDrawer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ private float InnerInspectorHeight(ParamProperty paramProperty, SerializedProper
return 0;

float height = 0;
var serializedObject = new SerializedObject(paramProperty.ScriptableObject);
var serializedObject = paramProperty.SerializedScriptableObject;
var prop = serializedObject.GetIterator();
bool children = true;
while (prop.NextVisible(children))
Expand All @@ -160,7 +160,6 @@ private float InnerInspectorHeight(ParamProperty paramProperty, SerializedProper
height += EditorGUI.GetPropertyHeight(prop, new GUIContent(prop.displayName), true);
height += EditorGUIUtility.standardVerticalSpacing;
}
serializedObject.Dispose();
return height;
}

Expand Down Expand Up @@ -206,18 +205,18 @@ private bool DrawGUI(Rect position, SerializedProperty property, ParamProperty p
objectFieldPosition.y, newButtonWidth, objectFieldPosition.height);
objectFieldPosition.width -= newButtonWidth;
EditorGUI.BeginChangeCheck();
bool objectChanged = false;
newObject = null;
// object field
var scriptableObject = paramProperty.ScriptableObject;
var fieldObject = EditorGUI.ObjectField(objectFieldPosition, scriptableObject, GetImplementingType(paramProperty.InterfaceType), false);
if (EditorGUI.EndChangeCheck())
{
// this means the user interacted and set the value on the field
// this helps determine if the user deliberately an object or nulled the field.
objectChanged = true;
// this helps determine if the user deliberately set an object or nulled the field.
newObject = fieldObject as ParameterScriptableObject;
scriptableObject = newObject;

// return early so that the ParamProperty can be updated with the correct scriptable object
return true;
}

if (GUI.Button(buttonRect, "New"))
Expand Down Expand Up @@ -250,9 +249,10 @@ private bool DrawGUI(Rect position, SerializedProperty property, ParamProperty p
{
var createdObject = ScriptableObject.CreateInstance(parameterInterface.ScriptableObjectType());
AssetDatabase.CreateAsset(createdObject, savePath);
objectChanged = true;
scriptableObject = createdObject;
newObject = createdObject as ParameterScriptableObject;

// return early so that the ParamProperty can be updated with the correct scriptable object
return true;
}
}

Expand Down Expand Up @@ -281,8 +281,7 @@ private bool DrawGUI(Rect position, SerializedProperty property, ParamProperty p
}
else if (canExpandDrawer && property.isExpanded)
{
var serializedObject = new SerializedObject(scriptableObject);
var prop = serializedObject.GetIterator();
var prop = paramProperty.SerializedScriptableObject.GetIterator();
EditorGUI.indentLevel++;
bool children = true;
while (prop.NextVisible(children))
Expand All @@ -307,7 +306,7 @@ private bool DrawGUI(Rect position, SerializedProperty property, ParamProperty p
{
height = EditorGUI.GetPropertyHeight(prop, propLabel, true);
position.height = height;
DrawExpandedField(serializedObject, position, prop, propLabel);
DrawExpandedField(paramProperty.SerializedScriptableObject, position, prop, propLabel);
}
position.y += height + EditorGUIUtility.standardVerticalSpacing;
}
Expand All @@ -322,10 +321,9 @@ private bool DrawGUI(Rect position, SerializedProperty property, ParamProperty p
*/
if (GUI.changed)
{
serializedObject.ApplyModifiedProperties();
paramProperty.SerializedScriptableObject.ApplyModifiedProperties();
InspectorAutoSave.DispatchDelayedSave();
}
serializedObject.Dispose();
}

if (paramProperty.ElementPosition.HasValue)
Expand All @@ -336,7 +334,7 @@ private bool DrawGUI(Rect position, SerializedProperty property, ParamProperty p
s_firstTargetObject = null;
}

return objectChanged;
return false;
}

/// <summary>
Expand Down
4 changes: 3 additions & 1 deletion Editor/Editor/ParameterScriptableObjectInspector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,9 @@ public override void OnInspectorGUI()
}

// collect properties & errors
List<(SerializedProperty, string)> properties = new List<(SerializedProperty, string)>();
List<(SerializedProperty, string)> properties = new();
// call to ensure the values are up to date with the target in case it was modified in another inspector/drawer
serializedObject.Update();
var serializedProp = serializedObject.GetIterator();
bool children = true;
while (serializedProp.NextVisible(children))
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "com.pocketgems.scriptableobject.flatbuffer",
"version": "4.2.0",
"version": "4.2.1",
"displayName": "Scriptable Object - FlatBuffer",
"description": "Seamless syncing between Scriptable Objects and CSVs. Scriptable Object data built to Google FlatBuffers for optimal runtime loading & access.",
"unity": "2021.3",
Expand Down
Loading