Skip to content

Instantly share code, notes, and snippets.

@thebne
Last active October 26, 2021 16:07
Show Gist options
  • Save thebne/6d2dd5e0e54776b38b240a5d59086a6f to your computer and use it in GitHub Desktop.
Save thebne/6d2dd5e0e54776b38b240a5d59086a6f to your computer and use it in GitHub Desktop.
Get C# object (or Type) from SerializedProperty - useful for ObjectField type constraint
/// <see cref="https://github.com/lordofduct/spacepuppy-unity-framework/blob/master/SpacepuppyBaseEditor/EditorHelper.cs"/>
public static Type GetTargetTypeOfProperty(SerializedProperty prop)
{
if (prop == null) return null;
var path = prop.propertyPath.Replace(".Array.data[", "[");
path = path.Substring(0, path.LastIndexOf('.'));
object obj = prop.serializedObject.targetObject;
var elements = path.Split('.');
foreach (var element in elements)
{
if (element.Contains("["))
{
var elementName = element.Substring(0, element.IndexOf("["));
var index = System.Convert.ToInt32(element.Substring(element.IndexOf("[")).Replace("[", "").Replace("]", ""));
obj = GetValue_Imp(obj, elementName, index);
}
else
{
obj = GetValue_Imp(obj, element);
}
}
return obj.GetType().GetField(prop.name).FieldType;
}
/// <summary>
/// Gets the object the property represents.
/// </summary>
/// <param name="prop"></param>
/// <returns></returns>
/// <see cref="https://github.com/lordofduct/spacepuppy-unity-framework/blob/master/SpacepuppyBaseEditor/EditorHelper.cs"/>
private static object GetTargetObjectOfProperty(SerializedProperty prop)
{
if (prop == null) return null;
var path = prop.propertyPath.Replace(".Array.data[", "[");
object obj = prop.serializedObject.targetObject;
var elements = path.Split('.');
foreach (var element in elements)
{
if (element.Contains("["))
{
var elementName = element.Substring(0, element.IndexOf("["));
var index = System.Convert.ToInt32(element.Substring(element.IndexOf("[")).Replace("[", "").Replace("]", ""));
obj = GetValue_Imp(obj, elementName, index);
}
else
{
obj = GetValue_Imp(obj, element);
}
}
return obj;
}
private static object GetValue_Imp(object source, string name)
{
if (source == null)
return null;
var type = source.GetType();
while (type != null)
{
var f = type.GetField(name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
if (f != null)
return f.GetValue(source);
var p = type.GetProperty(name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
if (p != null)
return p.GetValue(source, null);
type = type.BaseType;
}
return null;
}
private static object GetValue_Imp(object source, string name, int index)
{
var enumerable = GetValue_Imp(source, name) as System.Collections.IEnumerable;
if (enumerable == null) return null;
var enm = enumerable.GetEnumerator();
//while (index-- >= 0)
// enm.MoveNext();
//return enm.Current;
for (int i = 0; i <= index; i++)
{
if (!enm.MoveNext()) return null;
}
return enm.Current;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment