2017-09-24 8 views
1

私のゲームのアイテムデータベースを作成しようとしています。私はそれがゲームのすべてのアイテム(武器、消耗品、鎧など)を含むようにします。しかし、私はそれらのすべてがitemという親クラスから継承することを望みます。私が見たすべての例は、単一のアイテムクラスと継承を使用していません。XMLのUnityアイテムデータベース

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; 
} 

答えて

0

車輪を改造しないでください。シリアライザの標準機能を使用します。

は、クラスの所望の階層を作成します。

[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> 

デシリアライズが正しく希望のインスタンスを作成します。クラス。

+0

私が探していたもの –

0

:武器は

私の現在のXMLおよびアイテムとコンテナタイプの武器、タイプの鎧の鎧やその他のものであろう。だからあなたの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などは必要ありません。

すべての項目を整理して整理したい場合は、すべての項目クラスにシリアライズとデシリアライズのメソッドを追加して、すべてのファクトリで型を調べ、関連するクラスのdeserializeメソッドを呼び出す必要があります利用可能な他のすべての情報これはタイプに必要なすべてのコードをまとめておく利点があります。ヘルメットの作成コードはどこに新しい属性を追加するときにどこにあるかを把握する必要はありません。

アイテムごとに必要なテキストの量を実際に適切なものに保つために、シリアライゼーションで同じことを行うことができます(靴はダメージ属性などを必要としない可能性が高いです)。しかし、あなたの設定が何であるか分かりませんだから私はあなたがシリアル化に使用する外部ツールを持っていることを知っている。

関連する問題