Using Binary Formatter to deserialize multiple objects
Here's the code: this first section has been figured out I Keep getting an Invalid CastException: Specified Cast is not valid. Can anyone help with this one? i've been at it for awhile but can't seem to crack it.
the issue is in the load function, I've posted the whole code up for people to take a look.
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;
using System.Runtime.Serialization.Formatters.Binary;
using System;
public class Room_Class : MonoBehaviour
{
private const string SAVE_SEPERATOR = "#SAVE-VALUE#";
public enum RoomState { Broken, Fixed_Dirty, Fixed_Clean, Idle }
public RoomState roomState;
public enum RoomType { Kitchen, Bathroom, LivingRoom, Bedroom1, Bedroom2, Bedroom3, Outdoor, Basement, Attic, RecRoom, WineCellar, Stairwell, Study, ArtRoom, Office, Foyer }
public RoomType roomType;
public List<Appliance_Class> _appliances = new List<Appliance_Class>();
[SerializeField] List<string> _saves = new List<string>();
[SerializeField] Sprite[] images;
SpriteRenderer sprite;
bool startClock = false;
[SerializeField] float cleannningClock;
float maxCleanningTime = 120;
View_UI ui;
private DataService dataService;
private void Awake()
{
ui = FindObjectOfType<View_UI>();
sprite = GetComponentInChildren<SpriteRenderer>();
}
private void Start()
{
dataService = StartupScript.ds;
}
IEnumerator SwapSprite(int i)
{
yield return new WaitForEndOfFrame();
sprite.sprite = images[i];
}
public void CleanClock()
{
if (cleannningClock <= maxCleanningTime)
{
cleannningClock += 1 * Time.deltaTime;
}
else if (cleannningClock > maxCleanningTime) roomState = RoomState.Fixed_Dirty; /*ui.npcUpdater.text = $"{ roomType + " is dirty."}" ;*/
}
public void SaveApplianceState()
{
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Create(Application.dataPath + "/Saves/" + name + "Save.txt");
for (int i = 0; i < _appliances.Count; i++)
{
_appliances[i].appId = i;
SavedAppliance savedAppliance = new SavedAppliance
{
appID = _appliances[i].appId,
name = _appliances[i].name,
dep = _appliances[i].depreciation,
position = _appliances[i].transform.position
};
_saves.Add(JsonUtility.ToJson(savedAppliance));
}
bf.Serialize(file, _saves);
file.Close();
//Trying to tie into the DATASERVICE so far it's broken :'(
//if (dataService.UpdateRoomItemJSONS(saveString, this.gameObject.GetComponentInParent<Room_Class>().gameObject.name) == 1)
// print("it worked!");
//else
// print("it broke");
}
public void LoadApplianceState()
{
if (File.Exists(Application.dataPath + "/Saves/" + name + "Save.txt"))
{
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Open(Application.dataPath + "/Saves/" + name + "Save.txt", FileMode.Open);
Room_Class saved = (Room_Class)bf.Deserialize(file);
file.Close();
for (int i = 0; i <= _appliances.Count; i++)
{
foreach (Appliance_Class item in _appliances)
{
Appliance_Class appliance = item.GetComponent<Appliance_Class>();
if (appliance.appId == i)
{
LoadAppData(appliance, saved.name, saved.dep, saved.currentSprite, saved.position);
}
}
}
}
}
public void LoadAppData(Appliance_Class obj,string name, int dep, int currentSprite, Vector3 pos)
{
obj.name = name;
obj.depreciation = dep;
obj.whichSprite = currentSprite;
obj.transform.position = pos;
}
public void SaveAppData(Appliance_Class obj, string name, int dep, int currentSprite, Vector3 pos)
{
name = obj.name;
dep = obj.depreciation;
currentSprite = obj.whichSprite;
pos = obj.transform.position;
}
}
[Serializable]
public class SavedAppliance
{
public int appID;
public string name;
public int dep;
public int currentSprite;
public Vector3 position;
}
No the issue is i
Answer by streeetwalker · Sep 10, 2020 at 11:28 AM
@theyukonschoice, you have an array or list of your "appliances" in _appliances, right? I'm not sure what an "appliance" is in the sense you are using, but you must have some way of associating a given appliance with it's element in the array. Probably the name of the appliance is unique and links the two? Or your appliance array also stores a reference to the actual object instance
It kind of depends what kind of object an appliance is, but when you read the serialized jSon data back in, you simply need to reverse the association. link the indices of the elements in the resultant array that is created when you read data back in with their respective appliance.
For that reason it is better if you do not use "For Each" and use a simple "For index" form of the loop.
Your answer
Follow this Question
Related Questions
How to save data to load outside of unity 1 Answer
Euler angles in inspector 3 Answers
instatiated object don't get parameters 1 Answer
Why does everything happen to be UI?? plz help. 0 Answers
My collectable objects don't respond like they should after calling a coroutine for the first time? 0 Answers