Unity3D Editor 编辑器扩展3 Editor脚本

Unity3D Editor 编辑器扩展3 Editor脚本

环境:Unity2017.2 语言:C#

总起:

在编辑Unity项目的时候,总不可能避免的接触到Unity自身自带的Inspector参数调整无法很好的完成某些特定功能的情况。

比方说想要一个按钮直接能跳到游戏的主界面进行调试,然而普通的情况下甚至连添加一个按钮都做不到。

这边推荐一下本人花了20几刀购买的插件——Odin Inspector & Serializer: http://sirenix.net/odininspector。该插件能够摒弃我今天要讲的Editor脚本,非常轻松的就能完成一些炫酷的EditorUI。

Odin,我其实研究的不是太深入,因为在实际的项目中并没有用到,所以该插件的介绍,我想过段时间深入研究后再说。

今天的主角是Editor脚本。

Editor脚本:

♦ 简单介绍

首先Editor脚本必须放在Editor文件夹或其子文件夹下,然后我们来看一个Edior脚本的例子:

//PlayerEditor.cs
[CustomEditor(typeof(Player))]
public class PlayerEditor : Editor
{
    private SerializedProperty hpProperty;

    void Awake()
    {
        Debug.Log("Awake");
    }

    void OnEnable()
    {
        Debug.Log("OnEnable");
        hpProperty = serializedObject.FindProperty("hp");
    }

    public override void OnInspectorGUI()
    {
        // 更新serializedObject,在OnInspectorGUI一开始就要调用该函数
        serializedObject.Update();

        // 创建一个Int的滑动条
        EditorGUILayout.IntSlider(hpProperty, 0, 100, new GUIContent("HP"));

        // 使用自定义的滑动条
        ProgressBar(hpProperty.intValue / 100f, "HP");

        // 保存所有对脚本修改的值
        serializedObject.ApplyModifiedProperties();
    }

    // 自定义一个滑动条
    void ProgressBar(float value, string label)
    {
        Rect rect = GUILayoutUtility.GetRect(18, 18, "TextField");
        EditorGUI.ProgressBar(rect, value, label);
        EditorGUILayout.Space();
    }

    void OnDisable()
    {
        Debug.Log("OnDisable");
    }

    void OnDestroy()
    {
        Debug.Log("OnDestroy");
    }
}

// Player.cs
public class Player : MonoBehaviour
{
    public int hp;
}


效果如下:


可以注意到,PlayerEditor是继承于Editor的,除了Awake、OnEnable这类熟悉的生命周期方法外,脚本中很多操作使用到了UnityEditor.dll里的内容,而该dll是不会被打包的,所以非Editor文件夹底下的脚本千万不要引用到UnityEditor这个命名空间了。

Editor父类中的serializedObject代表的正是当前操作的这个脚本,使用以下操作可能更加明了:

Player player = (Player)serializedObject.targetObject;

Debug.Log(player.hp);

使用其成员变量targetObject可以直接获取到对应脚本进行操作。

具体OnInspectorGUI中的内容,我不想详细介绍了,主要是使用EditorGUILayout、GUILayout、GUILayoutUtility这三个类。

说到Editor,其实第一篇文章提到的MenuItem最好就是写在这样的脚本中。

♦ Editor脚本的结构

相比于介绍Editor的使用,我更想深入了解一下Editor这个类(使用方面,还有Odin完全可以代替Editor脚本呢)。

Editor的继承结构:Editor -> ScriptableObject -> UnityEngine.Object -> object。

Editor除了继承于ScriptableObject外,还实现了IPreviewable、IToolModeOwner接口。

我们刚刚使用的serializedObject是根据我们写的Component生成的SerializedObject(注意不是Editor的父类ScriptableObject)对象。

Editor的父类ScriptableObject可能很多人都用过,他可以很方便的保存一些配置信息,Prefab、资源引用什么的。

SerializedObject是UnityEditor命名空间的,用于以通用的方式操作对象的属性,可以自动处理撤销操作,和产生一些预制的样式UI。

看到这里,我越来越好奇Unity的对象序列化了,但是这边反编译的C#脚本引用的都是C++内容。

感觉有些遗憾,手头也没有C++代码,如果有大神指导如何获取该源码,希望能指条明路,谢谢!

个人:

看源码的时候,多数都会追到C++的代码,看得唯一感觉比较友好的就是UGUI的,因为他基本上都是基于C#来编写的,虽然内容比较繁杂,但是总也能理清思路。

我手头上有份Unity4 C++,但感觉不是很全,Transform几个类倒是有,像SerializedObject便找不到了,可能是我姿势不对。


猜你喜欢

转载自blog.csdn.net/u012632851/article/details/80531527