Skip to content
Merged
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
56 changes: 54 additions & 2 deletions Scripts/Editor/Extensions/SerializedPropertyExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,55 @@ public static FieldInfo GetFieldInfoFromPathByType(this SerializedProperty prope

return fieldInfo;
}
public static void SetValue(this SerializedProperty serializedProperty, object value)

Copy link

Copilot AI May 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Public extension methods should have XML doc comments. Please add a summary and parameter descriptions for SetValueReflective.

Suggested change
/// <summary>
/// Sets the value of a serialized property reflectively by traversing its property path.
/// </summary>
/// <param name="prop">The serialized property whose value is to be set.</param>
/// <param name="value">The new value to assign to the property.</param>

Copilot uses AI. Check for mistakes.
public static void SetValueReflective(this SerializedProperty prop, object value)
{
object root = prop.serializedObject.targetObject;

string[] parts = prop.propertyPath
.Replace(".Array.data[", "[")
.Split('.');
Comment on lines +36 to +38
Copy link

Copilot AI May 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Parsing the propertyPath using hard-coded replace/split logic can be brittle. Consider extracting the path parsing into a helper or adding comments to clarify the expected formats.

Suggested change
string[] parts = prop.propertyPath
.Replace(".Array.data[", "[")
.Split('.');
string[] parts = ParsePropertyPath(prop.propertyPath);

Copilot uses AI. Check for mistakes.

object current = root;
FieldInfo fi = null;

for (int i = 0; i < parts.Length; i++)
{
string part = parts[i];

if (part.EndsWith("]"))
{
int b = part.IndexOf('[');
string name = part.Substring(0, b);
int idx = int.Parse(part.Substring(b + 1, part.Length - b - 2));

fi = current.GetType()
.GetField(name,
BindingFlags.Instance
| BindingFlags.NonPublic
| BindingFlags.Public);
IList list = fi.GetValue(current) as System.Collections.IList;
current = list[idx];
}
else
{
fi = current.GetType()
.GetField(part,
BindingFlags.Instance
| BindingFlags.NonPublic
| BindingFlags.Public);
if (i < parts.Length - 1)
current = fi.GetValue(current);
}
}

fi.SetValue(current, value);

prop.serializedObject.Update();
prop.serializedObject.ApplyModifiedProperties();
Comment on lines +75 to +76
Copy link

Copilot AI May 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Calling Update() and ApplyModifiedProperties() inside the reflective setter may lead to repeated serialization passes when setting multiple properties. It might be more efficient to push these calls to the caller.

Suggested change
prop.serializedObject.Update();
prop.serializedObject.ApplyModifiedProperties();
// Note: The caller is responsible for calling `Update()` and `ApplyModifiedProperties()`
// on the `SerializedObject` to apply changes and update the serialized state.

Copilot uses AI. Check for mistakes.
}

public static void SetValue(this SerializedProperty serializedProperty, object value) {
switch (serializedProperty.propertyType)
{
case SerializedPropertyType.Integer:
Expand Down Expand Up @@ -106,6 +152,12 @@ public static void SetValue(this SerializedProperty serializedProperty, object v
case SerializedPropertyType.Hash128:
serializedProperty.hash128Value = (Hash128)value;
break;
case SerializedPropertyType.ManagedReference:
serializedProperty.managedReferenceValue = value;
break;
case SerializedPropertyType.Generic:
serializedProperty.SetValueReflective(value);
break;
default:
Debug.LogWarning(
$"Tried to copy value '{value}' from a template to an SOC item but apparently that's not supported.");
Expand Down