UI Toolkit系统学习

UI Toolkit
此文章用于学习UnityUI系统,手头的项目做完会来完善
官方文档
Unity上方菜单栏点击Window->UI Toolkit->Samples可以看UI Toolkit中的很多样例

使用 UI Toolkit 和 UI Builder 制作物品编辑器

在文件夹中右键->Create->UI Toolkit->Editor Window
出现以下窗口
在这里插入图片描述
输入名字创建窗口
文件夹中出现三个文件
在这里插入图片描述
从这步开始就能点击Unity上方菜单栏召唤自己写的Editor Window了

点击ItemEditor进入UIBuilder,用里面的工具创建需要的UI面板
在这里插入图片描述

创建 ListView 中的 ItemTemplate

再创建一个UIDocument,作为ItemList中每一个物体显示的模板
在这里插入图片描述

生成 ListView 列表

实现ItemTemplate读取数据库中物品数据并将其呈现在ListView上的方法

public class ItemEditor : EditorWindow
{private ItemDataList_SO dataBase;private List<ItemDetails> itemList = new List<ItemDetails>();private VisualTreeAsset itemRowTemplate;private ListView itemListView;[MenuItem("Editor/ItemEditor")]public static void ShowExample(){ItemEditor wnd = GetWindow<ItemEditor>();wnd.titleContent = new GUIContent("ItemEditor");}public void CreateGUI(){VisualElement root = rootVisualElement;var visualTree = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/Editor/UIBuilder/ItemEditor.uxml");VisualElement labelFromUXML = visualTree.Instantiate();root.Add(labelFromUXML);//拿到模板数据itemRowTemplate =AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/Editor/UIBuilder/ItemRowTemplate.uxml");//变量赋值itemListView = root.Q<VisualElement>("ItemList").Q<ListView>("ListView");LoadDataBase();GenerateListView();}/// <summary>/// 从数据库中加载文件/// </summary>private void LoadDataBase(){var dataArray=AssetDatabase.FindAssets("ItemDataList_SO");if (dataArray.Length > 1){var path = AssetDatabase.GUIDToAssetPath(dataArray[0]);//找到文件中对应的路径dataBase = AssetDatabase.LoadAssetAtPath(path, typeof(ItemDataList_SO)) as ItemDataList_SO;}itemList = dataBase.itemDetailsList;//如果不标记则无法保存数据EditorUtility.SetDirty(dataBase);}private void GenerateListView(){Func<VisualElement> makeItem = () => itemRowTemplate.CloneTree();//创建Action<VisualElement, int> bindItem = (e, i) =>{//在ItemTemplate上绑定数据if (i < itemList.Count){if (itemList[i].itemIcon != null){e.Q<VisualElement>("Icon").style.backgroundImage = itemList[i].itemIcon.texture;}e.Q<Label>("Name").text = itemList[i] == null ? "NO ITEM" : itemList[i].itemName;}};//将ItemTemplate呈现在ListView里itemListView.fixedItemHeight = 60;itemListView.itemsSource = itemList;itemListView.makeItem = makeItem;itemListView.bindItem = bindItem;}
}

makeItem会在每次添加新物品时调用——在数据绘制到窗口时会根据数据的数目逐一增加一个Item的时候
bindItem每个窗口显示的具体内容
itemsSource对应itemList里面的每一个数据

绑定 Editor Window 中的参数变量,实现 ListView 添加删除同步信息功能

实现在右侧面板中显示物体对应的信息

public class ItemEditor : EditorWindow
{private ItemDataList_SO dataBase;private List<ItemDetails> itemList = new List<ItemDetails>();private VisualTreeAsset itemRowTemplate;private ScrollView itemDetailsSection;private ItemDetails activeItem;//默认预览图片private Sprite defaultIcon;private VisualElement iconPreview;//获得VisualElementprivate ListView itemListView;[MenuItem("M STUDIO/ItemEditor")]public static void ShowExample(){ItemEditor wnd = GetWindow<ItemEditor>();wnd.titleContent = new GUIContent("ItemEditor");}public void CreateGUI(){// Each editor window contains a root VisualElement objectVisualElement root = rootVisualElement;// VisualElements objects can contain other VisualElement following a tree hierarchy.// VisualElement label = new Label("Hello World! From C#");// root.Add(label);// Import UXMLvar visualTree = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/Editor/UI Builder/ItemEditor.uxml");VisualElement labelFromUXML = visualTree.Instantiate();root.Add(labelFromUXML);//拿到模版数据itemRowTemplate = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/Editor/UI Builder/ItemRowTemplate.uxml");//拿默认Icon图片defaultIcon = AssetDatabase.LoadAssetAtPath<Sprite>("Assets/M Studio/Art/Items/Icons/icon_M.png");//变量赋值itemListView = root.Q<VisualElement>("ItemList").Q<ListView>("ListView");itemDetailsSection = root.Q<ScrollView>("ItemDetails");iconPreview = itemDetailsSection.Q<VisualElement>("Icon");//获得按键root.Q<Button>("AddButton").clicked += OnAddItemClicked;root.Q<Button>("DeleteButton").clicked += OnDeleteClicked;//加载数据LoadDataBase();//生成ListViewGenerateListView();}#region 按键事件private void OnDeleteClicked(){itemList.Remove(activeItem);itemListView.Rebuild();itemDetailsSection.visible = false;}private void OnAddItemClicked(){ItemDetails newItem = new ItemDetails();newItem.itemName = "NEW ITEM";newItem.itemID = 1001 + itemList.Count;itemList.Add(newItem);itemListView.Rebuild();}#endregionprivate void LoadDataBase(){var dataArray = AssetDatabase.FindAssets("ItemDataList_SO");//var dataArray = AssetDatabase.FindAssets("t:ItemDataList_SO");  //不同版本写法不一样//if (dataArray.Length >= 1)    //不同版本写法不同if (dataArray.Length > 1){var path = AssetDatabase.GUIDToAssetPath(dataArray[0]);dataBase = AssetDatabase.LoadAssetAtPath(path, typeof(ItemDataList_SO)) as ItemDataList_SO;}itemList = dataBase.itemDetailsList;//如果不标记则无法保存数据EditorUtility.SetDirty(dataBase);// Debug.Log(itemList[0].itemID);}private void GenerateListView(){Func<VisualElement> makeItem = () => itemRowTemplate.CloneTree();Action<VisualElement, int> bindItem = (e, i) =>{if (i < itemList.Count){if (itemList[i].itemIcon != null)e.Q<VisualElement>("Icon").style.backgroundImage = itemList[i].itemIcon.texture;e.Q<Label>("Name").text = itemList[i] == null ? "NO ITEM" : itemList[i].itemName;}};itemListView.fixedItemHeight = 50;  //根据需要高度调整数值itemListView.itemsSource = itemList;itemListView.makeItem = makeItem;itemListView.bindItem = bindItem;itemListView.onSelectionChange += OnListSelectionChange;//右侧信息面板不可见itemDetailsSection.visible = false;}private void OnListSelectionChange(IEnumerable<object> selectedItem){activeItem = (ItemDetails)selectedItem.First();GetItemDetails();itemDetailsSection.visible = true;}private void GetItemDetails(){itemDetailsSection.MarkDirtyRepaint();itemDetailsSection.Q<IntegerField>("ItemID").value = activeItem.itemID;itemDetailsSection.Q<IntegerField>("ItemID").RegisterValueChangedCallback(evt =>{activeItem.itemID = evt.newValue;});itemDetailsSection.Q<TextField>("ItemName").value = activeItem.itemName;itemDetailsSection.Q<TextField>("ItemName").RegisterValueChangedCallback(evt =>{activeItem.itemName = evt.newValue;itemListView.Rebuild();});iconPreview.style.backgroundImage = activeItem.itemIcon == null ? defaultIcon.texture : activeItem.itemIcon.texture;itemDetailsSection.Q<ObjectField>("ItemIcon").value = activeItem.itemIcon;itemDetailsSection.Q<ObjectField>("ItemIcon").RegisterValueChangedCallback(evt =>{Sprite newIcon = evt.newValue as Sprite;activeItem.itemIcon = newIcon;iconPreview.style.backgroundImage = newIcon == null ? defaultIcon.texture : newIcon.texture;itemListView.Rebuild();});//其他所有变量的绑定itemDetailsSection.Q<ObjectField>("ItemSprite").value = activeItem.itemOnWorldSprite;itemDetailsSection.Q<ObjectField>("ItemSprite").RegisterValueChangedCallback(evt =>{activeItem.itemOnWorldSprite = (Sprite)evt.newValue;});itemDetailsSection.Q<EnumField>("ItemType").Init(activeItem.itemType);itemDetailsSection.Q<EnumField>("ItemType").value = activeItem.itemType;itemDetailsSection.Q<EnumField>("ItemType").RegisterValueChangedCallback(evt =>{activeItem.itemType = (ItemType)evt.newValue;});itemDetailsSection.Q<TextField>("Description").value = activeItem.itemDescription;itemDetailsSection.Q<TextField>("Description").RegisterValueChangedCallback(evt =>{activeItem.itemDescription = evt.newValue;});itemDetailsSection.Q<IntegerField>("ItemUseRadius").value = activeItem.itemUseRadius;itemDetailsSection.Q<IntegerField>("ItemUseRadius").RegisterValueChangedCallback(evt =>{activeItem.itemUseRadius = evt.newValue;});itemDetailsSection.Q<Toggle>("CanPickedup").value = activeItem.canPickedup;itemDetailsSection.Q<Toggle>("CanPickedup").RegisterValueChangedCallback(evt =>{activeItem.canPickedup = evt.newValue;});itemDetailsSection.Q<Toggle>("CanDropped").value = activeItem.canDropped;itemDetailsSection.Q<Toggle>("CanDropped").RegisterValueChangedCallback(evt =>{activeItem.canDropped = evt.newValue;});itemDetailsSection.Q<Toggle>("CanCarried").value = activeItem.canCarried;itemDetailsSection.Q<Toggle>("CanCarried").RegisterValueChangedCallback(evt =>{activeItem.canCarried = evt.newValue;});itemDetailsSection.Q<IntegerField>("Price").value = activeItem.itemPrice;itemDetailsSection.Q<IntegerField>("Price").RegisterValueChangedCallback(evt =>{activeItem.itemPrice = evt.newValue;});itemDetailsSection.Q<Slider>("SellPercentage").value = activeItem.sellPercentage;itemDetailsSection.Q<Slider>("SellPercentage").RegisterValueChangedCallback(evt =>{activeItem.sellPercentage = evt.newValue;});}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/863817.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

leetCode-hot100-动态规划专题

动态规划 动态规划定义动态规划的核心思想动态规划的基本特征动态规划的基本思路例题322.零钱兑换53.最大子数组和72.编辑距离139.单词拆分62.不同路径63.不同路径Ⅱ64.最小路径和70.爬楼梯121.买卖股票的最佳时机152.乘积最大子数组 动态规划定义 动态规划&#xff08;Dynami…

【训练篇】MLU370-M8 完成 qwen1.5-7b-chat-lora训练及推理

文章目录 前言一、平台环境配置二、环境 or 模型准备1.模型下载2.环境准备2.1 modelscope2.2 transformers2.3 accelerate2.4 deepspeed2.5 peft2.6 环境代码修改 3训练代码准备4 代码修改 三&#xff0c;训练后推理验证四.推理效果展示1.微调前2.微调后 前言 本期我们采用魔塔…

distance delayed sound

distance delayed sound 在本章中&#xff0c;我们将讨论在游戏音频中使用距离延迟的重要性。我们将首先通过一个常见的例子——闪电和雷鸣&#xff0c;来展示这种重要性并解释距离延迟音频的基础知识。我们将讨论计算速度、距离和时间的数学和方程式&#xff0c;以确定距离延迟…

数据倾斜优化:Hive性能提升的核心

文章目录 1. 定义2. 数据倾斜2.1 Map2.2 Join2.3 Reduce 3. 写在最后 1. 定义 数据倾斜&#xff0c;也称为Data Skew&#xff0c;是在分布式计算环境中&#xff0c;由于数据分布不均匀导致某些任务处理的数据量远大于其他任务&#xff0c;从而形成性能瓶颈的现象。这种情况在H…

PotPlayer安装及高分辨率设置

第1步&#xff1a; 下载安装PotPlayer软件 PotPlayer链接&#xff1a;https://pan.baidu.com/s/1hW168dJrLBonUnpLI6F3qQ 提取码&#xff1a;z8xd 第2步&#xff1a; 下载插件&#xff0c;选择系统对应的位数进行运行&#xff0c;该文件不能删除&#xff0c;删除后将失效。 …

【强化学习的数学原理】课程笔记--2(贝尔曼最优公式,值迭代与策略迭代)

目录 贝尔曼最优公式最优 Policy求解贝尔曼最优公式求解最大 State Value v ∗ v^* v∗根据 v ∗ v^* v∗ 求解贪婪形式的最佳 Policy π ∗ \pi^* π∗一些证明过程 一些影响 π ∗ \pi^* π∗ 的因素如何让 π ∗ \pi^* π∗ 不 “绕弯路” γ \gamma γ 的影响reward 的…

2024/6/30周报

文章目录 摘要ABSTRACT文献阅读题目问题本文贡献方法LSTMTCN模型总体架构 实验实验结果 深度学习TCN-LSTM代码运行结果 总结 摘要 本周阅读了一篇关于TCN和LSTM进行光伏功率预测的文章&#xff0c;本文提出了一种利用LSTM-TCN预测光伏功率的新模型。它由长短期记忆和时间卷积网…

ThreadPoolExecutor基于ctl变量的声明周期管理

个人博客 ThreadPoolExecutor基于ctl变量的声明周期管理 | iwts’s blog 总集 想要完整了解下ThreadPoolExecutor&#xff1f;可以参考&#xff1a; 基于源码详解ThreadPoolExecutor实现原理 | iwts’s blog ctl字段的应用 线程池内部使用一个变量ctl维护两个值&#xff…

树莓派开发之文件传输

文章目录 一、简介使用U盘传输文件使用SD卡传输文件使用Xftp 7传输文件 二、 总结 一、简介 在树莓派开发中经常会用到文件传输&#xff0c;下面介绍几种树莓派文件传输的几种方法。 使用U盘传输文件 &#xff08;1&#xff09;复制所需传输文件到U盘 &#xff08;2&#…

C++:typeid4种cast转换

typeid typeid typeid是C标准库中提供的一种运算符&#xff0c;它用于获取类型的信息。它主要用于类型检查和动态类型识别。当你对一个变量或对象使用typeid运算符时&#xff0c;它会返回一个指向std::type_info类型的指针&#xff0c;这个信息包含了关于该类型名称、大小、基…

Pikachu靶场--Sql Inject

参考借鉴 pikachu靶场练习&#xff08;详细&#xff0c;完整&#xff0c;适合新手阅读&#xff09;-CSDN博客 数字型注入(post) 这种类型的SQL注入利用在用户输入处插入数值&#xff0c;而不是字符串。攻击者试图通过输入数字来修改SQL查询的逻辑&#xff0c;以执行恶意操作。…

Unity Shader 极坐标

Unity Shader 极坐标 前言项目简单极坐标极坐标变体之方形极坐标变体之圆形拉花 鸣谢 前言 极坐标记录 项目 简单极坐标 极坐标变体之方形 极坐标变体之圆形 拉花 鸣谢 【菲兹杂货铺】【Unity Shader教程】极坐标实现以及极坐标的两种变体

【87 backtrader期权策略】基于50ETF期权的covered-call-strategy

前段时间有读者希望能够实现一个期权策略的模板,这段时间通过akshare下载了期权的数据,并进行了清洗,写了一个最简单的期权策略,供大家参考。 策略逻辑: 这是151 trading strategies中的一个期权策略。 买入50ETF基金,手续费按照万分之二计算,一直持有卖出一个最远期的…

【实施】系统实施方案(软件方案Word)

软件实施方案 二、 项目介绍 三、 项目实施 四、 项目实施计划 五、 人员培训 六、 项目验收 七、 售后服务 八、 项目保障措施 软件开发全套资料获取&#xff1a;私信或者进主页获取。 软件产品&#xff0c;特别是行业解决方案软件产品不同于一般的商品&#xff0c;用户购买软…

13_旷视轻量化网络--ShuffleNet V2

回顾一下ShuffleNetV1:08_旷视轻量化网络--ShuffleNet V1-CSDN博客 1.1 简介 ShuffleNet V2是在2018年由旷视科技的研究团队提出的一种深度学习模型&#xff0c;主要用于图像分类和目标检测等计算机视觉任务。它是ShuffleNet V1的后续版本&#xff0c;重点在于提供更高效的模…

antd Select前端加模糊搜索

背景&#xff1a;前端的小伙伴经常在开发antd Select的时候后端不提供搜索模糊搜索接口&#xff0c;而是全量返回数据&#xff0c;这个时候就需要我们前端自己来写一个模糊搜索了。 效果 代码截图 代码 <SelectshowSearchmode"multiple"options{studioList}filte…

运维锅总详解Prometheus

本文尝试从Prometheus简介、架构、各重要组件详解、relable_configs最佳实践、性能能优化及常见高可用解决方案等方面对Prometheus进行详细阐述。希望对您有所帮助&#xff01; 一、Prometheus简介 Prometheus 是一个开源的系统监控和报警工具&#xff0c;最初由 SoundCloud …

基于模糊神经网络的时间序列预测(以hopkinsirandeath数据集为例,MATLAB)

模糊神经网络从提出发展到今天,主要有三种形式&#xff1a;算术神经网络、逻辑模糊神经网络和混合模糊神经网络。算术神经网络是最基本的&#xff0c;它主要是对输入量进行模糊化&#xff0c;且网络结构中的权重也是模糊权重&#xff1b;逻辑模糊神经网络的主要特点是模糊权值可…

Python技术笔记汇总(含语法、工具库、数科、爬虫等)

对Python学习方法及入门、语法、数据处理、数据可视化、空间地理信息、爬虫、自动化办公和数据科学的相关内容可以归纳如下&#xff1a; 一、Python学习方法 分解自己的学习目标&#xff1a;可以将学习目标分基础知识&#xff0c;进阶知识&#xff0c;高级应用&#xff0c;实…

2024 vue3入门教程:windows系统下部署node环境

一、打开下载的node官网 Node.js — 下载 Node.js 二、根据个人喜好的下载方法&#xff0c;下载到自己的电脑盘符下 三、我用的是方法3下载的压缩包&#xff0c;解压到E盘nodejs目录下&#xff08;看个人&#xff09; 四、配置电脑的环境变量&#xff0c;新建环境变量的时候…