如果答案存在于另一个名字下面,我真的很抱歉,但我一直在努力解决这个问题一个星期左右,并且没有找到任何类似的东西。
所以,我正在为一个统一的游戏构建一个Item系统。有一个具有这些属性的Item类
public int ItemId;
public string ItemName;
为简单起见,假设我想要两个派生类,Weapon和Armor,其中包含Weapon的BaseDamage属性和Armor的BaseArmor。
我还想从XML加载ItemContainer类中的项目,理想情况下,从同一个XML文件而不是武器中加载一个,一个用于装甲,一个用于魔药。
我尝试了多种方法,但到目前为止,我能够成功的唯一方法是将BaseDamage和BaseArmor添加到Item基类中......就像这样:
public class Item
{
[XmlAttribute("ID")] public int ItemID;
[XmlElement("Name")] public string ItemName;
[XmlElement("Damage")] public int ItemBaseDamage;
[XmlElement("Armor")] public int ItemBaseArmor;
}
并且根本没有将元素添加到某些项目的XML文件中:
<ItemCollection>
<Items>
<Item ID ="001">
<Name>Dagger</Name>
<Damage>10</Damage>
</Item>
<Item ID ="002">
<Name>Chain Mail</Name>
<Armor>5</Armor>
</Item>
</Items>
</ItemCollection>
它确实有效,但我觉得这不是正确的方法。另一个问题是,如果我想添加一个具有特定功能的Scroll类来强制转换写在该滚动上的咒语,我需要将“SpellToCast”属性添加到基类并向其添加一个CastSpell(Spell)函数从任何项目中调用,这不是我想要的......
简而言之,我想从XML加载多个项目,但每个项目都是其预期的派生类,以便他们可以访问各自的函数并获取其特定属性,如BaseDamage(如果它是武器)。 p>
我尝试使用名为类型类的ItemClass的XmlElement,但是我收到一条错误,说XmlElement / XmlAttribute在此声明类型上无效...
我还考虑过使用抽象的Item类,但是如何将项ID加载到抽象基类Item,然后将BaseDamage加载到派生类Weapon?
这是我用来(反序列化?我不确定这是正确的术语)XML文件的代码:
[XmlRoot("ItemCollection")]
public class ItemContainer
{
[XmlArray("Items")]
[XmlArrayItem("Item")]
public List<Item> items = new List<Item>();
public static ItemContainer Load(string itemPath)
{
TextAsset _xml = Resources.Load<TextAsset>(itemPath);
XmlSerializer serializer = new XmlSerializer(typeof(ItemContainer));
StringReader reader = new StringReader(_xml.text);
ItemContainer items = serializer.Deserialize(reader) as ItemContainer;
reader.Close();
return items;
}
}
所以,欢迎任何帮助,
由于
答案 0 :(得分:0)
试试这个代码示例,xml和c#的好工具是xml2csharp
class Program
{
static void Main(string[] args)
{
var xml = File.ReadAllText("test.xml");
var serializer = new XmlSerializer(typeof(ItemCollection));
using (var reader = new StringReader(xml))
{
var items = serializer.Deserialize(reader) as ItemCollection;
}
}
}
[XmlRoot(ElementName = "Item")]
public class Item
{
[XmlElement(ElementName = "Name")]
public string Name { get; set; }
[XmlElement(ElementName = "Damage")]
public string Damage { get; set; }
[XmlAttribute(AttributeName = "ID")]
public string ID { get; set; }
[XmlElement(ElementName = "Armor")]
public string Armor { get; set; }
}
[XmlRoot(ElementName = "Items")]
public class Items
{
[XmlElement(ElementName = "Item")]
public List<Item> Item { get; set; }
}
[XmlRoot(ElementName = "ItemCollection")]
public class ItemCollection
{
[XmlElement(ElementName = "Items")]
public Items Items { get; set; }
}
答案 1 :(得分:0)
虽然第一个答案并不完全是我想要的,但它确实让我在正确的轨道上发现了我使用多个根并通过谷歌搜索,我落在某个网站上并意识到解决方案是只是告诉XML文件我不打算使用Item Class,而是使用Weapon / Armor / Scroll等,以便将它们视为各自的派生类。
是这样的:
[XmlRoot("ItemCollection")]
public class ItemContainer
{
[XmlArray("Items")]
[XmlArrayItem("Weapon", Type = typeof(Weapon))]
[XmlArrayItem("Armor", Type = typeof(Armor))]
public List<Item> items = new List<Item>();
public static ItemContainer LoadItems(string itemPath)
{
TextAsset _xml = Resources.Load<TextAsset>(itemPath);
XmlSerializer serializer = new XmlSerializer(typeof(ItemContainer));
StringReader reader = new StringReader(_xml.text);
ItemContainer items = serializer.Deserialize(reader) as ItemContainer;
reader.Close();
return items;
}
}
我没有看过protoBuff,我发现的唯一的东西就是协议缓冲区,这似乎就是你所说的。我会记住它,但现在对于我对C#的基本理解可能有点太多了
<?xml version="1.0" encoding="utf-8" ?>
<ItemCollection>
<Items>
<Weapon Name ="Dagger">
<ID>01</ID>
<BaseDamage>10</BaseDamage>
</Weapon>
<Armor Name ="Chainmail">
<ID>04</ID>
<BaseArmor>5</BaseArmor>
</Armor>
</Items>
</ItemCollection>