一、用户编程

1、完成两个按钮的增加和删去功用

Unity3D 游戏开发:背包数据界面 创建按钮的添加和删除数据功能(17)
Unity3D 游戏开发:背包数据界面 创建按钮的添加和删除数据功能(17)

using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.UIElements;
using System.Collections.Generic;
using System;
using System.Linq;
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 defultIcon;
    private VisualElement iconPreview;
    //取得Visual Element 
    private ListView itemlistView;
    [MenuItem("Lzj/ItemEditor")] 
    public static void ShowExample()
    {
        ItemEditor wnd = GetWindow<ItemEditor>();
        wnd.titleContent = new GUIContent("ItemEditor");
    }
    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.uxml");
        VisualElement labelFromUXML = visualTree.Instantiate();
        root.Add(labelFromUXML);
        //拿到模板数据
        itemRowTemplate = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/Editor/UI Builder/ItemRowTemplates.uxml");
        //拿到默许Icon图片
        defultIcon = AssetDatabase.LoadAssetAtPath<Sprite>("Assets/M Studio/Art/Items/Icons/Lzj.jpg");
        //变量赋值,取得控制权
        itemlistView = root.Q<VisualElement>("ItemList").Q<ListView>("ListView");
        itemDetailsSection = root.Q <ScrollView>("ItemDetails");
        iconPreview = itemDetailsSection.Q<VisualElement>("Icon");
        //取得Button
        root.Q<Button>("AddButton").clicked += OnAddItemCliked;
        root.Q<Button>("DeleteButton").clicked += OnDeleteItemCliked;
        //加载数据
        LoadDataBase();
        //生成ListView
        GenerateListView(); 
    }
    # region 按键事情
    private void OnDeleteItemCliked()
    {
        itemList.Remove(activeItem);
        itemlistView.Rebuild();
        itemDetailsSection.visible =false;
    }
    private void OnAddItemCliked()
    {
        ItemDetails newItem = new ItemDetails();
        newItem.itemName = "NEW NAME";
        newItem .itemID =1000+itemList.Count;
        itemList .Add(newItem);
        itemlistView.Rebuild();
    }
    #endregion 
    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.itemDataList;
        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 += OnListSelectionChane;
        //右侧信息不行见
        itemDetailsSection.visible= false;
    }
    private void OnListSelectionChane(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();
        });
        itemDetailsSection.Q<EnumField>("ItemType").value = activeItem.itemType;
        itemDetailsSection.Q<EnumField>("ItemType").RegisterValueChangedCallback(evt =>
        {
            activeItem.itemType = (ItemType)Enum.Parse(typeof(ItemType), evt.newValue.ToString());
        });
        iconPreview.style.backgroundImage = activeItem.itemIcon == null ? defultIcon.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 ?defultIcon.texture: newIcon.texture;
            itemlistView.Rebuild();
        });
        itemDetailsSection.Q<ObjectField>("ItemSprite").value = activeItem.itemOnWorldSprite;
        itemDetailsSection.Q<ObjectField>("ItemSprite").RegisterValueChangedCallback(evt =>
        {
            Sprite newIcon = evt.newValue as Sprite;
            activeItem.itemOnWorldSprite = newIcon;
        });
        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>("CanPickup").value = activeItem.canPickup;
        itemDetailsSection.Q<Toggle>("CanPickup").RegisterValueChangedCallback(evt=>
        { 
            activeItem.canPickup=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;
        });
    } 
} 

二、开始了解脚本编程

1、取得Button

    root.Q<Button>("AddButton").clicked += OnAddItemCliked;
    root.Q<Button>("DeleteButton").clicked += OnDeleteItemCliked;

1)、代码是在UI界面中找到名为”AddButton”的Button控件,并注册了一个点击事情OnAddItemCliked。当用户点击该按钮时,会触发OnAddItemCliked()方法。这个方法完成了增加新条目的逻辑

2)、在这里,clicked是一个Unity UIElements中的事情(event),用于表明当该元素被点击时触发的事情,类似于一些其他UI框架中的Click()方法。

3)、运用+=操作符,咱们将OnAddItemCliked()方法与Button的clicked事情绑定起来了。这意味着,当该Button被点击时,就会调用OnAddItemCliked()方法。

2、增加按键事情

private void OnDeleteItemCliked()
{
    itemList.Remove(activeItem);
    itemlistView.Rebuild();
    itemDetailsSection.visible =false;
}
private void OnAddItemCliked()
{
    ItemDetails newItem = new ItemDetails();
    newItem.itemName = "NEW NAME";
    newItem .itemID =1000+itemList.Count;
    itemList .Add(newItem);
    itemlistView.Rebuild();
}

1)、itemList.Remove(activeItem):

这行代码的作用是从itemList列表中移除activeItem目标。在代码里,activeItem是当时被挑选的ItemDetails目标。

当用户点击UI界面中的”DeleteButton”按钮时,就会触发该代码。在删去前,咱们需求将该目标从列表中移除,并更新ListView。

2)、itemDetailsSection.visible =false:

itemDetailsSection是一个Unity UIElements中的ScrollView目标,用于展现当时挑选的ItemDetails目标的详细信息。当用户没有挑选任何ItemDetails目标时,咱们期望这个ScrollView不行见,以防止UI界面上的一些不必要的搅扰。这时就会运用到这行代码。

详细地说,visible是一个属性(property),它控制目标是否可见。经过将visible属性设置为false,咱们可以让itemDetailsSection在UI界面上不行见,然后到达躲藏的作用。

3)ItemDetails newItem = new ItemDetails():

这行代码的作用是创立一个新的ItemDetails目标,并将其赋值给变量newItem。在代码中,ItemDetails是一个自定义的类,用于存储游戏物品的详细信息,比方称号、图标、类型等等。

当用户点击UI界面中的”AddButton”按钮时,就会触发该代码。咱们需求增加一个新的ItemDetails目标到itemList列表中,以完成增加新条目的功用。

4)、itemList.Count

itemList.Count表明itemList这个列表中元素的数量,即列表中包括多少个元素。

在代码中,咱们运用了这行代码来获取itemList列表的长度。目的是在UI界面中更新列表的显现,以展现最新的信息。详细而言,咱们需求保证ListView包括与itemList中相同数量的子元素,以便正确地显现一切的游戏物品详细信息。

5)、itemList .Add(newItem):

itemList.Add(newItem)是将一个新的ItemDetails目标增加到itemList列表中去。在代码中,newItem是咱们创立的新目标,它包括了一个游戏物品的详细信息。

当咱们想要在UI界面中增加一个新的游戏物品时,就需求运用这行代码。它会将新游戏物品的详细信息增加到itemList列表中去,以便能在ListView中正确地显现出来。

三、未完待续……

阅读更多作者文章:

Unity3D 游戏开发:用户界面(Editor)绑定Editor Windows中的参数变量(16)