UIToolkit编辑器练习(一)

写一个UIToolkit的文章,记录一下UIToolkit的使用方式(一阵时间不用都快忘了),顺便写一个简单的物品编辑器
数据保存为xml,使用LinqToXml,编辑器使用UIToolkit制作


需要UIBuilder插件

1.创建Editor窗口

通过Assets->Create->UIToolkit->Editor Window创建窗口ItemDBEditor(可以只选C#和uxml)
然后通过UIBuilder,做一个简单的窗口
UIToolkit编辑器练习(一)
然后修改ItemEditor的代码,将修改一下创建窗口的代码

	//这里填工具栏路径
    [MenuItem("Editor/ItemDBEditor")]
    public static void ShowWindow()
    {
        ItemDBEditor wnd = GetWindow<ItemDBEditor>();
        wnd.titleContent = new GUIContent("ItemDBEditor");
    }

    private void OnEnable()
    {
        VisualElement root = rootVisualElement;
        //这里填上自己的uxml路径
        var xml = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/ItemSystem/ItemDBEditor.uxml");
        xml.CloneTree(rootVisualElement);
    }

这时候在Unity中通过工具栏Editor->ItemEditor打开编辑器了

2.生成Xml

在这里我主要使用LinqToXml,因为比较方便
首先在编辑器的Toolbar中添加一个ToolbarButton,用来生成Xml文件(当然最初始的文件也可以手动创建)
UIToolkit编辑器练习(一)
然后添加代码

private void OnEnable()
{
	//...
	//为这个Button注册创建xml的事件
	ToolbarButton AddXmlButton = root.Q<ToolbarButton>("CreateXml");
        AddXmlButton.clicked += () => 
        {
            string filePath = Application.dataPath + @"/ItemDB.xml";
            if (!File.Exists(filePath))
            {
                //创建XML文档实例
                XmlDocument xmlDoc = new XmlDocument();
                //创建root节点,也就是最上一层节点
                XmlElement xRoot = xmlDoc.CreateElement("ItemDatabase");
                xmlDoc.AppendChild(xRoot);

                xmlDoc.Save(filePath);
                Debug.Log("createXml OK!");
                AssetDatabase.Refresh();
            }
        };
}

这个时候就发现Xml就已经创建出来了

3.为Xml添加元素

先要创建一个ItemManager来管理物品

public class ItemManager : Singleton<ItemManager>
{
    //文件位置
    private static string filePath = Application.dataPath + @"/ItemDB.xml";
    private XDocument xDoc;
    private XElement root;
    
    public ItemManager()
    {
        Refresh();
    }
    
    //添加元素
    public void AddElement(CItem obj)
    {
        root.Add(obj.GetXElement());
        Save();
    }

    //更新函数
    public void Refresh()
    {
        if (File.Exists(filePath))
        {
            xDoc = XDocument.Load(filePath);
            root = xDoc.Root;
            Debug.Log("Refresh Success!");
        }
    }

    //保存为Xml
    private void Save()
    {
        if (File.Exists(filePath) && xDoc != null)
        {
            xDoc.Save(filePath);
            Debug.Log("Save Success!");
            AssetDatabase.Refresh();
        }
    }
}

创建一个CItem,里面设置一些基本的属性,并添加一个返回XElement的函数

public enum CItemType
{
    Equipment,
    Food,
    Medicine,
    Material
}

public class CItem
{
    public string name;
    public int id;
    //public Texture2D icon;
    public CItemType itemType;
    public int itemAmount;

    public XElement GetXElement()
    {
        XElement item = new XElement("Item",
                new XElement("Name", name),
                new XElement("ID", id),
                new XElement("ItemType", (int)itemType),
                new XElement("ItemAmount", itemAmount)
                );
        return item;
    }
}

Icon还没想好怎么做

这时候我们在编辑器中测试一下
添加一个新的按钮,并注册函数
UIToolkit编辑器练习(一)

	private void OnEnable()
    {
    	//...
		ToolbarButton AddElementButton = root.Q<ToolbarButton>("AddElement");
        AddElementButton.clicked += () => 
        {
            CItem item = new CItem()
            {
                name = "木剑",
                id = 10000001,
                itemType = CItemType.Equipment,
                itemAmount = 1
            };
            ItemManager.Instance.AddElement(item);
        };
    }

点击按钮就成功在xml中添加了新元素,接下来我们先用这种方式添加一些元素

<?xml version="1.0" encoding="utf-8"?>
<ItemDatabase>
  <Item>
    <Name>木剑</Name>
    <ID>10000001</ID>
    <ItemType>0</ItemType>
    <ItemAmount>1</ItemAmount>
  </Item>
  <Item>
    <Name>铁剑</Name>
    <ID>10000002</ID>
    <ItemType>0</ItemType>
    <ItemAmount>1</ItemAmount>
  </Item>
  <Item>
    <Name>初级生命药水</Name>
    <ID>10000003</ID>
    <ItemType>2</ItemType>
    <ItemAmount>99</ItemAmount>
  </Item>
  <Item>
    <Name>初级魔力药水</Name>
    <ID>10000004</ID>
    <ItemType>2</ItemType>
    <ItemAmount>99</ItemAmount>
  </Item>
</ItemDatabase>

4.使用ListView展示列表

先在UIBuilder中创建一个ListView
UIToolkit编辑器练习(一)
那么这个时候就需要在ItemManager中添加获取所有元素的函数

    public IEnumerable<XElement> GetAllElements()
    {
        IEnumerable<XElement> nodes = from p in root.Elements("Item") select p;
        return nodes;
    }

然后在Editor中为它添加函数

	//ItemList
	private ListView itemList;
	//保存的XElement数据
    private List<XElement> datas;
    private void OnEnable()
    {
    	//...
    	//寻找ListView
        itemList = root.Q<ListView>("ItemList");
        //加载数据
        datas = new List<XElement>(ItemManager.Instance.GetAllElements());
        //makeItem创建单个组件
        Func<VisualElement> makeItem = () => new Label();
        //bindItem绑定数据
        Action<VisualElement, int> bindItem = (e, i) => (e as Label).text = datas[i].Element("Name").Value;

        //设置一下
        itemList.itemsSource = datas;
        itemList.itemHeight = 20;
        itemList.makeItem = makeItem;
        itemList.bindItem = bindItem;
        itemList.selectionType = SelectionType.Single;
    }

这时候再打开编辑器,就会发现数据已经显示在了ListView中
UIToolkit编辑器练习(一)

5.修改xml编辑器内同步显示

在Editor中添加一个OnFocus函数,刷新数据即可

    private void OnFocus()
    {
        ItemManager.Instance.Refresh();
        datas = new List<XElement>(ItemManager.Instance.GetAllElements());
        itemList.itemsSource = datas;
        itemList.Refresh();
    }

这样,当我们手动在xml中添加数据,在编辑器中也会同步修改了

上一篇:LINQ to XML


下一篇:C#Linq to XML的简单读写