Last active
September 16, 2019 06:54
-
-
Save Refsa/a7989687d74f935ca78c8e8fdf8d31b3 to your computer and use it in GitHub Desktop.
Getting the SerializedProperty of the actual object of a CustomPropertyDrawer, when the object is stored in a List
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using System.Text.RegularExpressions; | |
using UnityEditor; | |
public static class SerializedPropertyExtensions | |
{ | |
// Takes the property path and does a regex to find all the sub paths to reach the actual object, | |
// then follows the path to find the actual SerializedProperty | |
// | |
// Example of how a property path string looks like in an extreme use case: | |
// testClassList.Array.data[0].testClass2.testClass3List.Array.data[0].testClass4.testClass5 | |
public static SerializedProperty FindActualProperty (SerializedProperty property) | |
{ | |
// Regex to find different parts of property path | |
Regex regex = new Regex (@"((\w+).Array.data\[(\d)\]|\.?(\w+)\.?)"); | |
MatchCollection mc = regex.Matches (property.propertyPath); | |
var arrays = new List < (string, int) > ( ); | |
foreach (Match m in mc) | |
{ | |
if (m.Groups[4].Value != "") | |
arrays.Add ((m.Groups[4].Value, -1)); | |
else | |
arrays.Add ((m.Groups[2].Value, int.Parse (m.Groups[3].Value))); | |
} | |
// Go down the hierarchy from the containing SerializedObject | |
var prop = property.serializedObject.FindProperty (arrays[0].Item1); | |
if (arrays[0].Item2 != -1) | |
prop = prop.GetArrayElementAtIndex (arrays[0].Item2); | |
for (int i = 1; i < arrays.Count; i++) | |
{ | |
prop = prop.FindPropertyRelative (arrays[i].Item1); | |
if (arrays[i].Item2 != -1) | |
prop = prop.GetArrayElementAtIndex (arrays[i].Item2); | |
} | |
return prop; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using UnityEditor; | |
// A CustomPropertyDrawer to show how the above script is used | |
[CustomPropertyDrawer (typeof (TestClass4))] | |
public class TestPropertyDrawer : PropertyDrawer | |
{ | |
public override void OnGUI (Rect position, SerializedProperty property, GUIContent label) | |
{ | |
EditorGUI.BeginProperty (position, label, property); | |
var prop = SerializedPropertyExtensions.FindActualProperty (property); | |
EditorGUI.PropertyField (position, prop.FindPropertyRelative ("testField")); | |
EditorGUI.EndProperty ( ); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Example structure where the script would be helpful. When the actual object of the | |
// SerializedProperty is stored in a list, the SerializedProperty will link to the list | |
// and not the wanted object | |
using System.Collections.Generic; | |
using UnityEngine; | |
[CreateAssetMenu (menuName = "TestSO")] | |
public class TestSO : ScriptableObject | |
{ | |
public List<TestClass> testClassList = new List<TestClass> ( ); | |
} | |
[System.Serializable] | |
public class TestClass | |
{ | |
public TestClass2 testClass2; | |
} | |
[System.Serializable] | |
public class TestClass2 | |
{ | |
public List<TestClass3> testClass3List = new List<TestClass3> ( ); | |
} | |
[System.Serializable] | |
public class TestClass3 | |
{ | |
public TestClass4 testClass4; | |
} | |
[System.Serializable] | |
public class TestClass4 | |
{ | |
public float testField = 0f; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment