Unity编辑器拓展之二:ReorderableList可重新排序的列表框(复杂使用)

先看效果gif图:
这里写图片描述

如果没有看过Unity编辑器拓展之一:ReorderableList可重新排序的列表框(简单使用)的,可以先看这一篇:
http://blog.csdn.net/qq_26999509/article/details/77782177

在此基础上,来绘制更加复杂的类

先提供一个需要绘制的类

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;

public class CharacterTest : MonoBehaviour 
{
    public List<Character> characters = new List<Character>();
    // Use this for initialization
    void Start () 
    {

    }

    // Update is called once per frame
    void Update () 
    {

    }
}

[Serializable]
public class Character
{
    [SerializeField]
    Texture icon;

    [SerializeField]
    string name;

    [SerializeField]
    int hp;

    [SerializeField]
    int power;

    [SerializeField]
    GameObject weapon;
}

然后跟上一篇一样,通过使用ReorderableList绘制List

using UnityEngine;
using System.Collections;
using UnityEditor;
using UnityEditorInternal;

[CustomEditor(typeof(CharacterTest))]
public class CharacterInspector : Editor 
{
    ReorderableList reorderableList;

    void OnEnable()
    {
        SerializedProperty prop = serializedObject.FindProperty("characters");

        reorderableList = new ReorderableList(serializedObject, prop, true, true, true, true);

        //设置单个元素的高度
        reorderableList.elementHeight = 80;

        //绘制单个元素
        reorderableList.drawElementCallback =
            (rect, index, isActive, isFocused) => {
                var element = prop.GetArrayElementAtIndex(index);
                rect.height -= 4;
                rect.y += 2;
                EditorGUI.PropertyField(rect, element);
            };

        //背景色
        reorderableList.drawElementBackgroundCallback = (rect, index, isActive, isFocused) => {
            GUI.backgroundColor = Color.yellow;
        };

        //头部
        reorderableList.drawHeaderCallback = (rect) =>
            EditorGUI.LabelField(rect, prop.displayName);

    }

    public override void OnInspectorGUI()
    {
        serializedObject.Update();
        reorderableList.DoLayoutList();
        serializedObject.ApplyModifiedProperties();
    }
}

目前的效果如下图:

这里写图片描述

最后还需要利用PropertyDrawer来绘制单个Serializable类的每个实例的GUI,也就是Character类

using UnityEngine;
using System.Collections;
using UnityEditor;

//定制Serializable类的每个实例的GUI
[CustomPropertyDrawer(typeof(Character))]
public class CharacterDrawer : PropertyDrawer 
{
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        //创建一个属性包装器,用于将常规GUI控件与SerializedProperty一起使用
        using (new EditorGUI.PropertyScope(position, label, property))
        {
            //设置属性名宽度 Name HP
            EditorGUIUtility.labelWidth = 60;
            //输入框高度,默认一行的高度
            position.height = EditorGUIUtility.singleLineHeight;

            //ico 位置矩形
            Rect iconRect = new Rect(position)
            {
                width = 68,
                height = 68
            };

            Rect nameRect = new Rect(position)
            {
                width = position.width - 70,    //减去icon的width 64
                x = position.x + 70             //在icon的基础上右移64
            };

            Rect hpRect = new Rect(nameRect)
            {
                //在name的基础上,y坐标下移
                y = nameRect.y + EditorGUIUtility.singleLineHeight + 2
            };

            Rect powerRect = new Rect(hpRect)
            {
                //在hp的基础上,y坐标下移
                y = hpRect.y + EditorGUIUtility.singleLineHeight + 2
            };

            Rect weaponLabelRect = new Rect(powerRect)
            {
                y = powerRect.y + EditorGUIUtility.singleLineHeight + 2,
                width = 60
            };

            Rect weaponRect = new Rect(weaponLabelRect)
            {
                x = weaponLabelRect.x + 60,
                width = powerRect.width - 60
            };

            //找到每个属性的序列化值
            SerializedProperty iconProperty = property.FindPropertyRelative("icon");
            SerializedProperty nameProperty = property.FindPropertyRelative("name");
            SerializedProperty hpProperty = property.FindPropertyRelative("hp");
            SerializedProperty powerProperty = property.FindPropertyRelative("power");
            SerializedProperty weaponProperty = property.FindPropertyRelative("weapon");

            //绘制icon
            iconProperty.objectReferenceValue = EditorGUI.ObjectField(iconRect, iconProperty.objectReferenceValue, typeof(Texture), false);

            //绘制name
            nameProperty.stringValue = EditorGUI.TextField(nameRect, nameProperty.displayName, nameProperty.stringValue);

            //Slider,范围在0-100
            EditorGUI.IntSlider(hpRect, hpProperty, 0, 100);
            //Slider,范围在0-10
            EditorGUI.IntSlider(powerRect, powerProperty, 0, 10);

            EditorGUI.PrefixLabel(weaponLabelRect, new GUIContent("weapon"));
            EditorGUI.PropertyField(weaponRect, weaponProperty, GUIContent.none);
        }
    }
}

最后效果就是文章一开始的gif图了

示例工程链接:
链接:http://pan.baidu.com/s/1cgyZ98 密码:jbzh

以上知识分享,如有错误,欢迎指出,共同学习,共同进步

猜你喜欢

转载自blog.csdn.net/qq_26999509/article/details/77801852
今日推荐