[Unity编辑器扩展] 数组或List -- 通过PropertyDrawer绘制列表元素

列表元素类

using UnityEngine;
[System.Serializable]
public class Role
{
    public Texture Tex;
    public GameObject Prefab;
    public string Name;
    public int Health;
    public int Damage;
    public float Speed;
    public float AngularSpeed;
}

列表

using System.Collections.Generic;
using UnityEngine;

public class RoleModel : MonoBehaviour
{
    public List RoleList = new List();
}

列表编辑器扩展

using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
[CustomEditor(typeof(RoleModel))]
public class RoleModelEditor : Editor
{
    private ReorderableList _roleList;

    private void OnEnable()
    {
        //创建ReorderableList 参数:
        //arg1:序列化物体,arg2:序列化数据,arg3:可否拖动,arg4:是否显示标题,arg5:是否显示添加按钮,arg6:是否显示添加按钮
        _roleList = new ReorderableList(serializedObject, serializedObject.FindProperty("RoleList")
            , true, true, true, true);

        //自定义列表名称
        _roleList.drawHeaderCallback = (Rect rect) =>
        {
            GUI.Label(rect, "Role List");
        };

        ////定义元素的高度
        _roleList.elementHeight = 135;

        //自定义绘制列表元素
        _roleList.drawElementCallback = (Rect rect, int index, bool selected, bool focused) =>
        {
            //根据index获取对应元素 
            SerializedProperty item = _roleList.serializedProperty.GetArrayElementAtIndex(index);
            rect.height -= 4;
            rect.y += 2;
            EditorGUI.PropertyField(rect, item, new GUIContent("Index " + index));
        };

        //当删除元素时候的回调函数,实现删除元素时,有提示框跳出
        _roleList.onRemoveCallback = (ReorderableList list) =>
        {
            if (EditorUtility.DisplayDialog("Warnning", "Do you want to remove this element?", "Remove", "Cancel"))
            {
                ReorderableList.defaultBehaviours.DoRemoveButton(list);
            }
        };
    }


    public override void OnInspectorGUI()
    {
        //更新
        serializedObject.Update();
        //自动布局绘制列表
        _roleList.DoLayoutList();
        //应用
        serializedObject.ApplyModifiedProperties();
    }

}

列表元素绘制

using UnityEditor;
using UnityEngine;

[CustomPropertyDrawer(typeof(Role))]
public class RoleDrawer : PropertyDrawer
{
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        using (new EditorGUI.PropertyScope(position, label, property))
        {

            //设置属性名宽度
            EditorGUIUtility.labelWidth = 60;
            position.height = EditorGUIUtility.singleLineHeight;

            //
            Rect iconRect = new Rect(position)
            {
                width = 64,
                height = 64
            };

            var prefabRect = new Rect(position)
            {
                width = position.width - 80,
                x = position.x + 80
            };

            var nameRect = new Rect(prefabRect)
            {
                y = prefabRect.y + EditorGUIUtility.singleLineHeight + 5
            };

            var healthSliderRect = new Rect(nameRect)
            {
                y = nameRect.y + EditorGUIUtility.singleLineHeight + 5
            };

            var damageSliderRect = new Rect(healthSliderRect)
            {
                y = healthSliderRect.y + EditorGUIUtility.singleLineHeight + 5
            };

            var speedSliderRect = new Rect(position)
            {
                width = position.width / 2,
                y = damageSliderRect.y + EditorGUIUtility.singleLineHeight + 5
            };

            var angularSpeedSliderRect = new Rect(position)
            {
                width = position.width / 2,
                x = position.width / 2 + 40,
                y = damageSliderRect.y + EditorGUIUtility.singleLineHeight + 5
            };


            //
            SerializedProperty iconProperty = property.FindPropertyRelative("Tex");
            SerializedProperty prefabProperty = property.FindPropertyRelative("Prefab");
            SerializedProperty nameProperty = property.FindPropertyRelative("Name");
            SerializedProperty healthProperty = property.FindPropertyRelative("Health");
            SerializedProperty damageProperty = property.FindPropertyRelative("Damage");
            SerializedProperty speedProperty = property.FindPropertyRelative("Speed");
            SerializedProperty angularSpeedProperty = property.FindPropertyRelative("AngularSpeed");


            iconProperty.objectReferenceValue =
                EditorGUI.ObjectField(iconRect, iconProperty.objectReferenceValue, typeof(Texture), false);
            prefabProperty.objectReferenceValue =
                EditorGUI.ObjectField(prefabRect, prefabProperty.displayName, prefabProperty.objectReferenceValue, typeof(GameObject), false); ;
            nameProperty.stringValue =
                EditorGUI.TextField(nameRect, nameProperty.displayName, nameProperty.stringValue);
            healthProperty.intValue =
               EditorGUI.IntSlider(healthSliderRect, healthProperty.displayName, healthProperty.intValue, 1, 10);
            damageProperty.intValue =
                EditorGUI.IntSlider(damageSliderRect, damageProperty.displayName, damageProperty.intValue, 1, 10);
            speedProperty.floatValue =
                EditorGUI.FloatField(speedSliderRect, speedProperty.displayName, speedProperty.floatValue);
            angularSpeedProperty.floatValue =
                EditorGUI.FloatField(angularSpeedSliderRect, angularSpeedProperty.displayName, angularSpeedProperty.floatValue);

        }
    }
}

最终效果

[Unity编辑器扩展] 数组或List -- 通过PropertyDrawer绘制列表元素_第1张图片

你可能感兴趣的:(Unity,C#)