Reputation: 51
I am working on a game project which we save the items that player collected into the .xml file, we are doing this to keep track of the player's development process. For example you are going into dungeon to slay an enemy. After you slay your enemy the game drops random item and if you want to add that item to your inventory you simply going to click on it. And that's where the problem occurs. The function that saves a new item to xml document works fine but it only adds the collected item if i refresh the xml page manually or reboot the game. (Which we don't want in this case) Is there any way or workaround for me to update the xml document and save it while game is running?
I've tried to fix that problem by using "XmlTextWriter" class but it end up deleting all the items from database and started to insert all of them again. Which makes me think about performance.
Here is the function that saves new item to the database. "ContentDataCarrier" is class that contains the information about item. (ID, Name, Effects, SellPrice etc.)
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));
}
I am expecting to save the items that player collected to xml file at runtime.
Upvotes: 1
Views: 1644
Reputation: 51
I finally found a way to make it work. I just used XMLSerializer just like how @derHugo suggests. With the XMLSerializer i can save and fetch data from ".xml" file whenever i want.
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>();
}
This is the code that works for me.
Hope this will help someone out there.
Thanks.
Upvotes: 1