168 lines
7.3 KiB
C#
168 lines
7.3 KiB
C#
|
using System;
|
|||
|
using System.Reflection;
|
|||
|
using UnityEngine;
|
|||
|
#if UNITY_EDITOR
|
|||
|
using UnityEditor;
|
|||
|
#endif
|
|||
|
|
|||
|
namespace Obi{
|
|||
|
|
|||
|
[System.AttributeUsage(System.AttributeTargets.Field)]
|
|||
|
public class SerializeProperty : PropertyAttribute
|
|||
|
{
|
|||
|
public string PropertyName { get; private set; }
|
|||
|
|
|||
|
public SerializeProperty(string propertyName)
|
|||
|
{
|
|||
|
PropertyName = propertyName;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#if UNITY_EDITOR
|
|||
|
[CustomPropertyDrawer(typeof(SerializeProperty))]
|
|||
|
public class SerializePropertyAttributeDrawer : PropertyDrawer
|
|||
|
{
|
|||
|
private PropertyInfo propertyFieldInfo = null;
|
|||
|
private object target = null;
|
|||
|
|
|||
|
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
|||
|
{
|
|||
|
if (target == null)
|
|||
|
target = GetSource(property);
|
|||
|
|
|||
|
// Find the property field using reflection, in order to get access to its getter/setter.
|
|||
|
if (propertyFieldInfo == null)
|
|||
|
propertyFieldInfo = target.GetType().GetProperty(((SerializeProperty)attribute).PropertyName,
|
|||
|
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
|||
|
|
|||
|
if (propertyFieldInfo != null)
|
|||
|
{
|
|||
|
// Retrieve the value using the property getter:
|
|||
|
object value = propertyFieldInfo.GetValue(target,null);
|
|||
|
|
|||
|
// Draw the property:
|
|||
|
EditorGUI.BeginProperty(position,label,property);
|
|||
|
EditorGUI.BeginChangeCheck();
|
|||
|
value = DrawProperty(position,property.propertyType,propertyFieldInfo.PropertyType,value,label);
|
|||
|
|
|||
|
// If any changes were detected, call the property setter:
|
|||
|
if (EditorGUI.EndChangeCheck() && propertyFieldInfo != null)
|
|||
|
{
|
|||
|
foreach (var t in property.serializedObject.targetObjects)
|
|||
|
{
|
|||
|
// Record object state for undo:
|
|||
|
Undo.RecordObject(t, "Inspector");
|
|||
|
|
|||
|
// Call property setter:
|
|||
|
propertyFieldInfo.SetValue(t, value, null);
|
|||
|
SetPropertyValue(property, propertyFieldInfo.PropertyType, value);
|
|||
|
|
|||
|
// Record prefab modification:
|
|||
|
PrefabUtility.RecordPrefabInstancePropertyModifications(t);
|
|||
|
}
|
|||
|
}
|
|||
|
EditorGUI.EndProperty();
|
|||
|
|
|||
|
}else
|
|||
|
{
|
|||
|
EditorGUI.LabelField(position,"Error: could not retrieve property.");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private object GetSource(SerializedProperty property)
|
|||
|
{
|
|||
|
object trgt = property.serializedObject.targetObject;
|
|||
|
string[] data = property.propertyPath.Split('.');
|
|||
|
|
|||
|
if (data.Length == 1)
|
|||
|
return trgt;
|
|||
|
else{
|
|||
|
for (int i = 0; i < data.Length-1;++i){
|
|||
|
trgt = trgt.GetType().GetField(data[i]).GetValue(trgt);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return trgt;
|
|||
|
}
|
|||
|
|
|||
|
private object DrawProperty(Rect position, SerializedPropertyType propertyType, Type type, object value, GUIContent label)
|
|||
|
{
|
|||
|
switch (propertyType)
|
|||
|
{
|
|||
|
case SerializedPropertyType.Integer:
|
|||
|
return EditorGUI.IntField(position,label,(int)value);
|
|||
|
case SerializedPropertyType.Boolean:
|
|||
|
return EditorGUI.Toggle(position,label,(bool)value);
|
|||
|
case SerializedPropertyType.Float:
|
|||
|
return EditorGUI.FloatField(position,label,(float)value);
|
|||
|
case SerializedPropertyType.String:
|
|||
|
return EditorGUI.TextField(position,label,(string)value);
|
|||
|
case SerializedPropertyType.Color:
|
|||
|
return EditorGUI.ColorField(position,label,(Color)value);
|
|||
|
case SerializedPropertyType.ObjectReference:
|
|||
|
return EditorGUI.ObjectField(position,label,(UnityEngine.Object)value,type,true);
|
|||
|
case SerializedPropertyType.ExposedReference:
|
|||
|
return EditorGUI.ObjectField(position,label,(UnityEngine.Object)value,type,true);
|
|||
|
case SerializedPropertyType.LayerMask:
|
|||
|
return EditorGUI.LayerField(position,label,(int)value);
|
|||
|
case SerializedPropertyType.Enum:
|
|||
|
return EditorGUI.EnumPopup(position,label,(Enum)value);
|
|||
|
case SerializedPropertyType.Vector2:
|
|||
|
return EditorGUI.Vector2Field(position,label,(Vector2)value);
|
|||
|
case SerializedPropertyType.Vector3:
|
|||
|
return EditorGUI.Vector3Field(position,label,(Vector3)value);
|
|||
|
case SerializedPropertyType.Vector4:
|
|||
|
return EditorGUI.Vector4Field(position,label,(Vector4)value);
|
|||
|
case SerializedPropertyType.Rect:
|
|||
|
return EditorGUI.RectField(position,label,(Rect)value);
|
|||
|
case SerializedPropertyType.AnimationCurve:
|
|||
|
return EditorGUI.CurveField(position,label,(AnimationCurve)value);
|
|||
|
case SerializedPropertyType.Bounds:
|
|||
|
return EditorGUI.BoundsField(position,label,(Bounds)value);
|
|||
|
default:
|
|||
|
throw new NotImplementedException("Unimplemented propertyType "+propertyType+".");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void SetPropertyValue(SerializedProperty property, Type type, object value)
|
|||
|
{
|
|||
|
switch (property.propertyType)
|
|||
|
{
|
|||
|
case SerializedPropertyType.Integer:
|
|||
|
property.intValue = (int)value; break;
|
|||
|
case SerializedPropertyType.Boolean:
|
|||
|
property.boolValue = (bool)value; break;
|
|||
|
case SerializedPropertyType.Float:
|
|||
|
property.floatValue = (float)value; break;
|
|||
|
case SerializedPropertyType.String:
|
|||
|
property.stringValue = (string)value; break;
|
|||
|
case SerializedPropertyType.Color:
|
|||
|
property.colorValue = (Color)value; break;
|
|||
|
case SerializedPropertyType.ObjectReference:
|
|||
|
property.objectReferenceValue = (UnityEngine.Object)value; break;
|
|||
|
case SerializedPropertyType.ExposedReference:
|
|||
|
property.exposedReferenceValue = (UnityEngine.Object)value; break;
|
|||
|
case SerializedPropertyType.LayerMask:
|
|||
|
property.intValue = (int)value; break;
|
|||
|
case SerializedPropertyType.Enum:
|
|||
|
property.enumValueIndex = (int)value; break;
|
|||
|
case SerializedPropertyType.Vector2:
|
|||
|
property.vector2Value = (Vector2)value; break;
|
|||
|
case SerializedPropertyType.Vector3:
|
|||
|
property.vector3Value = (Vector3)value; break;
|
|||
|
case SerializedPropertyType.Vector4:
|
|||
|
property.vector4Value = (Vector4)value; break;
|
|||
|
case SerializedPropertyType.Rect:
|
|||
|
property.rectValue = (Rect)value; break;
|
|||
|
case SerializedPropertyType.AnimationCurve:
|
|||
|
property.animationCurveValue = (AnimationCurve)value; break;
|
|||
|
case SerializedPropertyType.Bounds:
|
|||
|
property.boundsValue = (Bounds)value; break;
|
|||
|
default:
|
|||
|
throw new NotImplementedException("Unimplemented propertyType " + property.propertyType + ".");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
#endif
|
|||
|
}
|