Well this is the basic script that does the actual parsing of that xml:
public void Load()
{
TextAsset data = UnityEngine.Resources.Load("Inventory") as TextAsset;
var itemDict = new Dictionary<string, InvItem>();
var graphicOpts = new List<SpawnPool.ItemOptions>();
var comboList = new List<ComboInfo>();
var xdoc = new XmlDocument();
xdoc.LoadXml(data.text);
var xitems = xdoc.DocumentElement.SelectNodes("./item");
foreach (XmlElement xel in xitems)
{
//create IInvItem
string sname = xel.GetAttribute("name");
if (itemDict.ContainsKey(sname)) continue;
string stype = (xel.HasAttribute("type")) ? xel.GetAttribute("type") : "SimpleItem";
var info = new InventorySerializedInfo(sname, stype);
var xprops = xel.SelectNodes("./attrib");
foreach (XmlElement xprop in xprops)
{
info.SetAttrib(xprop.GetAttribute("name"), xprop.InnerText);
}
var item = DeserializeItem(info);
itemDict.Add(sname, item);
//load graphics GameObject prefab and prepare for pool
var xgraphics = xel.SelectSingleNode("./graphics") as XmlElement;
var opts = new SpawnPool.ItemOptions();
opts.Prefab = UnityEngine.Resources.Load(xgraphics.GetAttribute("prefab")) as GameObject;
opts.ItemName = sname;
if (xgraphics.HasAttribute("cachesize")) opts.CacheSize = ConvertUtil.ToInt(xgraphics.GetAttribute("cachesize"));
if (xgraphics.HasAttribute("resizebuffer")) opts.ResizeBuffer = ConvertUtil.ToInt(xgraphics.GetAttribute("resizebuffer"));
graphicOpts.Add(opts);
//get combo to make if any
var combo = new ComboInfo();
combo.ItemName = sname;
combo.Found = (xel.HasAttribute("found")) ? ConvertUtil.ToBool(xel.GetAttribute("found")) : false;
var xcombo = xel.SelectSingleNode("./combo") as XmlElement;
if (xcombo != null StringUtil.IsNotNullOrWhitespace(xcombo.InnerText))
{
string[] sparts = xcombo.InnerText.Split(',');
Array.Resize(ref sparts, 2);
combo.Part1 = StringUtil.Trim(sparts[0]);
combo.Part2 = StringUtil.Trim(sparts[1]);
}
comboList.Add(combo);
}
//set properties
_itemDict = itemDict;
_graphicPool.ClearCache();
_graphicPool.CacheInstances(graphicOpts);
_comboInfos = comboList;
}
private InvItem DeserializeItem(InventorySerializedInfo info)
{
var tp = Type.GetType("Ponyo.Items." + info.ClassName);
if (tp != null tp.IsSubclassOf(typeof(InvItem)))
{
var obj = Activator.CreateInstance(tp) as InvItem;
obj.Deserialize(this, info);
return obj;
}
throw new Exception("Failed to deserialize item " + info.Name + ".");
}
It makes reference to quite a bit of different classes.
See I’ve been building my own framework (independent of Unity really) for a long time now and I’ve merely pulled them into my unity project to work with. Modifying what was necessary to get it to work together.
In this I’m using several things including:
SpawnPool - this is a system that deals with caching and pooling GameObjects, especially those with graphics that are heavy. I can ask for already create gameobjects from the pool, and if none are available the cache is buffered.
ConvertUtil - a conversion utility I use with my own standard/expectation of object parsing.
StringUtil - another utility I use with my own standard/expectation of dealing with strings
IInvItem - this represents an item, not as a gameobject, but as a basic object. An IInvItem can have a graphic associated with it so it can appear on screen.
InventorySerializedInfo - a wrapper object for sending serialized info around. InvItem’s are serializable, this is the serializedInfo that is passed to and retrieved from it when serializing it.
You’ll not that in ‘DeserializeItem’ I call ‘Deserialize’ on an InvItem… that’s where I pass in the info. Each InvItem sub-class has it’s own unique properties. They retrieve them from this ‘info’ passed in.
So that attribute @type in each item in the xml… that’s a class (which I have in the Ponyo.Items namespace). Those classes MUST inherit from InvItem, else they fail to work.