Type mismatch и None в листе ScriptableObject'ов при их выгрузке из файла
Я делаю систему сохранений в Unity на основе записи данных в файл и их последующей выгрузке из него. Конкретно проблема возникает с сохранением инвентаря. Когда я проверяю работу системы в редакторе, все работает как надо. Сохраняет активный предмет, снаряжение и сам инвентарь. Но при перезаходе в Unity / Перезапуске приложения на Андроид в листе предметов появляются надписи None или Type mismatch. Либо же эти надписи появляются в поле со спрайтом предмета или в поле с ивентом, привязанном к предмету. Так же параметры предметов путаются между собой.
Фото:
Методы сохранения и загрузки инвентаря:
public List<PlayerInventory> myInventorys;
public InventoryItem noneItem;
public InventoryItem overWriteItem;
public InventoryManagerUnique manager;
private InventoryItem magicItem;
public void SaveInventory()
{
if (!Directory.Exists(Application.persistentDataPath + "/GameSave"))
Directory.CreateDirectory(Application.persistentDataPath + "/GameSave");
if (!Directory.Exists(Application.persistentDataPath + "/GameSave/Inventorys"))
Directory.CreateDirectory(Application.persistentDataPath + "/GameSave/Inventorys");
BinaryFormatter bf = new BinaryFormatter();
FileStream file;
string json;
for (int i = 0; i < myInventorys.Count; i++)
{
if (!Directory.Exists(Application.persistentDataPath + "/GameSave/Inventorys/Inventory" + (i + 1)))
Directory.CreateDirectory(Application.persistentDataPath + "/GameSave/Inventorys/Inventory" + (i + 1));
file = File.Create(Application.persistentDataPath + "/GameSave/Inventorys/Inventory" + (i + 1) + "/Inventory.txt");
json = JsonUtility.ToJson(myInventorys[i]);
bf.Serialize(file, json);
file.Close();
for (int j = 0; j < myInventorys[i].myInventory.Count; j++)
{
file = File.Create(Application.persistentDataPath + "/GameSave/Inventorys/Inventory" + (i + 1) + "/Item" + (j + 1) + ".txt");
json = JsonUtility.ToJson(myInventorys[i].myInventory[j]);
bf.Serialize(file, json);
file.Close();
}
}
magicItem = manager.magicSlot.thisItem;
file = File.Create(Application.persistentDataPath + "/GameSave/Inventorys/MagicItem.txt");
json = JsonUtility.ToJson(magicItem);
bf.Serialize(file, json);
file.Close();
}
public void LoadInventory()
{
if (!Directory.Exists(Application.persistentDataPath + "/GameSave/Inventorys"))
Directory.CreateDirectory(Application.persistentDataPath + "/GameSave/Inventorys");
BinaryFormatter bf = new BinaryFormatter();
FileStream file;
for (int i = 0; i < myInventorys.Count; i++)
{
if (!Directory.Exists(Application.persistentDataPath + "/GameSave/Inventorys/Inventory" + (i + 1)))
Directory.CreateDirectory(Application.persistentDataPath + "/GameSave/Inventorys/Inventory" + (i + 1));
if (File.Exists(Application.persistentDataPath + "/GameSave/Inventorys/Inventory" + (i + 1) + "/Inventory.txt"))
{
file = File.Open(Application.persistentDataPath + "/GameSave/Inventorys/Inventory" + (i + 1) + "/Inventory.txt", FileMode.Open);
JsonUtility.FromJsonOverwrite((string)bf.Deserialize(file), myInventorys[i]);
file.Close();
}
for (int j = 0; j < myInventorys[i].myInventory.Count; j++)
{
if (File.Exists(Application.persistentDataPath + "/GameSave/Inventorys/Inventory" + (i + 1) + "/Item" + (j + 1) + ".txt"))
{
file = File.Open(Application.persistentDataPath + "/GameSave/Inventorys/Inventory" + (i + 1) + "/Item" + (j + 1) + ".txt", FileMode.Open);
JsonUtility.FromJsonOverwrite((string)bf.Deserialize(file), myInventorys[i].myInventory[j]);
file.Close();
}
}
}
manager.magicSlot.Setup(noneItem, manager);
if (File.Exists(Application.persistentDataPath + "/GameSave/Inventorys/MagicItem.txt"))
{
if (File.ReadAllText(Application.persistentDataPath + "/GameSave/Inventorys/MagicItem.txt") != "")
{
file = File.Open(Application.persistentDataPath + "/GameSave/Inventorys/MagicItem.txt", FileMode.Open);
JsonUtility.FromJsonOverwrite((string)bf.Deserialize(file), overWriteItem);
manager.magicSlot.Setup(overWriteItem, manager);
file.Close();
}
}
else
File.Create(Application.persistentDataPath + "/GameSave/Inventorys/MagicItem.txt");
}
То есть я сохраняю в память сам объект инвентаря, а затем предметы в нём. Потом выгружаю сначала инвентарь, а затем предметы в него.
Скрипт предмета, который сохраняется в память:
[CreateAssetMenu(fileName ="New Item", menuName ="Inventory/Item")]
[System.Serializable]
public class InventoryItem : ScriptableObject
{
public int numberHeld;
public Sprite itemSprite;
public string itemDescription;
public string itemName;
public bool usable;
public bool stackable;
public UnityEvent thisEvent;
[Header("If it's weapon or armor")]
public int damage;
public int armor;
public UniqueClass uniqueClass;
public void Use()
{
thisEvent.Invoke();
DecreaseAmount();
}
public void DecreaseAmount()
{
numberHeld--;
if (numberHeld < 0)
{
numberHeld = 0;
}
}
}
Скрипт инвентаря:
[System.Serializable]
[CreateAssetMenu(fileName = "New Inventory", menuName = "Inventory/PlayerInventory")]
public class PlayerInventory : ScriptableObject
{
public List<InventoryItem> myInventory = new List<InventoryItem>();
}
Скрипт менеджера инвентаря:
public class InventoryManagerUnique : InventoryManager
{
public InventorySlotUnique helmetSlot;
public InventorySlotUnique chestplateSlot;
public InventorySlotUnique legginsSlot;
public InventorySlotUnique weaponSlot;
public InventoryItem noneItem;
public GameObject equipButton;
public void SetUnique()
{
int maxHelmetArmor = 0;
int maxChestplateArmor = 0;
int maxLegginsArmor = 0;
int maxWeaponDamage = 0;
helmetSlot.Setup(noneItem, this);
chestplateSlot.Setup(noneItem, this);
legginsSlot.Setup(noneItem, this);
weaponSlot.Setup(noneItem, this);
for (int i = 0; i < playerInventory.myInventory.Count; i++)
{
switch (playerInventory.myInventory[i].uniqueClass)
{
case UniqueClass.Helmet:
if (playerInventory.myInventory[i].armor > maxHelmetArmor)
{
maxHelmetArmor = playerInventory.myInventory[i].armor;
helmetSlot.Setup(playerInventory.myInventory[i], this);
}
break;
case UniqueClass.Chestplate:
if (playerInventory.myInventory[i].armor > maxChestplateArmor)
{
maxChestplateArmor = playerInventory.myInventory[i].armor;
chestplateSlot.Setup(playerInventory.myInventory[i], this);
}
break;
case UniqueClass.Leggins:
if (playerInventory.myInventory[i].armor > maxLegginsArmor)
{
maxLegginsArmor = playerInventory.myInventory[i].armor;
legginsSlot.Setup(playerInventory.myInventory[i], this);
}
break;
case UniqueClass.Weapon:
if (playerInventory.myInventory[i].damage > maxWeaponDamage)
{
maxWeaponDamage = playerInventory.myInventory[i].damage;
weaponSlot.Setup(playerInventory.myInventory[i], this);
}
break;
}
}
}
Маюсь с этим уже часов 7, не могу понять, в чем проблема.


