- Home /
Binary Formatting Loading Error
I have a script which is intended to save / load the whole game. When unity compiles the script no errors. When I save the game no error, however when I load the game I get this error
"ArgumentException: Object type NewItem[] cannot be converted to target type: System.Int32[] Parameter name: val System.Reflection.MonoField.SetValue (System.Object obj, System.Object val, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Globalization.CultureInfo culture) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/MonoField.cs:148) System.Reflection.FieldInfo.SetValue (System.Object obj, System.Object value) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/FieldInfo.cs:150) System.Runtime.Serialization.ObjectRecord.SetMemberValue (System.Runtime.Serialization.ObjectManager manager, System.Reflection.MemberInfo member, System.Object value) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization/ObjectManager.cs:439) System.Runtime.Serialization.FixupRecord.FixupImpl (System.Runtime.Serialization.ObjectManager manager) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization/ObjectManager.cs:396) System.Runtime.Serialization.BaseFixupRecord.DoFixup (System.Runtime.Serialization.ObjectManager manager, Boolean strict) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization/ObjectManager.cs:329) System.Runtime.Serialization.ObjectRecord.DoFixups (Boolean asContainer, System.Runtime.Serialization.ObjectManager manager, Boolean strict) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization/ObjectManager.cs:506) System.Runtime.Serialization.ObjectManager.RegisterObjectInternal (System.Object obj, System.Runtime.Serialization.ObjectRecord record) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization/ObjectManager.cs:255) System.Runtime.Serialization.ObjectManager.RegisterObject (System.Object obj, Int64 objectID, System.Runtime.Serialization.SerializationInfo info, Int64 idOfContainingObj, System.Reflection.MemberInfo member, System.Int32[] arrayIndex) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization/ObjectManager.cs:306) System.Runtime.Serialization.Formatters.Binary.ObjectReader.RegisterObject (Int64 objectId, System.Object objectInstance, System.Runtime.Serialization.SerializationInfo info, Int64 parentObjectId, System.Reflection.MemberInfo parentObjectMemeber, System.Int32[] indices) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs:314) System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadNextObject (System.IO.BinaryReader reader) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs:157) System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadObjectGraph (BinaryElement elem, System.IO.BinaryReader reader, Boolean readHeaders, System.Object& result, System.Runtime.Remoting.Messaging.Header[]& headers) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs:110) System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.NoCheckDeserialize (System.IO.Stream serializationStream, System.Runtime.Remoting.Messaging.HeaderHandler handler) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/BinaryFormatter.cs:179) System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize (System.IO.Stream serializationStream) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/BinaryFormatter.cs:136) SLD.LoadPlayer (Int32 saveSlot) (at Assets/Resources/Scripts/SLD.cs:24) SLD.LoadAll (Int32 saveSlot) (at Assets/Resources/Scripts/SLD.cs:45) LoadScreen.BeginLoad () (at Assets/Resources/Scripts/LoadScreen.cs:39) "
This is the save/load script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
public static class SLD {
public static void SavePlayer (Player player, Inventory inv, PerkManager pm, int saveSlot = 0) {
BinaryFormatter bf = new BinaryFormatter ();
FileStream stream = new FileStream (Application.persistentDataPath + "/player" + saveSlot.ToString () + ".etc", FileMode.Create);
PlayerData data = new PlayerData (player, inv, pm);
bf.Serialize (stream, data);
stream.Close ();
}
public static PlayerData LoadPlayer (int saveSlot = 0) {
if (File.Exists (Application.persistentDataPath + "/player.etc")) {
BinaryFormatter bf = new BinaryFormatter ();
FileStream stream = new FileStream (Application.persistentDataPath + "/player" + saveSlot.ToString () + ".etc", FileMode.Open);
PlayerData data = bf.Deserialize (stream) as PlayerData;
stream.Close ();
foreach (Spawner spawn in Player.p.spawners) {
spawn.Save (saveSlot);
}
foreach (Container spawn in Player.p.containers) {
spawn.Save (saveSlot);
}
return data;
} else {
Debug.LogError ("File does not exsit");
return Player.p.pd;
}
}
public static void LoadAll (int saveSlot = 0) {
PlayerData data = LoadPlayer (saveSlot);
Player.p.water = data.stats [0];
Player.p.hunger = data.stats [1];
Player.p.sleep = data.stats [2];
Player.p.hp = data.stats [3];
Player.p.exp = data.exp;
Player.p.level = data.level;
Transform player = Player.p.player;
player.position = new Vector3 (data.x, data.y, data.z);
PerkManager.p.unlocked = data.perkUnlocked;
PerkManager.p.unlockTokens = data.perkTokens;
int i = 0;
while (i < Inventory.inv.slots.Length) {
Inventory.inv.SetItem (i, data.slot [i]);
// Inventory.inv.slots [i].item = Inventory.inv.items[data.slot[i]];
Inventory.inv.slots [i].amount = data.slotAmounts[i];
i += 1;
}
NewNote.n.NewNot ("Load", "Load Complete");
Debug.Log ("Loading Complete");
}
}
[Serializable]
public class PlayerData {
public float[] stats = new float[4];
public int exp = 0;
public int level = 0;
public float x = 0;
public float y = 0;
public float z = 0;
public bool[] perkUnlocked = new bool[2];
public int perkTokens;
public int[] slot = new int[20];
public int[] slotAmounts = new int[20];
public PlayerData(Player player, Inventory inv, PerkManager pm) {
stats = new float[4];
stats [0] = player.water;
stats [1] = player.hunger;
stats [2] = player.sleep;
stats [3] = player.hp;
exp = player.exp;
level = player.level;
x = player.player.position.x;
y = player.player.position.y;
z = player.player.position.z;
perkUnlocked = pm.unlocked;
perkTokens = pm.unlockTokens;
int i = 0;
while (i < inv.slots.Length) {
slot [i] = inv.slots [i].item.id;
slotAmounts [i] = inv.slots [i].amount;
Debug.Log (inv.slots [i].slotId.ToString () + "---" + inv.slots [i].amount.ToString () + "---" + i.ToString ());
i += 1;
}
NewNote.n.NewNot ("Save", "Save Complete");
Debug.Log ("Saving Complete");
}
}
And this is the script in the array it's referencing in the error
using UnityEngine;
[CreateAssetMenu(fileName = "New Item", menuName = "Items")]
public class NewItem : ScriptableObject {
new public string name = "New Item";
public float weight;
public float pickUpDistance;
public int id;
public bool holdable;
public GameObject heldObject;
public Sprite texture;
public GameObject itemPrefab;
//public NewGun gunType;
public bool isGun;
public int value = 10;
}
Are you sure you don't have some old / outdated saved file which you are loading? The binary formatter stores the exact type of every object and value it serializes. Since it deserialized a "NewItem[]" and tried to store it in an "int[]" you most likely had previously serialized the actual NewItem values. You should make sure to delete all save files you have at the moment and start with a new fresh save.
Thanks! I tried you suggestion and it worked perfectly thank you.