引擎综合项目day4

134 阅读3分钟

image.png

一、什么是UI ToolKit

1.前言

我们之前使用过的UI解决方案有UGUI,这里学习的UIToolKit是unity新推出的UI解决方案,目的是为了让我们更高效得开发出可复性性高且复杂的UI界面

2.UI ToolKit设计原理

image.png

二、背包数据初始化

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.这里出现的中括号相关的代码参考其他博客文档

blog.csdn.net/qq_32065601…

4.在Script文件中创建一个inventory类库存放我们的SO数据类

image.png

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来存放我们的数据库的信息

image.png

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

image.png

- 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)
            {
                
            }*/
        }
    }
}

image.png