using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace MoreMountains.Tools
{
///
/// Serialized property extensions
///
public static class MMSerializedPropertyExtensions
{
#if UNITY_EDITOR
///
/// Returns the object value of a target serialized property
///
///
///
public static object MMGetObjectValue(this SerializedProperty property)
{
if (property == null)
{
return null;
}
string propertyPath = property.propertyPath.Replace(".Array.data[", "[");
object targetObject = property.serializedObject.targetObject;
var elements = propertyPath.Split('.');
foreach (var element in elements)
{
if (!element.Contains("["))
{
targetObject = GetPropertyValue(targetObject, element);
}
else
{
string elementName = element.Substring(0, element.IndexOf("["));
int elementIndex = System.Convert.ToInt32(element.Substring(element.IndexOf("[")).Replace("[", "").Replace("]", ""));
targetObject = GetPropertyValue(targetObject, elementName, elementIndex);
}
}
return targetObject;
}
private static object GetPropertyValue(object source, string propertyName)
{
if (source == null)
{
return null;
}
Type propertyType = source.GetType();
while (propertyType != null)
{
FieldInfo fieldInfo = propertyType.GetField(propertyName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
if (fieldInfo != null)
{
return fieldInfo.GetValue(source);
}
PropertyInfo propertyInfo = propertyType.GetProperty(propertyName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.IgnoreCase | BindingFlags.Instance);
if (propertyInfo != null)
{
return propertyInfo.GetValue(source, null);
}
propertyType = propertyType.BaseType;
}
return null;
}
private static object GetPropertyValue(object source, string propertyName, int index)
{
var enumerable = GetPropertyValue(source, propertyName) as System.Collections.IEnumerable;
if (enumerable == null)
{
return null;
}
var enumerator = enumerable.GetEnumerator();
for (int i = 0; i <= index; i++)
{
if (!enumerator.MoveNext())
{
return null;
}
}
return enumerator.Current;
}
#endif
}
}