Skip to content

Instantly share code, notes, and snippets.

@monry
Created August 21, 2020 15:54
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save monry/9de7009689cbc5050c652bcaaaa11daa to your computer and use it in GitHub Desktop.
Save monry/9de7009689cbc5050c652bcaaaa11daa to your computer and use it in GitHub Desktop.
Find parent SerializedProperty
using System.Linq;
using System.Text.RegularExpressions;
using UnityEditor;
namespace Monry
{
public static class SerializedPropertyExtensions
{
public static SerializedProperty FindParentProperty(this SerializedProperty serializedProperty)
{
var propertyPaths = serializedProperty.propertyPath.Split('.');
if (propertyPaths.Length <= 1)
{
return default;
}
var parentSerializedProperty = serializedProperty.serializedObject.FindProperty(propertyPaths.First());
for (var index = 1; index < propertyPaths.Length - 1; index++)
{
if (propertyPaths[index] == "Array" && propertyPaths.Length > index + 1 && Regex.IsMatch(propertyPaths[index + 1], "^data\\[\\d+\\]$"))
{
var match = Regex.Match(propertyPaths[index + 1], "^data\\[(\\d+)\\]$");
var arrayIndex = int.Parse(match.Groups[1].Value);
parentSerializedProperty = parentSerializedProperty.GetArrayElementAtIndex(arrayIndex);
index++;
}
else
{
parentSerializedProperty = parentSerializedProperty.FindPropertyRelative(propertyPaths[index]);
}
}
return parentSerializedProperty;
}
}
}
@thebne
Copy link

thebne commented Oct 17, 2021

this won't work if a middle element is an array (always returns it). fix:

            for (var index = 1; index < propertyPaths.Length - 1; index++)
            {
                if (propertyPaths[index] == "Array")
                {
                    if (index + 1 == propertyPaths.Length - 1)
                    {
                        // reached the end
                        break;
                    }
                    if (propertyPaths.Length > index + 1 && Regex.IsMatch(propertyPaths[index + 1], "^data\\[\\d+\\]$"))
                    {
                        var match = Regex.Match(propertyPaths[index + 1], "^data\\[(\\d+)\\]$");
                        var arrayIndex = int.Parse(match.Groups[1].Value);
                        parentSerializedProperty = parentSerializedProperty.GetArrayElementAtIndex(arrayIndex);
                        index++;
                    }
                }
                else
                {
                    parentSerializedProperty = parentSerializedProperty.FindPropertyRelative(propertyPaths[index]);
                }
            }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment