【问题标题】:How to save and update ".xml" file at runtime?如何在运行时保存和更新“.xml”文件?
【发布时间】:2019-07-22 08:48:43
【问题描述】:

我正在开发一个游戏项目,我们将玩家收集的物品保存到 .xml 文件中,我们这样做是为了跟踪玩家的开发过程。例如,您要进入地牢杀死敌人。杀死敌人后,游戏会掉落随机物品,如果您想将该物品添加到您的库存中,只需单击它即可。这就是问题发生的地方。将新项目保存到 xml 文档的功能工作正常,但如果我手动刷新 xml 页面或重新启动游戏,它只会添加收集的项目。 (在这种情况下我们不希望这样做)我有什么方法或解决方法可以在游戏运行时更新 xml 文档并保存它?

我试图通过使用“XmlTextWriter”类来解决这个问题,但它最终从数据库中删除了所有项目并开始再次插入所有项目。 这让我想到了性能。

这是将新项目保存到数据库的功能。 “ContentDataCarrier”是包含项目信息的类。 (ID、名称、效果、SellPrice 等)

 public void AddItemToDatabase(ContentDataCarrier contentDataCarrier)
 {
            var databaseDocument = new XmlDocument();

            // Load the database XML document with the file path.
            // Note: We need to make sure if "AssetDatabase.GetAssetPath()" function also works at runtime. 
            databaseDocument.Load(AssetDatabase.GetAssetPath(_itemProgressDatabase));

            // Now create new nodes for each property that "contentDataCarrier" has.
            XmlNode itemWrapperNode = databaseDocument.CreateElement("item");

            XmlNode idNode = databaseDocument.CreateElement("ID");
            idNode.InnerText = LastAddedItemID++.ToString();

            XmlNode levelNode = databaseDocument.CreateElement("level");
            levelNode.InnerText = contentDataCarrier.Level.ToString();

            XmlNode nameNode = databaseDocument.CreateElement("name");
            nameNode.InnerText = contentDataCarrier.Name; 

            XmlNode descriptionNode = databaseDocument.CreateElement("description");
            descriptionNode.InnerText = contentDataCarrier.Description;

            XmlNode spriteNode = databaseDocument.CreateElement("sprite");
            spriteNode.InnerText = "null"; // Somehow find a way to save sprite id and load it into game.

            XmlNode qualityNode = databaseDocument.CreateElement("quality");
            qualityNode.InnerText = contentDataCarrier.Quality.ToString();

            XmlNode slotTypeNode = databaseDocument.CreateElement("slotType");
            slotTypeNode.InnerText = contentDataCarrier.SlotType.ToString();

            XmlNode sellPriceNode = databaseDocument.CreateElement("sellPrice");
            sellPriceNode.InnerText = contentDataCarrier.SellPrice.ToString();

            XmlNode buyPriceNode = databaseDocument.CreateElement("buyPrice");
            buyPriceNode.InnerText = contentDataCarrier.BuyPrice.ToString();

            XmlNode sellableNode = databaseDocument.CreateElement("sellable");
            sellableNode.InnerText = contentDataCarrier.Sellable.ToString();

            XmlNode droppedFromEnemyNode = databaseDocument.CreateElement("droppedFromEnemy");
            droppedFromEnemyNode.InnerText = contentDataCarrier.DroppedFromEnemy.ToString();

            XmlNode itemEffectsListNode = databaseDocument.CreateElement("effects");
            AddItemEffectsToDatabase(databaseDocument, itemEffectsListNode, contentDataCarrier.ItemEffects);

            // Save the new item.
            itemWrapperNode.AppendChild(idNode);
            itemWrapperNode.AppendChild(levelNode);
            itemWrapperNode.AppendChild(nameNode);
            itemWrapperNode.AppendChild(descriptionNode);
            itemWrapperNode.AppendChild(spriteNode);
            itemWrapperNode.AppendChild(qualityNode);
            itemWrapperNode.AppendChild(slotTypeNode);
            itemWrapperNode.AppendChild(sellPriceNode);
            itemWrapperNode.AppendChild(buyPriceNode);
            itemWrapperNode.AppendChild(sellableNode);
            itemWrapperNode.AppendChild(droppedFromEnemyNode);
            itemWrapperNode.AppendChild(itemEffectsListNode);

            databaseDocument.DocumentElement.InsertAfter(itemWrapperNode, 
            databaseDocument.DocumentElement.LastChild);


     databaseDocument.Save(AssetDatabase.GetAssetPath(_itemProgressDatabase));
}

我希望在运行时将播放器收集的项目保存到 xml 文件中。

【问题讨论】:

  • 也许这有助于wiki.unity3d.com/index.php/…
  • 使用:databaseDocument.Save(filename);
  • @derHugo 感谢您的回复,正在调查。
  • @jdweng 感谢您的回复,我已经在函数末尾添加了。
  • 您还有问题吗?

标签: c# xml unity3d xmldocument


【解决方案1】:

我终于找到了让它工作的方法。我只是像@derHugo 建议的那样使用 XMLSerializer。 使用 XMLSerializer,我可以随时从“.xml”文件中保存和获取数据。

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

[DisallowMultipleComponent]
internal sealed class XMLManager : MonoBehaviour
{
    public ItemDatabase ItemDatabase = new ItemDatabase();

    public void SaveItem()
    {
        var xmlSerializer = new XmlSerializer(typeof(ItemDatabase));
        var fileStream = new FileStream(Application.dataPath + "/StreamingFiles/XML/Items.xml", FileMode.Create);

        xmlSerializer.Serialize(fileStream, ItemDatabase);

        fileStream.Close();
    }

    public void LoadItem()
    {
        var xmlSerializer = new XmlSerializer(typeof(ItemDatabase));
        var fileStream = new FileStream(Application.dataPath + "/StreamingFiles/XML/Items.xml", FileMode.Open);

        ItemDatabase = xmlSerializer.Deserialize(fileStream) as ItemDatabase;

        fileStream.Close();
    }
}

[System.Serializable]
public sealed class Item
{
    public string Name;
    public string Description;
    public int Damage;
    public Source Element;

    public enum Source { Fire, Water, Air };
}

[System.Serializable]
public sealed class ItemDatabase
{
    public List<Item> items = new List<Item>();
}

这是适合我的代码。

希望这会对那里的人有所帮助。

谢谢。

【讨论】:

    猜你喜欢
    • 2014-03-10
    • 2011-09-30
    • 2016-02-10
    • 1970-01-01
    • 2018-04-07
    • 1970-01-01
    • 2011-06-05
    • 1970-01-01
    • 2019-06-27
    相关资源
    最近更新 更多