【问题标题】:Unity item database in XMLXML 中的 Unity 项目数据库
【发布时间】:2017-09-24 16:46:28
【问题描述】:

我正在尝试为我的游戏创建一个项目数据库。我希望它包含游戏中的所有物品(武器、消耗品、盔甲等)。但我希望它们都继承自一个名为 item 的父类。我见过的所有示例都使用单个项目类并且没有继承。

XML 中有没有一种方法可以使我的数据库在我反序列化它时,它们都将是正确的类型?武器将是武器类型,盔甲类型等。

我当前的 XML 和项目和容器:

<?xml version="1.0" encoding="UTF-8"?>
<ItemCollection>
  <Items>
    <DatabaseItem name="Sword">
      <Damage>20</Damage>
    </DatabaseItem>
    <DatabaseItem name="Wand">
      <Damage>10</Damage>
    </DatabaseItem>
  </Items>
</ItemCollection>


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Xml.Serialization;
using System.IO;

[XmlRoot("itemCollection")]
public class ItemContainer
{
    [XmlArray("Items")]
    [XmlArrayItem("DatabaseItem")]
    public List<DatabaseItem> items = new List<DatabaseItem>();

    public static ItemContainer Load(string path)
    {
        TextAsset _xml = Resources.Load<TextAsset>(path);
        XmlSerializer serializer = new XmlSerializer(typeof(ItemContainer));
        StringReader reader = new StringReader(_xml.text);
        ItemContainer items = serializer.Deserialize(reader) as ItemContainer;
        reader.Close();
        return items;
    }
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;    
using System.Xml;
using System.Xml.Serialization;

public class DatabaseItem
{
    [XmlAttribute("title")]
    public string title;

    [XmlAttribute("damage")]
    public float damage;
}

【问题讨论】:

    标签: c# xml unity3d


    【解决方案1】:

    不要重新发明轮子。使用序列化程序的标准功能。

    创建所需的类层次结构:

    [XmlInclude(typeof(Sword))]
    [XmlInclude(typeof(Axe))]
    [XmlInclude(typeof(Helmet))]
    [XmlInclude(typeof(Shell))]
    public class Item
    {
        [XmlAttribute("title")]
        public string Title;
    }
    
    public class Weapon : Item
    {
        [XmlAttribute("damage")]
        public float Damage;
    }
    
    public class Armor : Item
    {
        [XmlAttribute("protection")]
        public float Protection;
    }
    
    public class Sword : Weapon { }
    public class Axe : Weapon { }
    
    public class Helmet : Armor { }
    public class Shell : Armor { }
    

    重要!在属性XmlInclude中指定所有类都是基类的后代。

    创建我们类的多个实例并将它们添加到容器中:

    var sword = new Sword();
    var axe = new Axe();
    var helmet = new Helmet();
    var shell = new Shell();
    
    var container = new ItemContainer();
    container.Items.Add(sword);
    container.Items.Add(axe);
    container.Items.Add(helmet);
    container.Items.Add(shell);
    

    现在序列化后的 xml 将如下所示:

    <?xml version="1.0" encoding="utf-8"?>
    <itemCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <Items>
            <DatabaseItem xsi:type="Sword" damage="0" />
            <DatabaseItem xsi:type="Axe" damage="0" />
            <DatabaseItem xsi:type="Helmet" protection="0" />
            <DatabaseItem xsi:type="Shell" protection="0" />
        </Items>
    </itemCollection>
    

    反序列化将正确创建所需类的实例。

    【讨论】:

    • 正是我想要的
    【解决方案2】:

    您可以添加一个指定类型的属性。所以你的 XML 看起来更像这样:

    <?xml version="1.0" encoding="UTF-8"?>
    <ItemCollection>
      <Items>
        <DatabaseItem title="Sword">
          <damage>20</damage>
          <type>sword</type>  <-- New
        </DatabaseItem>
        <DatabaseItem title="Wand">
          <damage>10</damage>
          <type>wand</type>   <-- New
        </DatabaseItem>
      </Items>
    </ItemCollection>
    

    然后,您创建一个工厂,负责从 DatabaseItem 创建项目。所以你可能会调用类似ItemFactory.Create(DatabaseItem item) 的东西,它会返回该项目的一个实例。您制作物品所需的所有代码都将在其中,然后您只需根据需要分发新物品。

    使用type 变量,您应该有足够的信息让系统推断出它必须制造什么,其余的值特定于该项目类型,因此盔甲不需要damage 等等.

    如果你想保持一切干净/有条理,你可以为每个项目类添加序列化和反序列化方法,这样工厂所要做的就是查看类型并调用相关类的反序列化方法,然后查看所有它拥有的其他信息。这样做的好处是将类型所需的所有代码保存在一起,因此当您向其中添加新属性时,您不必弄清楚头盔的创建代码到底在哪里......

    然后您可以对序列化执行相同的操作,以便将每个项目所需的文本量保持在实际相关的内容(鞋子可能不需要损坏属性等)但我不知道是什么你的设置是,所以据我所知,你有一个用于序列化的外部工具......

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-02
      • 2014-10-30
      • 1970-01-01
      • 2015-07-11
      • 1970-01-01
      • 1970-01-01
      • 2019-05-01
      相关资源
      最近更新 更多