Skip to content

Instantly share code, notes, and snippets.

@monry
Created August 21, 2020 15:54
Show Gist options
  • 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]);
                }
            }

@Enamul-Islam-Jisan
Copy link

To get index in parent

public static int GetIndexInParent(this SerializedProperty serializedProperty)
{
    SerializedProperty parent = serializedProperty.FindParentProperty();
    if (parent != serializedProperty)
    {
        for (int i = 0; i < parent.arraySize; i++)
        {
            var prop = parent.GetArrayElementAtIndex(i);
            if (SerializedProperty.EqualContents(prop, serializedProperty))
                return i;
        }
    }
    return -1;
}

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