Unity - 序列化 ScriptableObject、SerializedProperty 编辑器运用进阶

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();
    }
}

Demo 项目链接

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值