1

So, what I am trying to do is to save a float and a string into a database so that I can use those values later in a persistent highscore table.

I've come that far that I'm able to save the data, and the more entries I feed the Save function, the bigger the file becomes. So I'm assuming, that works.

When I want to deserialize the file in order to read and construct a scoretable, I get this error:

InvalidCastException: Cannot cast from source type to destination type. loadHighScore.LoadFromFile () (at Assets/scripts/GameManager/loadHighScore.cs:40)loadHighScore.Start () (at Assets/scripts/GameManager/loadHighScore.cs:18)

Here are the two scripts:

highscoreCounter:

using UnityEngine;
using System.Collections;
using System;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

public class highscoreCounter : MonoBehaviour
{

    public static highscoreCounter control;

    public int highScoreFinal;
    public string playerName;

    void Update()
    {
        highScoreFinal = GetComponent<highscoreCalculator>().highScoreFinal;
        playerName = GameObject.Find("LevelFinisher").GetComponent<finishLevel>().newPlayerName;
        SaveToFile();
    }
    public void SaveToFile()
    {
        BinaryFormatter bf = new BinaryFormatter();
        FileStream file = File.Create(Application.persistentDataPath + "/highScore.dat");

        PlayerData data = new PlayerData();
        data.playerName = playerName;
        data.highScoreFinal = highScoreFinal;

        bf.Serialize(file, data);
        file.Close();
    }

    [Serializable]
    class PlayerData
    {
        public int highScoreFinal;
        public string playerName;
    }
}

loadHighScore:

using UnityEngine;
using System.Collections;
using System;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

public class loadHighScore : MonoBehaviour {

    public static loadHighScore control;
    int highScoreFinal;
    string playerName;

    public GameObject playerEntry;


    void Start () {

        LoadFromFile();
    }


    public void LoadFromFile()
    {
        if (File.Exists(Application.persistentDataPath + "/highScore.dat"))
        {
            BinaryFormatter bf = new BinaryFormatter();
            FileStream file = File.Open(Application.persistentDataPath + "/highScore.dat", FileMode.Open);
            PlayerData data = (PlayerData)bf.Deserialize(file);

            file.Close();

            playerName = data.playerName;
            highScoreFinal = data.highScoreFinal;
            print(playerName);
            print(highScoreFinal);
        }


    }

    [Serializable]
    class PlayerData
    {
        public int highScoreFinal;
        public string playerName;
    }
}

For this code I followed the Serialization Tutorial on Unitys YT channel, if anyone wonders.

I would be really helpful for someone steering me in the right direction of what's wrong here, cause I'm already looking at it for about 3 hours without being able to figure out whats wrong.

Blue
  • 22,608
  • 7
  • 62
  • 92
  • `BinaryFormatter` is notorious for data not being desearalizeable if the underlying data structures changed. Try switching to a more forgiving seralization structure like XML or JSON. – Scott Chamberlain Jul 11 '16 at 19:33
  • Hello Scott, thanks for the tip for changing to XML. Still, I'd like to know what's going on here, cause I can't understand why it happens. Cheers –  Jul 11 '16 at 19:36
  • Possible duplicate of [Best way to save large amount of data locally in unity3D android?](http://stackoverflow.com/questions/35936710/best-way-to-save-large-amount-of-data-locally-in-unity3d-android) – Fattie Jul 11 '16 at 19:46
  • I don't want to pollute my PlayerPrefs with data that's better stored in a external file. –  Jul 11 '16 at 19:50

1 Answers1

0

Try moving PlayerData class to a separate file, otherwise these two PlayerData classes are viewed as independent and thus incompatible

EDIT: To clarify, create new script from unity and replace the contents with this:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System;

[Serializable]
class PlayerData
{
    public int highScoreFinal;
    public string playerName;
}

then delete those two PlayerData classes you had because you now dont need them

makapaka
  • 102
  • 2
  • 9
  • Thanks, how would I call it when I stored it in another file? –  Jul 11 '16 at 19:56
  • Best call this file PlayerData.cs, I edited my answer to explain it a bit better – makapaka Jul 11 '16 at 20:07
  • Thanks for the help! It fixed the error, but apparently the *.dat file saved has still no content in it, as the returned values are Null for the strings and 0 for the integers. –  Jul 11 '16 at 20:16