-
Notifications
You must be signed in to change notification settings - Fork 6
ReorderableList
using System.Collections.Generic;
using UnityEngine;
using UniEasy;
public class ReorderableListOverview : MonoBehaviour
{
[Reorderable]
public List<GameObject> A;
}

public class ReorderableListOverview : MonoBehaviour
{
[Reorderable, BackgroundColor("#00408080")]
public List<GameObject> A;
}

public class StateMachineActionObject
{
public Animator Animator;
public AnimatorStateInfo StateInfo;
public int LayerIndex;
public int PathHash;
public AnimatorState State;
}
public abstract class StateMachineAction : ScriptableObject
{
public abstract void Execute(StateMachineActionObject smao);
}
public class StateMachineHandler : StateMachineBehaviour
{
[Reorderable, BackgroundColor("#00008080") ]
public List<StateMachineAction> Actions = new List<StateMachineAction>();
public bool IgnoreWeight = false;
}

public class StateMachineHandler : StateMachineBehaviour
{
[Reorderable, DropdownMenu(typeof(StateMachineAction)), BackgroundColor("#00008080")]
public List<StateMachineAction> Actions = new List<StateMachineAction>();
public bool IgnoreWeight = false;
}
After adding the DropdownMenuAttribute, the plus button changes.

By clicking the plus sign, a drop-down menu will pop up.

Select a class in the drop-down menu to create a nested ScriptableObject in the Object.

The type parameter in the DropdownMenuAttribute can limit the class displayed in the drop-down menu to be a subclass of this type.
You can adjust the parameters by selecting nested ScriptableObject, but it's not intuitive or convenient.
So is time to ObjectReferenceAttribute go on stage.
public class StateMachineHandler : StateMachineBehaviour
{
[Reorderable, DropdownMenu(typeof(StateMachineAction)), BackgroundColor("#00008080"), ObjectReference]
public List<StateMachineAction> Actions = new List<StateMachineAction>();
public bool IgnoreWeight = false;
}

As you can see, it will draw as many fields as possible for the Object you reference.
public class ReorderableListOverview : MonoBehaviour
{
[Reorderable, BackgroundColor("#00408080"), ObjectReference]
public List<GameObject> A;
}

It's not hard for you to find that this attribute is a custom drawing of ReorderableList elements.
So, if you want to customize the drawing of a certain type of element, you can also refer to the ObjectReferenceDrawer
[CustomPropertyDrawer(typeof(ObjectReferenceAttribute))]
public class ObjectReferenceDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
...
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
...
}
}
So far ReorderableList has brought us great convenience, but it still goes beyond that.
Many times, we don't need a class to inherit MonoBehaviour or ScriptableObject, but we also want to modify the fields of this class directly under the Inspector.
So is time to RuntimeObjectAttribute go on stage.
[UniEasy.ContextMenu("Runtime/C")]
public class C
{
public int D;
public string E;
}
You can use UniEasy.ContextMenuAttribute to classify items in the drop-down menu.

public class ReorderableListOverview : MonoBehaviour
{
[Reorderable, BackgroundColor("#00408080"), ObjectReference]
public List<GameObject> A;
[Reorderable, BackgroundColor("#00808080"), DropdownMenu(typeof(C)), RuntimeObject]
public List<string> B;
}
The RuntimeObjectAttribute must be used with the DropdownMenuAttribute, and the array element type must be string.

RuntimeObject does not support reference types, so don't add GameObject or ScriptableObject type fields!!!
You can instance this class through the RuntimeObject.FromJson() method.
And convert this class to a string through the RuntimeObject.ToJson() method.
public class ReorderableListOverview : MonoBehaviour
{
void Start()
{
Debug.Log(B[0]);
object obj = RuntimeObject.FromJson(B[0]);
Debug.Log(RuntimeObject.ToJson(obj));
}
}
It is worth mentioning that the fields in the RuntimeObject also support the RuntimeObjectAttribute, and support the multi-level nesting of the RuntimeObject.
[UniEasy.ContextMenu("Runtime/C")]
public class C
{
public int D;
public string E;
[Reorderable, BackgroundColor("#00808080"), DropdownMenu(typeof(C)), RuntimeObject]
public List<string> F;
}

It also supports custom drawing of fields.
[RuntimeCustomPropertyDrawer(typeof(RangeAttribute))]
public class RuntimeRangeDrawer : RuntimePropertyDrawer
{
public override void OnGUI(Rect position, RuntimeSerializedProperty property, GUIContent label)
{
...
}
public override float GetPropertyHeight(RuntimeSerializedProperty property, GUIContent label)
{
...
}
}
[UniEasy.ContextMenu("Runtime/C")]
public class C
{
[Range(0, 10)]
public int D;
}

Finally, if you want to expand them.
You can try to inherit ReorderableListDrawer, refer to EntityBehaviourDrawer.
[CustomEditor(typeof(EntityBehaviour), true)]
public class EntityBehaviourDrawer : ReorderableListDrawer
{
protected override void DrawInspector()
{
base.DrawInspector();
...
}
}
You can try to inherit RuntimeObjectDrawer, refer to RuntimeFeatureDrawer.
[CustomPropertyDrawer(typeof(RuntimeFeatureAttribute))]
public class RuntimeFeatureDrawer : RuntimeObjectDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
base.OnGUI(mainPosition, property, label);
...
}
}