- Home /
Serialization creates file while returning nothing
I'm trying to achieve a persistent leader scoreboard with the help of serialization. At first I kept close to the Unity tutorial, but had to wander off after a while to actually make those functions work to my liking and for my purpose.
Here are the scripts
loadHighscore.cs
using UnityEngine;
using System.Collections;
using System;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
public class loadHighScore : MonoBehaviour {
int highScoreFinal;
string playerName;
public PlayerData playerData;
void Start () {
LoadFromFile();
//print(playerData.playerName);
//print(playerData.playerScore);
//Debug.Log(playerData.playerName.ToString());
//Debug.Log(playerData.playerScore.ToString());
}
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.playerScore;
}
}
}
highScoreCounter.cs
using UnityEngine;
using System.Collections;
using System;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
public class highscoreCounter : MonoBehaviour
{
public static highscoreCounter control;
int highScoreFinal;
string playerName;
void Update()
{
highScoreFinal = GetComponent<highscoreCalculator>().highScoreFinal;
playerName = GameObject.Find("LevelFinisher").GetComponent<finishLevel>().newPlayerName;
}
public void SaveToFile()
{
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Create(Application.persistentDataPath + "/highScore.dat");
PlayerData data = new PlayerData();
data.playerName = playerName;
data.playerScore = highScoreFinal;
bf.Serialize(file, data);
file.Close();
}
}
PlayerData.cs
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System;
[Serializable]
public class PlayerData
{
public string playerName;
public int playerScore;
}
public class PlayerDatabase
{
public List<PlayerData> list = new List<PlayerData>();
}
So, what is going on: I am having troubles filling the *.dat file. What happens is that as soon as the game ends and I enter my string as well as my highscore, it's fed into the file and saved. The file continually grows bigger.
When I try to load the values to check if they are actually saved, it will return me null for the strings, and 0 for the integers. I cannot tell whats going on, and I would really appreciate any tips.
ps: Yes, I could make this into saving a xml to check, or use PlayerPrefs, but I really want to learn how to work with serialization.....
Thanks!
Answer by Bunny83 · Jul 12, 2016 at 09:25 AM
Uhm i guess
data.playerName = playerName;
data.highScoreFinal = highScoreFinal;
inside LoadFromFile should be the other way round:
playerName = data.playerName;
highScoreFinal = data.highScoreFinal;
Your code loads the data object from the file and then overwrites it's values with the values in your script.
Oh god, yeah thanks! But the load function now only shows me the last entries, not all from the file.
Do if have to call all entries with for-loop in order to retrieve all entries?
Answer by DenisTribouillois · Jul 12, 2016 at 11:47 AM
You shouldn't call SaveToFile in Update , call it just once, just after you set the values of highScoreFinal and playerName.
Oh god, yeah thanks! But the load function now only shows me the last entries, not all from the file.
Your code save only one user and overwrite it at each save if I understand correctly. You should make a list and add users to it and then save the list.
Okay, that makes sense. I switched the save function into a trigger event and changed now the PlayerData list to
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System;
[Serializable]
public class PlayerData
{
public string playerName;
public int playerScore;
}
public class PlayerDatabase
{
public List<PlayerData> list = new List<PlayerData>();
}
But its still not printing me a full list of things. All I get is this:
The first is supposed to be the string while the second is supposed to be the int. At least the latter is printed me correctly, while its still only just printing the latest entry (probably also not filling the list)
Try to print a specific index of the list, and see if the list is correctly filled. I don't think the print method can print the whole list (at least with string).
See http://answers.unity3d.com/questions/607775/output-a-string-list.html
So your list may be correctly filled, just not printed.
it's still returning empty as in the screenshot above.
If the list is correctly filled with the playerScore but not playerName the problem may be the writing of the name in the list (supposing you always fill both at the same time). Are you sure that this part
playerName = GameObject.Find("LevelFinisher").GetComponent<finishLevel>().newPlayerName;
returns the correct string ?