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

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

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

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

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

这个是一个简单的窗口,满足上述的需求。这种官方风格的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

时间: 2024-10-04 15:12:55

Unity编辑器开发:官方风格的Table控件的相关文章

【转】Android官方下拉刷新控件 SwipeRefreshLayout

今天在Google+上看到了SwipeRefreshLayout这个名词,遂搜索了下,发现竟然是刚刚google更新sdk新增加的一个widget,于是赶紧抢先体验学习下. SwipeRefreshLayout SwipeRefreshLayout字面意思就是下拉刷新的布局,继承自ViewGroup,在support v4兼容包下,但必须把你的support library的版本升级到19.1. 提到下拉刷新大家一定对ActionBarPullToRefresh比较熟悉,而如今google推出了

iOS开发基础篇-手写控件

一.手写控件的步骤 1)使用相应的控件类创建控件对象: 2)设置该控件的各种属性: 3)添加空间到视图中: 4)如果是 UIButton 等控件,还需考虑控件的单击事件等: 二.添加 UIButton 单击事件  [topbtn addTarget:self action:@selector(move:) forControlEvents:UIControlEventTouchUpInside]; 1) addTarget:forControlEvents: 方法定义在 UIControl 类中

iOS开发UI篇—手写控件,frame,center和bounds属性

iOS开发UI基础—手写控件,frame,center和bounds属性 一.手写控件 1.手写控件的步骤 (1)使用相应的控件类创建控件对象 (2)设置该控件的各种属性 (3)添加控件到视图中 (4)如果是button等控件,还需考虑控件的单击事件等 (5)注意:View Contollor和view的关系 2.注意点 在OC开发中,Storyboard中的所有操作都可以通过代码实现,程序员一定要熟练掌握代码布局界面的能力! 设置控件监听方法的示例代码如下: [btn addTarget:se

visual studio开发工具的C#主流控件属性一览表

visual studio开发工具的C#主流控件属性一览表 详细的介绍了各控制属性的详细中文介绍 C#控件及常用设计整理 1.窗体 1.常用属性 (1)Name属性:用来获取或设置窗体的名称,在应用程序中可通过Name属性来引用窗体. (2) WindowState属性: 用来获取或设置窗体的窗口状态. 取值有三种: Normal (窗体正常显示). Minimized(窗体以最小化形式显示)和 Maximized(窗体以最大化形式显示). (3)StartPosition属性:用来获取或设置运

Qt开发环境中使用报表控件FastReport遇到的一些问题(二)

上一节中谈到的那个问题:传递的变量内容如果是纯英文,报表报错.经笔者反复测试,找到了解决办法:代码中第5行替换为以下 params<<"my_var"<<"\"xyz\""; 在内容前后用\"把内容括起来,在把报表设计器中Code页的语言设置为非PascalScript就好了. Qt开发环境中使用报表控件FastReport遇到的一些问题(二),布布扣,bubuko.com

IOS开发基础篇--手写控件,frame,center和bounds属性

iOS开发UI基础—手写控件,frame,center和bounds属性 一.手写控件 1.手写控件的步骤 (1)使用相应的控件类创建控件对象 (2)设置该控件的各种属性 (3)添加控件到视图中 (4)如果是button等控件,还需考虑控件的单击事件等 (5)注意:View Contollor和view的关系 2.注意点 在OC开发中,Storyboard中的所有操作都可以通过代码实现,程序员一定要熟练掌握代码布局界面的能力! 设置控件监听方法的示例代码如下: [btn addTarget:se

OS开发UI基础—手写控件,frame,center和bounds属性

OS开发UI基础—手写控件,frame,center和bounds属性 一.手写控件 1.手写控件的步骤 (1)使用相应的控件类创建控件对象 (2)设置该控件的各种属性 (3)添加控件到视图中 (4)如果是button等控件,还需考虑控件的单击事件等 (5)注意:View Contollor和view的关系 2.注意点 在OC开发中,Storyboard中的所有操作都可以通过代码实现,程序员一定要熟练掌握代码布局界面的能力! 设置控件监听方法的示例代码如下: [btn addTarget:sel

HYSwitch - iOS7风格的开关控件

可以自定义控件大小. 可以修改关闭背景色.打开背景色.按钮颜色. 通过block回调. 详见.h文件 GitHub:  https://github.com/rainbownight/HYSwitchExample HYSwitch - iOS7风格的开关控件

iOS开发项目篇—43子控件的细节处理

iOS开发项目篇—43子控件的细节处理 一.升级UI 把之前的UI图片删除,换上新的图片(图片命名一致,规范)没有其他的影响. 删除之后,添加. 替换之后,做一次clear操作. 建议把沙盒中的包删除,删除之后再做一次clear操作. 二.调整转发(模块) 1.设置背景(使用提供的素材图片进行平铺) 为转发微博部分设置背景,考虑到这个部分整体上是一个UIView,可以尝试以下设置. 第一种尝试: 但是这样设置,因为图片是平铺的,所以整个背景会出现线条效果,影响显示,不可行. 第二种尝试: 注意: