Unity 2021 已经把UIBuilder 内置了,项目组也打算 后续工具采用 toolkit来写,这边也是找了一下教程熟悉了一下。
UI 工具包 - Unity 手册
首先 先创建一个EditorWindow
会生成相应的C#,UXML,USS代码
默认会把显示的MenuItem代码生成,以及Root VisualElement生成,会默认加载对应的uxml文件。
[MenuItem("Tools/TestTool")]
public static void ShowExample()
{
TestTool wnd = GetWindow<TestTool>();
wnd.titleContent = new GUIContent("TestToolPanel");
}
public void CreateGUI()
{
// Each editor window contains a root VisualElement object
VisualElement root = rootVisualElement;
// VisualElements objects can contain other VisualElement following a tree hierarchy.
VisualElement label = new Label("Hello World! From C#");
root.Add(label);
// Import UXML
var visualTree = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/Cube/delete.uxml");
VisualElement labelFromUXML = visualTree.Instantiate();
root.Add(labelFromUXML);
// A stylesheet can be added to a VisualElement.
// The style will be applied to the VisualElement and all of its children.
var styleSheet = AssetDatabase.LoadAssetAtPath<StyleSheet>("Assets/Cube/delete.uss");
VisualElement labelWithStyle = new Label("Hello World! With Style");
labelWithStyle.styleSheets.Add(styleSheet);
root.Add(labelWithStyle);
}
新的方式 是通过 像Root 结点添加 各种组件的方式,可以在 UIBuilder面板上操作,也可以代码添加。
代码添加:
var rightPart = root.Q<VisualElement>("right");
HelpBox tipBox = new HelpBox("Test Tip", HelpBoxMessageType.Info);
rightPart.Add(tipBox);
想使用 面板上的 结点可以采用代码查找Name的方式:
_objFiled = root.Q<ObjectField>("ObjectField");
还可以给某些组件 添加事件,比如 Toggle
toggle.RegisterValueChangedCallback(TogValueChanged);
private void TogValueChanged(ChangeEvent<bool> evt)
{
// evt.newValue
}
按钮组件的 事件 绑定:
_createBtn = root.Q<Button>("CreateBtn");
_createBtn.clicked += CreateEvent;
ListView组件的使用:
_leftList = root.Q<ListView>("LeftListView");
//赋值
_leftList.itemsSource = _objs;
//单个Item
_leftList.makeItem = MakeListItem;
//数据绑定
_leftList.bindItem = BindListItem;
//List Item 选中事件
_leftList.onSelectionChange += OnSelectChange;
新版UI 也支持 IMGUI嵌入
//嵌入IMGUI
rightPart.Add(new IMGUIContainer(() =>
{
if (GUILayout.Button("TestBtn"))
{
Debug.Log("TestLog");
}
}));
支持计时器任务:
//计时器(默认 打开界面 就会执行)
var scheduleItem = root.schedule.Execute(() =>
{
Debug.Log("Schedule Event");
});
//间隔2秒执行一次
//scheduleItem.Every(2000);
//打开页面之后延迟两秒执行
//scheduleItem.ExecuteLater(2000);
完整代码:
//打开页面执行一次
public void CreateGUI()
{
// Each editor window contains a root VisualElement object
VisualElement root = rootVisualElement;
// Import UXML
var visualTree = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/Editor/Test/TestTool.uxml");
VisualElement labelFromUXML = visualTree.Instantiate();
root.Add(labelFromUXML);
var rightPart = root.Q<VisualElement>("right");
HelpBox tipBox = new HelpBox("Test Tip", HelpBoxMessageType.Info);
rightPart.Add(tipBox);
_objFiled = root.Q<ObjectField>("ObjectField");
if (_objFiled != null)
{
_objFiled.objectType = typeof(GameObject);
_objFiled.allowSceneObjects = false;
//注册一个回调 当有变化的时候
_objFiled.RegisterValueChangedCallback((obj) => { Debug.Log(obj.newValue.name); });
}
_createBtn = root.Q<Button>("CreateBtn");
_createBtn.clicked += CreateEvent;
_refreshBtn = root.Q<Button>("RefreshBtn");
_refreshBtn.clicked += RefreshEvent;
_leftList = root.Q<ListView>("LeftListView");
_leftList.onSelectionChange += OnSelectChange;
_nameText = root.Q<TextField>("NameTextField");
_posText = root.Q<Vector3Field>("PosField");
//数据绑定
_nameText.bindingPath = "m_Name";
_posText.bindingPath = "m_LocalPosition";
//嵌入IMGUI
rightPart.Add(new IMGUIContainer(() =>
{
if (GUILayout.Button("TestBtn"))
{
Debug.Log("TestLog");
}
}));
//计时器(默认 打开界面 就会执行)
var scheduleItem = root.schedule.Execute(() =>
{
Debug.Log("Schedule Event");
});
//间隔2秒执行一次
//scheduleItem.Every(2000);
//打开页面之后延迟两秒执行
//scheduleItem.ExecuteLater(2000);
}
private void OnSelectChange(IEnumerable<object> obj)
{
foreach (var item in obj)
{
GameObject go = item as GameObject;
Selection.activeGameObject = go;
SerializedObject serializedObj = new SerializedObject(go);
_nameText.Bind(serializedObj);
SerializedObject serializedTrans = new SerializedObject(go.transform);
_posText.Bind(serializedTrans);
}
}
private void BindListItem(VisualElement arg1, int index)
{
Label label = arg1 as Label;
var go = _objs[index];
label.text = go.name;
}
private VisualElement MakeListItem()
{
var label = new Label();
label.style.unityTextAlign = TextAnchor.MiddleCenter;
label.style.marginLeft = 5;
return label;
}
private void CreateEvent()
{
if (_objFiled.value == null)
{
return;
}
GameObject prefab = _objFiled.value as GameObject;
GameObject obj = Instantiate(prefab);
obj.transform.position = new Vector3(Random.Range(0, 10), 0, Random.Range(0, 10));
}
private void RefreshEvent()
{
Scene currentScene = SceneManager.GetActiveScene();
_objs = currentScene.GetRootGameObjects();
_leftList.itemsSource = _objs;
_leftList.makeItem = MakeListItem;
_leftList.bindItem = BindListItem;
}
同时UIToolKit 也支持 脚本编辑器扩展:文章来源:https://www.toymoban.com/news/detail-521513.html
[CustomEditor(typeof(TestCube))]
public class TestCubeEditor : Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
}
//该函数优先级大于上面
public override VisualElement CreateInspectorGUI()
{
//return base.CreateInspectorGUI();
VisualElement root = new VisualElement();
Button testBtn = new Button();
testBtn.style.width = 200;
root.Add(testBtn);
Label testLabel = new Label("TestLabel");
root.Add(testLabel);
Toggle tog = new Toggle();
root.Add(tog);
return root;
}
}
文章来源地址https://www.toymoban.com/news/detail-521513.html
到了这里,关于UI Tool Kit 使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!