#if UNITY_EDITOR // // douduck08: https://github.com/douduck08 // Use Reflection to get instance of Unity's SerializedProperty in Custom Editor. // Modified codes from 'Unity Answers', in order to apply on nested List or Array. // // Original author: HiddenMonk & Johannes Deml // Ref: http://answers.unity3d.com/questions/627090/convert-serializedproperty-to-custom-class.html // using System.Collections; using System.Linq; using System.Reflection; using System.Text.RegularExpressions; using UnityEditor; using UnityEngine; namespace FIMSpace.FEditor { public static class SerializedPropertyExtensions { public static T GetValue(this SerializedProperty property) where T : class { object obj = property.serializedObject.targetObject; string path = property.propertyPath.Replace(".Array.data", ""); string[] fieldStructure = path.Split('.'); Regex rgx = new Regex(@"\[\d+\]"); for (int i = 0; i < fieldStructure.Length; i++) { if (fieldStructure[i].Contains("[")) { int index = System.Convert.ToInt32(new string(fieldStructure[i].Where(c => char.IsDigit(c)).ToArray())); obj = GetFieldValueWithIndex(rgx.Replace(fieldStructure[i], ""), obj, index); } else { obj = GetFieldValue(fieldStructure[i], obj); } } return (T)obj; } public static bool SetValue(this SerializedProperty property, T value) where T : class { object obj = property.serializedObject.targetObject; string path = property.propertyPath.Replace(".Array.data", ""); string[] fieldStructure = path.Split('.'); Regex rgx = new Regex(@"\[\d+\]"); for (int i = 0; i < fieldStructure.Length - 1; i++) { if (fieldStructure[i].Contains("[")) { int index = System.Convert.ToInt32(new string(fieldStructure[i].Where(c => char.IsDigit(c)).ToArray())); obj = GetFieldValueWithIndex(rgx.Replace(fieldStructure[i], ""), obj, index); } else { obj = GetFieldValue(fieldStructure[i], obj); } } string fieldName = fieldStructure.Last(); if (fieldName.Contains("[")) { int index = System.Convert.ToInt32(new string(fieldName.Where(c => char.IsDigit(c)).ToArray())); return SetFieldValueWithIndex(rgx.Replace(fieldName, ""), obj, index, value); } else { Debug.Log(value); return SetFieldValue(fieldName, obj, value); } } private static object GetFieldValue(string fieldName, object obj, BindingFlags bindings = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) { FieldInfo field = obj.GetType().GetField(fieldName, bindings); if (field != null) { return field.GetValue(obj); } return default(object); } private static object GetFieldValueWithIndex(string fieldName, object obj, int index, BindingFlags bindings = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) { FieldInfo field = obj.GetType().GetField(fieldName, bindings); if (field != null) { object list = field.GetValue(obj); if (list.GetType().IsArray) { return ((object[])list)[index]; } else if (list is IEnumerable) { return ((IList)list)[index]; } } return default(object); } public static bool SetFieldValue(string fieldName, object obj, object value, bool includeAllBases = false, BindingFlags bindings = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) { FieldInfo field = obj.GetType().GetField(fieldName, bindings); if (field != null) { field.SetValue(obj, value); return true; } return false; } public static bool SetFieldValueWithIndex(string fieldName, object obj, int index, object value, bool includeAllBases = false, BindingFlags bindings = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) { FieldInfo field = obj.GetType().GetField(fieldName, bindings); if (field != null) { object list = field.GetValue(obj); if (list.GetType().IsArray) { ((object[])list)[index] = value; return true; } else if (value is IEnumerable) { ((IList)list)[index] = value; return true; } } return false; } } } #endif