Table控件可以很是直觀地展示批量的數據。在Unity中,Light Explorer就是一個典型的具備Table控件的窗口。 git
如上圖所示,窗口上方是4個TabButton。下面就是一個Table。這個Table功能很是強大,有列表,排序,篩選,實時同步數據更新,實時同步選擇等功能。 github
在Unity項目開發中,也經常須要作這種Table數據的展現或者相似的功能,好比簡單的一個需求,找出當前場景中全部的Camra,並顯示它的某些屬性。用Table控件展現以下 編輯器
這個是一個簡單的窗口,知足上述的需求。這種官方風格的Table窗口不只在功能上知足了需求,在外觀上很是OK。 函數
在實現上,這種控件,實際上是Unity提供的TreeView控件的擴展。Light Explorer中使用到了繼承於TreeView的SerializedPropertyTreeView。可是很是遺憾的是,目前SerializedPropertyTreeView是internal的class,因此咱們沒法經過繼承來實現。查看它的源碼能夠看到,有部分代碼依賴了內部的類,或者這也是官方沒法公開這個SerializedPropertyTreeView的緣由。可是,若是去除掉一些可有可無的功能,事實上是徹底能夠脫耦而獨立出來。涉及到SerializedPropertyTable,SerializedPropertyTreeView,SerializedPropertyFilters以及SerializedPropertyDataStore這4個類。 blog
而在使用時,也較爲簡單,提供一個搜索方法,列信息便可。好比完成上面提到的顯示相機的需求,能夠用如下代碼: 排序
首先定義一個窗口,實現從菜單打開 繼承
public class ComponentFindWindow : EditorWindow
{
[MenuItem("Tools/Windows/ComponentFindWindow")]
public static void Open()
{
GetWindow<ComponentFindWindow>();
}開發
}get
在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個參數
這裏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團隊可以早日把這個控件公開。