Unity - 序列化 ScriptableObject、SerializedProperty 编辑器运用进阶
拓展上一篇关于Unity 序列化 编辑器运用
上一篇是单独使用 一个类对象,下面将 List
运用到 序列化中,将如 public List<Npc> npcList = new List<Npc>();
显示在 Inspector 面板,并且使用序列化
先看效果图
// Npc 类不变
[System.Serializable]
public class Npc
{
public int npcID;
public int nameID;
public float speed;
public float life;
}
// NpcClass 类改用 List
public class NpcClass : MonoBehaviour {
public List<Npc> npcList = new List<Npc>();
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
}
// EventTriggerEditor.cs 改动较大
using UnityEngine;
using System.Collections;
using UnityEditor;
[CanEditMultipleObjects]
[CustomEditor(typeof(NpcClass))]
public class NpcClassEditor : Editor {
private SerializedProperty npcList;
private int removeIndex = -1;
private GUIContent debugBtn;
// 添加按钮文本
private GUIContent m_IconToolbarPlus;
//移除按钮文本
private GUIContent m_IconToolbarMinus;
void OnEnable()
{
// 使用 serializedObject.FindProperty 方法
// 获取 NpcClass 中定义的 public Npc npc; 变量
npcList = serializedObject.FindProperty("npcList");
debugBtn = new GUIContent("Debug");
debugBtn.tooltip = "Debug values about the npc";
m_IconToolbarPlus = new GUIContent(EditorGUIUtility.IconContent("Toolbar Plus"));
m_IconToolbarPlus.tooltip = "Add a item with this list.";
m_IconToolbarMinus = new GUIContent(EditorGUIUtility.IconContent("Toolbar Minus"));
m_IconToolbarMinus.tooltip = "Remove a Item in this list.";
}
public override void OnInspectorGUI()
{
serializedObject.Update();
DrawNpcList();
if (removeIndex > -1)
{
// 移除 npcList 中 第 removeIndex 项目
RemoveItem(removeIndex);
removeIndex = -1;
}
if (GUI.changed)
{
EditorUtility.SetDirty(target);
}
// 绘制 添加项按钮
DrawAddBtn();
serializedObject.ApplyModifiedProperties();
}
private void DrawAddBtn()
{
// 计算添加按钮(x, y, width, hight)
Rect btPosition = GUILayoutUtility.GetRect(m_IconToolbarPlus, GUI.skin.button);
const float addButonWidth = 150f;
btPosition.x = btPosition.x + (btPosition.width - addButonWidth) / 2;
btPosition.width = addButonWidth;
// 添加项按钮
if (GUI.Button(btPosition, m_IconToolbarPlus))
{
AddItem();
}
if (npcList.arraySize <= 0)
{
EditorGUILayout.HelpBox("this lis has't Item", MessageType.Warning);
}
}
// 向 npcList 添加一项
private void AddItem()
{
npcList.arraySize += 1;
SerializedProperty npc = npcList.GetArrayElementAtIndex(npcList.arraySize -1);
serializedObject.ApplyModifiedProperties();
}
// 移除一项
private void RemoveItem(int index)
{
if (npcList.arraySize > index)
{
//移除 第 index 项目
npcList.DeleteArrayElementAtIndex(index);
}
}
// 绘制整个 npcList
private void DrawNpcList()
{
if (npcList.arraySize <= 0)
{
return;
}
for (int i = 0; i < npcList.arraySize; i ++)
{
//从 npcList 中获取每项值
SerializedProperty npc = npcList.GetArrayElementAtIndex(i);
DrawNpc(npc, i);
}
}
// 绘制 Npc 类属性
private void DrawNpc(SerializedProperty npc, int index)
{
EditorGUILayout.BeginVertical("box");
Rect removeButtonPos = GUILayoutUtility.GetRect(m_IconToolbarMinus, GUI.skin.button);
const float removeButonWidth = 50f;
removeButtonPos.x = removeButtonPos.width - removeButonWidth / 2 - 5;
removeButtonPos.width = removeButonWidth;
if (GUI.Button(removeButtonPos, m_IconToolbarMinus))
{
removeIndex = index;
}
GUILayout.Space(5);
// 获取 npc 类中的 npcID 属性
SerializedProperty npcID = npc.FindPropertyRelative("npcID");
// 将 npcID 属性绘制在 Inspector 面板
EditorGUILayout.PropertyField(npcID, new GUIContent("NpcID"));
GUILayout.Space(5);
SerializedProperty nameID = npc.FindPropertyRelative("nameID");
EditorGUILayout.PropertyField(nameID, new GUIContent("NameID"));
GUILayout.Space(5);
SerializedProperty speed = npc.FindPropertyRelative("speed");
EditorGUILayout.PropertyField(speed, new GUIContent("Speed"));
GUILayout.Space(5);
SerializedProperty life = npc.FindPropertyRelative("life");
EditorGUILayout.PropertyField(life, new GUIContent("Life"));
GUILayout.Space(5);
Rect btPosition = GUILayoutUtility.GetRect(debugBtn, GUI.skin.button);
const float addButonWidth = 150f;
btPosition.x = btPosition.x + (btPosition.width - addButonWidth) / 2;
btPosition.width = addButonWidth;
if (GUI.Button(btPosition, debugBtn))
{
Debug.Log("npcID :" + npcID.intValue);
Debug.Log("nameID :" + nameID.intValue);
Debug.Log("speed :" + speed.floatValue);
Debug.Log("life :" + life.floatValue);
}
EditorGUILayout.EndVertical();
GUILayout.Space(10);
serializedObject.ApplyModifiedProperties();
}
}