一、什么是UI ToolKit
1.前言
我们之前使用过的UI解决方案有UGUI,这里学习的UIToolKit是unity新推出的UI解决方案,目的是为了让我们更高效得开发出可复性性高且复杂的UI界面
2.UI ToolKit设计原理
二、背包数据初始化
1.创建DataCollection存放所有数据集合
在数据集合中创建物品详情列表
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]//让下面生成的对象序列化,这样才可以显示到inspector窗口上
//物品详情列表
public class ItemDetails
{
//物品id
public int itemID;
//物品名字
public string name;
//物品类型
public ItemType itemType;
//物品图片
public Sprite itemIcon;
//物品在世界地图中显示的图片
public Sprite itemOnWorldSprite;
//物品中的描述信息
public string itemDescription;
//物品可显示的网格大小的范围
public int itemUseRadius;
//物品是否可以拾取
public bool canPickedup;
//物品是否可以被扔出
public bool canDropped;
//物品是否可以举着
public bool canCarried;
//物品的价格
public int itemPrice;
//物品的折扣范围 值是0-1
[Range(0,1)]//在检查窗口中显示进度条0到1
public float sellPercentage;
}
2.创建Enum文件存储所有枚举类型的数据
编写存储物品类型的枚举
//Enums文件中存取了所有的枚举类型
//物品的类型
public enum ItemType
{
//种子,商品,家具,
Seed,Commodity,Furniture,
//锄头,砍树的工具,砸石头的工具,割草的工具,浇水的工具,菜篮子,可以被割的杂草
HoeTool,ChopTool,BeakTool,ReapTool,WaterTool,CollectTool,ReapableScenery
}
3.这里出现的中括号相关的代码参考其他博客文档
4.在Script文件中创建一个inventory类库存放我们的SO数据类
5.数据列表类ItemDataList_SO
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
//作用是在Aseets文件夹下,鼠标右键,菜单栏中添加一个按钮项,菜单名为menuName,并执行生成名为fileName的脚本,order为按钮显示顺序,只有一个的时候可以不用填
[CreateAssetMenu(fileName = "ItemDataList_SO",menuName ="Inventory/ItemDataList")]
public class ItemDataList_SO : ScriptableObject
{
public List<ItemDetails> itemDetailsList;
}
复制代码
6.创建GameData来存放我们的数据库的信息
三、使用 UI Toolkit 和 UI Builder 制作物品编辑器
- demo 脚本
using UnityEngine;
using UnityEngine.UIElements;
using UnityEditor.UIElements;
using System.Collections.Generic;
using System.Net;
using static UnityEditor.Progress;
using System;
public class Demo : EditorWindow
{
//先拿到数据
ItemDataList_SO database;
// 拿到 itemDatalist 存放我们的所有数据类别。
List<ItemDetails> itemDataList = new List<ItemDetails> ();
// 定义一个左侧的模板
VisualTreeAsset leftListTemplate;
//定义一个listview
ListView listView;
[MenuItem("UIToolKit/Demo")]////和编辑器交互的代码,表示打升的窗口的位置
public static void ShowExample()
{
Demo wnd = GetWindow<Demo>();
wnd.titleContent = new GUIContent("Demo");
}
public void CreateGUI()
{
// Each editor window contains a root VisualElement object
VisualElement root = rootVisualElement; // 表示更节点
// Import UXML
var visualTree = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/Editor/UI Builder/ItemEditor 1.uxml");
VisualElement labelFromUXML = visualTree.Instantiate(); //visual Tree 克隆出来的VisualElement 阶段
root.Add(labelFromUXML);//在根节点 添加一个VisualElement节点
leftListTemplate = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/Editor/UI Builder/ItemRowTemplate.uxml");
//拿到左侧listview节点
listView = root.Q<VisualElement>("ItemList").Q<ListView>("ListView");//拿到ItemList下面的 listview
//加载数据
loadData();
// 左侧的列表 动态生成 左侧的列表 添加到 listview 节点下面 所以要拿到listview节点
generalLeftTemplate();
}
private void generalLeftTemplate()
{
Func<VisualElement> makeItem = () => leftListTemplate.CloneTree();// 关联动态的模板
Action<VisualElement,int> bindItem = (e, i) =>// e表示我们的模板 ,i表示 模板上的列表的长度
{
//i要小于我的实际数据中的列表长度,要不让直接获取有可能超出列表长度
if (i < itemDataList.Capacity)
// 到这里我们就可以给动态模板中的节点赋值了。
{
if (itemDataList[i].ItemImage != null)
{
e.Q<VisualElement>("Row").Q<VisualElement>("Icon").style.backgroundImage = itemDataList[i].ItemImage.texture;// 加载图片
e.Q<VisualElement>("Row").Q<Label>("Name").text = itemDataList[i].Name;
}
}
};
listView.makeItem = makeItem;
listView.bindItem = bindItem;
listView.itemsSource= itemDataList;
}
private void loadData()
{
// 在asset 文件夹中找到所有的 itemDataList_so类型的类文件
var GuidArray = AssetDatabase.FindAssets("ItemDataList_SO");
if (GuidArray.Length>0)
{
//获取database之前要先拿到路径
var path = AssetDatabase.GUIDToAssetPath(GuidArray[0]);
//拿到路径后呢就可以加载路径了。
database = AssetDatabase.LoadAssetAtPath(path,typeof(ItemDataList_SO))as ItemDataList_SO;
itemDataList = database.itemDetailsList;
// 到目前为止,我们加载到了数据 那么ui界面如果更改了数据 那么怎么才能将数据存起来
EditorUtility.SetDirty(database);
/* Debug.Log(itemDataList[0].Name);
foreach (var i in itemDataList)
{
}*/
}
}
}