本文转载自:https://blog.csdn.net/qq_26999509/article/details/77801852
如果没有看过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 characters = new List();
// 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
以上知识分享,如有错误,欢迎指出,共同学习,共同进步