写一个UIToolkit的文章,记录一下UIToolkit的使用方式(一阵时间不用都快忘了),顺便写一个简单的物品编辑器
数据保存为xml,使用LinqToXml,编辑器使用UIToolkit制作
需要UIBuilder插件
1.创建Editor窗口
通过Assets->Create->UIToolkit->Editor Window创建窗口ItemDBEditor(可以只选C#和uxml)
然后通过UIBuilder,做一个简单的窗口
然后修改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文件(当然最初始的文件也可以手动创建)
然后添加代码
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还没想好怎么做
这时候我们在编辑器中测试一下
添加一个新的按钮,并注册函数
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
那么这个时候就需要在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中
5.修改xml编辑器内同步显示
在Editor中添加一个OnFocus函数,刷新数据即可
private void OnFocus()
{
ItemManager.Instance.Refresh();
datas = new List<XElement>(ItemManager.Instance.GetAllElements());
itemList.itemsSource = datas;
itemList.Refresh();
}
这样,当我们手动在xml中添加数据,在编辑器中也会同步修改了