我正在为Unity游戏制作库存系统。
按预期方式将库存序列化并保存到xml文件中;但是,当我反序列化时,项目被设置为null并抛出 TargetInvocationException ;最后是 NullReferenceException 。
我做错了什么?
public void SaveInventoryToXML()
{
System.Xml.Serialization.XmlSerializer writer = new System.Xml.Serialization.XmlSerializer(typeof (List<Item>));
System.IO.StreamWriter file = new System.IO.StreamWriter(inventoryPath);
writer.Serialize(file, inventory);
file.Close();
}
public void LoadInventoryFromXML()
{
System.Xml.Serialization.XmlSerializer reader = new System.Xml.Serialization.XmlSerializer(typeof(List<Item>));
StreamReader sr = new StreamReader(inventoryPath);
inventory = (List<Item>) reader.Deserialize(sr);
sr.Close();
}
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
[System.Serializable] //what's with the square brackets
public class Item
{
public string ItemName;
public int ItemId;
public string ItemDesc;
public int BaseWorth;
public int BaseDamage;
public int RequiredLevel;
public Sprite Sprite;
public ItemType itemType;
public ItemRarity itemRarity;
public Weapon.WeaponType weaponType;
public Weapon.AttackType attackType;
public List<Enchantment> Enchantments;
public bool Stackable;
public int StackSize = 99;
public int Amount = 1;
public enum ItemType
{
Weapon, Consumable, Quest, Armor, Boots, Helmet, Gloves, Ring, Amulet
}
public enum ItemRarity
{
Common, Rare, Unique, Magic
}
public Item(string name, int id, int reqlvl, string desc, int baseworth, int basedamage, List<Enchantment> enchantments, ItemType itemtype, ItemRarity itemrarity, Sprite sprite )
{
ItemName = name;
ItemId = id;
RequiredLevel = reqlvl;
ItemDesc = desc;
BaseWorth = baseworth;
BaseDamage = basedamage;
Enchantments = enchantments;
itemType = itemtype;
itemRarity = itemrarity;
Sprite = sprite;
additionalParameters();
}
private void additionalParameters()
{
switch (itemType)
{
case ItemType.Consumable:
Stackable = true;
break;
}
}
public Item()
{
ItemId = -1;
}
}
public class Enchantment
{
public EnchantmentType Type;
public int Amount;
public enum EnchantmentType
{
Fire, Ice, Poison, Electric, Brutalize, Greed, Invisiblity, Heal, ReplenishStamina, ReplenishMana,
AddMaxHealth, AddMaxStamina, AddMaxMana
}
public Enchantment(EnchantmentType type, int amount)
{
Amount = amount;
Type = type;
}
public Enchantment()
{
}
}
NullReferenceException
System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Reflection/MonoMethod.cs:222)
Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.
System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Reflection/MonoMethod.cs:232)
System.Reflection.MonoProperty.SetValue (System.Object obj, System.Object value, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] index, System.Globalization.CultureInfo culture) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Reflection/MonoProperty.cs:348)
System.Reflection.PropertyInfo.SetValue (System.Object obj, System.Object value, System.Object[] index) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Reflection/PropertyInfo.cs:102)
System.Xml.Serialization.XmlTypeMapMember.SetValue (System.Object ob, System.Object value)
System.Xml.Serialization.XmlSerializationReaderInterpreter.SetMemberValue (System.Xml.Serialization.XmlTypeMapMember member, System.Object ob, System.Object value, Boolean isValueList)
System.Xml.Serialization.XmlSerializationReaderInterpreter.ReadMembers (System.Xml.Serialization.ClassMap map, System.Object ob, Boolean isValueList, Boolean readByOrder)
System.Xml.Serialization.XmlSerializationReaderInterpreter.ReadClassInstanceMembers (System.Xml.Serialization.XmlTypeMapping typeMap, System.Object ob)
System.Xml.Serialization.XmlSerializationReaderInterpreter.ReadClassInstance (System.Xml.Serialization.XmlTypeMapping typeMap, Boolean isNullable, Boolean checkType)
System.Xml.Serialization.XmlSerializationReaderInterpreter.ReadObject (System.Xml.Serialization.XmlTypeMapping typeMap, Boolean isNullable, Boolean checkType)
System.Xml.Serialization.XmlSerializationReaderInterpreter.ReadObjectElement (System.Xml.Serialization.XmlTypeMapElementInfo elem)
System.Xml.Serialization.XmlSerializationReaderInterpreter.ReadMembers (System.Xml.Serialization.ClassMap map, System.Object ob, Boolean isValueList, Boolean readByOrder)
System.Xml.Serialization.XmlSerializationReaderInterpreter.ReadClassInstanceMembers (System.Xml.Serialization.XmlTypeMapping typeMap, System.Object ob)
System.Xml.Serialization.XmlSerializationReaderInterpreter.ReadClassInstance (System.Xml.Serialization.XmlTypeMapping typeMap, Boolean isNullable, Boolean checkType)
System.Xml.Serialization.XmlSerializationReaderInterpreter.ReadObject (System.Xml.Serialization.XmlTypeMapping typeMap, Boolean isNullable, Boolean checkType)
System.Xml.Serialization.XmlSerializationReaderInterpreter.ReadObjectElement (System.Xml.Serialization.XmlTypeMapElementInfo elem)
System.Xml.Serialization.XmlSerializationReaderInterpreter.ReadListElement (System.Xml.Serialization.XmlTypeMapping typeMap, Boolean isNullable, System.Object list, Boolean canCreateInstance)
System.Xml.Serialization.XmlSerializationReaderInterpreter.ReadObject (System.Xml.Serialization.XmlTypeMapping typeMap, Boolean isNullable, Boolean checkType)
System.Xml.Serialization.XmlSerializationReaderInterpreter.ReadRoot (System.Xml.Serialization.XmlTypeMapping rootMap)
System.Xml.Serialization.XmlSerializationReaderInterpreter.ReadRoot ()
System.Xml.Serialization.XmlSerializer.Deserialize (System.Xml.Serialization.XmlSerializationReader reader)
采样 输出
<?xml version="1.0" encoding="utf-8"?>
<ArrayOfItem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Item>
<ItemName>Steel Sword</ItemName>
<ItemId>102</ItemId>
<ItemDesc>A fine steel sword.</ItemDesc>
<BaseWorth>125</BaseWorth>
<BaseDamage>25</BaseDamage>
<RequiredLevel>10</RequiredLevel>
<Sprite>
<name>BasicWeapons_2</name>
<hideFlags>NotEditable</hideFlags>
</Sprite>
<itemType>Weapon</itemType>
<itemRarity>Rare</itemRarity>
<weaponType>Sword</weaponType>
<attackType>Swing</attackType>
<Stackable>false</Stackable>
<StackSize>99</StackSize>
<Amount>1</Amount>
</Item>
<Item>
<ItemName>Mithril Sword</ItemName>
<ItemId>103</ItemId>
<ItemDesc>Feels lighter than steel, yet much sharper...</ItemDesc>
<BaseWorth>625</BaseWorth>
<BaseDamage>125</BaseDamage>
<RequiredLevel>25</RequiredLevel>
<Sprite>
<name>BasicWeapons_3</name>
<hideFlags>NotEditable</hideFlags>
</Sprite>
<itemType>Weapon</itemType>
<itemRarity>Unique</itemRarity>
<weaponType>Sword</weaponType>
<attackType>Swing</attackType>
<Stackable>false</Stackable>
<StackSize>99</StackSize>
<Amount>1</Amount>
</Item>
<Item>
<ItemId>-1</ItemId>
<BaseWorth>0</BaseWorth>
<BaseDamage>0</BaseDamage>
<RequiredLevel>0</RequiredLevel>
<itemType>Weapon</itemType>
<itemRarity>Common</itemRarity>
<weaponType>Sword</weaponType>
<attackType>Swing</attackType>
<Stackable>false</Stackable>
<StackSize>99</StackSize>
<Amount>1</Amount>
</Item>
</ArrayOfItem>
答案 0 :(得分:2)
我刚刚尝试了您的代码,并设法通过删除Sprite
字段使其正常工作。我的猜测是,这是你的罪魁祸首,因为它很可能无法序列化 - 所以你可能只需要将精灵的路径存储为string
或类似的东西。
var list = new List<Item>()
{
new Item(),
new Item()
};
var xmlSerializer = new System.Xml.Serialization.XmlSerializer(typeof(List<Item>));
using (var stream = File.Open("Document.xml", FileMode.CreateNew))
{
xmlSerializer.Serialize(stream, list);
}
using (var stream = File.Open("Document.xml", FileMode.Open))
{
xmlSerializer.Deserialize(stream);
}
产生以下输出:
<?xml version="1.0"?>
<ArrayOfItem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Item>
<ItemId>-1</ItemId>
<BaseWorth>0</BaseWorth>
<BaseDamage>0</BaseDamage>
<RequiredLevel>0</RequiredLevel>
<itemType>Weapon</itemType>
<itemRarity>Common</itemRarity>
<Stackable>false</Stackable>
<StackSize>99</StackSize>
<Amount>1</Amount>
</Item>
<Item>
<ItemId>-1</ItemId>
<BaseWorth>0</BaseWorth>
<BaseDamage>0</BaseDamage>
<RequiredLevel>0</RequiredLevel>
<itemType>Weapon</itemType>
<itemRarity>Common</itemRarity>
<Stackable>false</Stackable>
<StackSize>99</StackSize>
<Amount>1</Amount>
</Item>
</ArrayOfItem>
答案 1 :(得分:1)
显然手动执行操作并不好玩,但您可以尝试通过IXmlSerializable进行序列化。