Unity编辑器扩展--Create Custom Inspector

本文介绍了如何使用Unity的CreateCustomInspector功能,通过扩展编辑器为Level类创建自定义Inspector面板,实现参数验证和界面调整。教程涵盖了关键代码段,如脏检查、GUI操作和事件响应,并展示了修改前后的效果。
摘要由CSDN通过智能技术生成

一、Create Custom Inspector

重绘inspector面板一方面是我们的挂在脚本的窗口变得友好,另一方面可以让其变得更强大,比如添加一些有效性验证。

二、重要说明

  1. EditorUtility.SetDirty(object target):该方法可以表明target对象为dirty((⊙﹏⊙)b,怎么翻译合适?)的,unity会将有dirty标记的已经改变的对象在磁盘中存储,可以用来对一些修改数据的强制刷新,这里用来立即绘制GUI(我们对GUI的修改不会立即生效,只有鼠标在Scene上时才会强制重绘界面元素)。
  2. 对于类似GUI.Style等静态属性的修改,在修改前需要备份,使用后在设回,避免修改后的对其他无需使用修改后属性的干扰。
  3. 布局中的GUILayout.BeginVertical等需成对出现,有始有终。
  4. 该类型的脚本都需放在Editor文件夹下,unity会自动调用。

三、Code

using UnityEngine;
using System.Collections;
using UnityEditor;

namespace RunAndJump.LeveCreator
{
    //[CanEditMultipleObjects]  //希望多个挂在该类的对象可以在inspector面板选定多个一同修改的话
    //需要将该标签添加上,由于level类一个场景下只有一个,所以无需添加该标记
    [CustomEditor(typeof(Level))]
    public class LevelInspector : Editor
    {
        private Level _myTarget;
        private int _newTotalColumns;
        private int _newTotalRows;

        private void OnEnable()
        {
            Debug.Log("OnEnable was called...");
            _myTarget = (Level)target;
            InitLevel();
            ResetResizeValues();
        }

        private void OnDisable()
        {
            Debug.Log("OnDisable was called...");
        }

        private void OnDestory()
        {
            Debug.Log("OnDestroy was called...");
        }

        public override void OnInspectorGUI()
        {
            EditorGUILayout.LabelField("The GUI of this inspector was modified.");
            EditorGUILayout.LabelField("The current level time is:"+_myTarget.TotalTime);

//            DrawDefaultInspector();//使用unity默认的绘制方式来显示Inspector面板
            DrawDateGUI();
            DrawLevelSizeGUI();

            //当使用绘制面板方法并且GUI改变时刷新GUI页面
            if(GUI.changed)
                EditorUtility.SetDirty(_myTarget);
        }

        private void DrawLevelSizeGUI()
        {
            EditorGUILayout.LabelField("Size",EditorStyles.boldLabel);
            EditorGUILayout.BeginHorizontal("box");
            EditorGUILayout.BeginVertical();
            _newTotalColumns = EditorGUILayout.IntField("Columns", Mathf.Max(0, _newTotalColumns));
            _newTotalRows = EditorGUILayout.IntField("Rows", Mathf.Max(0, _newTotalRows));
            EditorGUILayout.EndVertical();
            EditorGUILayout.BeginVertical();

            bool oldEnable = GUI.enabled;
            GUI.enabled = (_newTotalColumns != _myTarget.TotalColumns || _newTotalRows != _myTarget.TotalRows);
            bool buttonResize = GUILayout.Button("Resize", GUILayout.Height(2*EditorGUIUtility.singleLineHeight));
            if (buttonResize)
            {
                if (EditorUtility.DisplayDialog(
                    "Level Creator",
                    "Are you sure you want to resize the leve?\nThis action cannot be undone",
                    "yes",
                    "no"
                    ))
                {
                    ResizeLeve();
                }

            }

            bool buttonReset = GUILayout.Button("Reset");
            if (buttonReset)
            {
                ResetResizeValues();
            }
            GUI.enabled = oldEnable;

            EditorGUILayout.EndVertical();
            EditorGUILayout.EndHorizontal();
        }

        private void InitLevel()
        {
            if (_myTarget.Pieces == null || _myTarget.Pieces.Length == 0)
            {
                Debug.Log("Initializing thie Pieces array...");
                _myTarget.Pieces=new LevelPiece[_myTarget.TotalColumns*_myTarget.TotalRows];
            }
        }

        private void ResetResizeValues()
        {
            _newTotalColumns = _myTarget.TotalColumns;
            _newTotalRows = _myTarget.TotalRows;
        }

        private void ResizeLeve()
        {
            LevelPiece[] newPieces=new LevelPiece[_newTotalColumns*_newTotalRows];
            for (int col = 0; col < _myTarget.TotalColumns; ++col)
            {
                for (int row = 0; row < _myTarget.TotalRows; ++row)
                {
                    if (col < _newTotalColumns && row < _newTotalRows)
                    {
                        newPieces[col + row*_newTotalColumns] = _myTarget.Pieces[col + row*_myTarget.TotalColumns];
                    }
                    else
                    {
                        LevelPiece piece = _myTarget.Pieces[col+row*_myTarget.TotalColumns];
                        if (piece != null)
                        {
                            //在editor模式下我们必须使用DestroyImmediate
                            Object.DestroyImmediate(piece.gameObject);
                        }
                    }
                }
            }
            _myTarget.Pieces = newPieces;
            _myTarget.TotalColumns = _newTotalColumns;
            _myTarget.TotalRows = _newTotalRows;
        }

        private void DrawDateGUI()
        {
            EditorGUILayout.LabelField("Data",EditorStyles.boldLabel);
            EditorGUILayout.BeginVertical("box");
            _myTarget.TotalTime = EditorGUILayout.IntField("Total Time", Mathf.Max(0, _myTarget.TotalTime));
            _myTarget.Gravity = EditorGUILayout.FloatField("Gravity", _myTarget.Gravity);
            _myTarget.Bgm = (AudioClip) EditorGUILayout.ObjectField("Bgm", _myTarget.Bgm, typeof (AudioClip), false);
            _myTarget.Background =
                (Sprite) EditorGUILayout.ObjectField("Background", _myTarget.Background, typeof (Sprite), false);
            EditorGUILayout.EndVertical();
        }
    }
}

四、效果

前:前后:后

五、原文链接

https://www.cnblogs.com/Firepad-magic/p/6624091.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值