zoukankan      html  css  js  c++  java
  • Unity编辑器开发:官方风格的Table控件

    Unity编辑器开发:官方风格的Table控件

    Table控件能够非常直观地展现批量的数据。在Unity中,Light Explorer就是一个典型的具有Table控件的窗口。

    20170729_1

    如上图所示,窗口上方是4个TabButton。下面就是一个Table。这个Table功能非常强大,有列表,排序,筛选,实时同步数据更新,实时同步选择等功能。

    在Unity项目开发中,也常常需要做这种Table数据的展示或者类似的功能,比如简单的一个需求,找出当前场景中所有的Camra,并显示它的某些属性。用Table控件展示如下

    20170729_2

    这个是一个简单的窗口,满足上述的需求。这种官方风格的Table窗口不仅在功能上满足了需求,在外观上非常OK。

    在实现上,这种控件,其实是Unity提供的TreeView控件的扩展。Light Explorer中使用到了继承于TreeView的SerializedPropertyTreeView。但是非常遗憾的是,目前SerializedPropertyTreeView是internal的class,所以我们无法通过继承来实现。查看它的源码可以看到,有部分代码依赖了内部的类,或者这也是官方无法公开这个SerializedPropertyTreeView的原因。但是,如果去除掉一些无关紧要的功能,事实上是完全可以脱耦而独立出来。涉及到SerializedPropertyTable,SerializedPropertyTreeView,SerializedPropertyFilters以及SerializedPropertyDataStore这4个类。

    而在使用时,也较为简单,提供一个搜索方法,列信息即可。比如完成上面提到的显示相机的需求,可以用以下代码:

    首先定义一个窗口,实现从菜单打开

    public class ComponentFindWindow : EditorWindow
    {
            [MenuItem("Tools/Windows/ComponentFindWindow")]
            public static void Open()
            {
                GetWindow<ComponentFindWindow>();
            }

    }

    在ComponentFindWindow中增加一个SerializedPropertyTable声明,并进行绘制

    private SerializedPropertyTable m_table;

    public void OnGUI()
    {
        using (new EditorGUILayout.VerticalScope())
        {
            if (m_table != null)
            {
                m_table.OnGUI();
            }
        }
    }
    当然,这时候什么都不会发生,我们还要对m_table进行实例化

    public void OnEnable()
    {
        m_table = new SerializedPropertyTable("Table", FindObjects, CreateCameraColumn);
    }

    SerializedPropertyTable的构造函数有3个参数

    • 第一个是唯一的标签。用于表示这个TreeView序列号信息的ID
    • 第二个是显示内容的搜索函数。例如我们要显示所有的Camera,就要提供找到这个Camera的方法
    • 第三个是列信息。包括列名,长度,可拉伸的最大最小长度,对齐方式,是否可排序,列的绘制方法,排序方法,筛选方法等等

    这里FindObjects声明如下

    private Camera[] FindObjects()
    {
        return FindObjectsOfType<Camera>();
    }

    创建列方法CreateCameraColumn如下

    private SerializedPropertyTreeView.Column[] CreateCameraColumn(out string[] propnames)
    {
        propnames = new string[3];
        var columns = new SerializedPropertyTreeView.Column[3];
        columns[0] = new SerializedPropertyTreeView.Column
        {
            headerContent = new GUIContent("Name"),
            headerTextAlignment = TextAlignment.Left,
            sortedAscending = true,
            sortingArrowAlignment = TextAlignment.Center,
            width = 200,
            minWidth = 25f,
            maxWidth = 400,
            autoResize = false,
            allowToggleVisibility = true,
            propertyName = null,
            dependencyIndices = null,
            compareDelegate = SerializedPropertyTreeView.DefaultDelegates.s_CompareName,
            drawDelegate = SerializedPropertyTreeView.DefaultDelegates.s_DrawName,
            filter = new SerializedPropertyFilters.Name()
        };
        columns[1] = new SerializedPropertyTreeView.Column
        {
            headerContent = new GUIContent("On"),
            headerTextAlignment = TextAlignment.Left,
            sortedAscending = true,
            sortingArrowAlignment = TextAlignment.Center,
            width = 25,
            autoResize = false,
            allowToggleVisibility = true,
            propertyName = "m_Enabled",
            dependencyIndices = null,
            compareDelegate = SerializedPropertyTreeView.DefaultDelegates.s_CompareCheckbox,
            drawDelegate = SerializedPropertyTreeView.DefaultDelegates.s_DrawCheckbox,
        };

        columns[2] = new SerializedPropertyTreeView.Column
        {
            headerContent = new GUIContent("Mask"),
            headerTextAlignment = TextAlignment.Left,
            sortedAscending = true,
            sortingArrowAlignment = TextAlignment.Center,
            width = 200,
            minWidth = 25f,
            maxWidth = 400,
            autoResize = false,
            allowToggleVisibility = true,
            propertyName = "m_CullingMask",
            dependencyIndices = null,
            compareDelegate = SerializedPropertyTreeView.DefaultDelegates.s_CompareInt,
            drawDelegate = SerializedPropertyTreeView.DefaultDelegates.s_DrawDefault,
            filter = new SerializedPropertyFilters.Name()
        };
        for (var i = 0; i < columns.Length; i++)
        {
            var column = columns[i];
            propnames[i] = column.propertyName;
        }

        return columns;
    }
    至此,就实现了所有功能。

    这个控件实用性非常高,非常希望Unity团队能够早日把这个控件公开。

    项目地址:https://github.com/CodeGize/UnityTable

    个人博客请访问:http://www.cnblogs.com/CodeGize/
  • 相关阅读:
    tensorflow 2.0 学习 (十) 拟合与过拟合问题
    tensorflow 2.0 学习 (九) tensorboard可视化功能认识
    tensorflow 2.0 学习 (八) keras模块的认识
    tensorflow 2.0 学习 (七) 反向传播代码逐步实现
    tensorflow 2.0 学习 (六) Himmelblua函数求极值
    tensorflow 2.0 学习 (五)MPG全连接网络训练与测试
    arp协议简单介绍
    Pthread spinlock自旋锁
    线程和进程状态
    内核态(内核空间)和用户态(用户空间)的区别和联系·
  • 原文地址:https://www.cnblogs.com/CodeGize/p/7255738.html
Copyright © 2011-2022 走看看