一、用户编程
1、实现两个按钮的添加和删除功能
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中正确地显示出来。