Files
Unity-Serializable-Func/Editor/Extensions/SerializedProperty/SerializedPropertyExtensions.cs

146 lines
5.6 KiB
C#

#if UNITY_EDITOR
using System.Collections;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
namespace SerializableFunc.Editor.Extensions.SerializedProperty
{
public static class SerializedPropertyExtensions
{
static readonly Regex rgx = new Regex(@"\[\d+\]", RegexOptions.Compiled);
public static object GetBoxedValue(this UnityEditor.SerializedProperty property)
{
property.serializedObject.ApplyModifiedProperties();
#if UNITY_2023_2_OR_NEWER
return property.boxedValue;
#else
return GetValue<object>(property);
#endif
}
public static void SetBoxedValue(this UnityEditor.SerializedProperty property, object value)
{
property.serializedObject.Update();
#if UNITY_2023_2_OR_NEWER
property.boxedValue = value;
#else
SetValue<object>(property, value);
#endif
property.serializedObject.ApplyModifiedProperties();
}
public static T GetValue<T>(this UnityEditor.SerializedProperty property) where T : class
{
object obj = property.serializedObject.targetObject;
string path = property.propertyPath.Replace(".Array.data", string.Empty);
string[] fieldStructure = path.Split('.');
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], string.Empty), obj, index);
}
else
{
obj = GetFieldValue(fieldStructure[i], obj);
}
}
return (T)obj;
}
public static bool SetValue<T>(this UnityEditor.SerializedProperty property, T value) where T : class
{
object obj = property.serializedObject.targetObject;
string path = property.propertyPath.Replace(".Array.data", "");
string[] fieldStructure = path.Split('.');
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
{
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 (list is IEnumerable)
{
((IList)list)[index] = value;
return true;
}
}
return false;
}
}
}
#endif