当前位置:   article > 正文

「Unity3D」(12)EditorWindow使用ScriptableObject绘制界面_editorwindows 怎么储存数据 unity

editorwindows 怎么储存数据 unity

通常绘制EditorWindow需要手动一个个手动绘制控件和布局,但是联想到Inspector可以根据SerializedObject对象自动绘制和布局,那么如果我们可以根据SerializedObject对象来控制EditorWindow的显示,然后在此之上再进行一些自定义工作,岂不是会方便快捷很多。

本文将会介绍,如何使用ScriptableObject对象的Inspector绘制,来填充EditorWindow的界面显示。关于Inspector绘制介绍见这篇文章:自定义属性面板Inspector详解

ScriptableObject对象的Inpsector绘制

ScriptableObject对象可以运行时存储临时数据,也可以生成.asse文件持久化数据,如果ScriptableObject持久化对象对应一个EditorWindow窗口,刚好可以当做窗口配置数据源来使用。当然,ScriptableObject的asset文件本身拥有Inpsector编辑显示能力,可以单独用来保存数据使用。比如,建立如下一个ScriptableObject子类:

using UnityEngine;
using System.Collections;

// 生成入口到Unity菜单Assets->Create下
[CreateAssetMenu(menuName = "Create ShowObject")]
public class ShowObject : ScriptableObject
{
    public Vector3 position;
    [Space(20)] // 注意,ShowObject需要单独一个文件,并且文件名与类名一致,[]属性才能有效。
    public string  label;
    [Range(0, 10)] // 注意,ShowObject需要单独一个文件,并且文件名与类名一致,[]属性才能有效。
    public int     intData;
    public bool    isCheck;
    public Options options;
    public Shader  defaultShader;

    public enum Options
    {
        Opt1,
        Opt2,
        Opt3,
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

这样,我们就能够创建一个ShowObject的asset文件,而选中这个asset文件,就可以看到ShowObject的绘制和布局。我们就是需要把这个Inspector的显示,放入到EditorWindow之中绘制。

创建EditorWindow

public class EditorWindows : EditorWindow
{
    [MenuItem("ExtendingEditor/ShowObject Window")]
    public static void ShowObjectWindow() 
    {
        EditorWindow.GetWindow<EditorWindows>(true, "ShowObject Window", true);
    }

    private void OnGUI() 
    {
        // 绘制ScriptableObject的Inspector显示,目前是空的。
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

绘制ScriptableObject

有两种方法,来绘制ScriptableObject的内容:

  • 手动遍历ScriptableObject每个属性绘制。
  • 自动调用ScriptableObject Inspector的绘制方法。
第一种,手动遍历ScriptableObject

首先,我们需要创建ScriptableObject对象,然后构建一个SerializedObject,接着遍历绘制SerializedObject的每一个Property。

public class EditorWindows : EditorWindow
{
    private SerializedObject serializedObject;

    [MenuItem("ExtendingEditor/ShowObject Window")]
    public static void ShowObjectWindow() 
    {
        var window = EditorWindow.GetWindow<EditorWindows>(true, "ShowObject Window", true);
        // 创建ScriptableObject并生成SerializedObject
        window.serializedObject = new SerializedObject(ScriptableObject.CreateInstance<ShowObject>());
    }

    private void OnGUI() 
    {
        this.serializedObject.Update();
        
        var iterator = this.serializedObject.GetIterator();
        // go to child
        iterator.NextVisible(true);
        // skip name
        iterator.Next(false);
        // skip EditorClassIdentifier
        iterator.Next(false);
        
        // 遍历每一个属性并绘制
        while (iterator.Next(false))
        {
            EditorGUILayout.PropertyField(iterator);
        }
    
        this.serializedObject.ApplyModifiedProperties();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
第二种,调用ScriptableObject Inspector的绘制

既然ScriptableObject有自己的Inspector绘制,那么我们就可以直接调用Inspector的Editor绘制,而不需要自己手动遍历SerializedObject的属性。

public class EditorWindows : EditorWindow
{
    private Editor editor;

    [MenuItem("ExtendingEditor/ShowObject Window")]
    public static void ShowObjectWindow() 
    {
        var window = EditorWindow.GetWindow<EditorWindows>(true, "ShowObject Window", true);
        // 直接根据ScriptableObject构造一个Editor
        window.editor = Editor.CreateEditor(ScriptableObject.CreateInstance<ShowObject>());
    }

    private void OnGUI() 
    {
        // 直接调用Inspector的绘制显示
        this.editor.OnInspectorGUI();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
效果

更多设想

既然ScriptableObject有自己的Inspector的Editor绘制,那么我们就可以自定义扩展它,然后就可以直接显示在EditorWindows里面了。比如:

// 自定义ScriptableObject的Editor显示
[CanEditMultipleObjects, CustomEditor(typeof(ShowObject))]
public class ShowObjectEditor : Editor
{
}
  • 1
  • 2
  • 3
  • 4
  • 5

当然,也可以使用PropertyDrawer和PropertyAttribute来进行扩展。


「简化自定义窗口工作」


MojoUnity-Editor:一个简单通用的Unity属性面板(Inspector)和窗口(Window)的扩展

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/100117
推荐阅读
相关标签
  

闽ICP备14008679号