I am attempting to modify the [Unity Trash Cat Walkthrough][1] so that it will save information for multiple levels instead of just one general leaderboard for the entire game.
The issue is when I am trying to read the fastest times entries for each level from the file that was previously created. I am receiving the error: EndOfStreamException: Failed to read past end of stream.
This is happening at these lines:
entry.name = r.ReadString();
entry.time = r.ReadSingle();
entry.score = r.ReadInt32();
entry.sceneNum = r.ReadInt32();
entry.bonusCount = r.ReadInt32();
I, however, am not sure if this is happening bc I am writing to the file incorrectly or reading… or BOTH. Is this even a good way to go about this? Am I looking at this wrong?
Here is my code:
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;
public struct FastestTimeEntry : System.IComparable<FastestTimeEntry>
{
public int sceneNum;
public string name;
public float time;
public int score;
public int bonusCount;
public int CompareTo(FastestTimeEntry other)
{
// We want to sort from lowest to highest time.
return time.CompareTo(other.time);
}
}
public class PlayerProgress{
static protected PlayerProgress m_Instance;
static public PlayerProgress instance { get { return m_Instance; } }
protected string saveFile = "";
static int s_Version = 1;
public int tokens;
public int premium;
public int unlockedSceneNum;
public bool licenseAccepted;
public string previousName = "Game Champ";
public List<FastestTimeEntry>[] fastestTimes = new List<FastestTimeEntry>[GameControllerMain.sceneNames.Length];
public int ftueLevel = 0;
public int rank = 0;
public int totalBonusCount = 0;
public int totalScore;
// Fastest Time management
public int GetTimePlace(float time, int sceneNum)
{
FastestTimeEntry entry = new FastestTimeEntry();
entry.time = time;
entry.sceneNum = sceneNum;
int index = fastestTimes[sceneNum].FindIndex(c => c.time == time);
Debug.Log("GetTimePlace Index:"+ index);
return index < 0 ? (~index) : index;
}
public void InsertTime(float time, int score, int sceneNum, int bonusCount)
{
Debug.Log("Inserting time...");
FastestTimeEntry entry = new FastestTimeEntry();
entry.time = time;
entry.score = score;
entry.sceneNum = sceneNum;
entry.bonusCount = bonusCount;
fastestTimes[sceneNum].Insert(GetTimePlace(time, sceneNum), entry);
// Keep only the 10 best scores.
while (fastestTimes[sceneNum].Count > 10)
fastestTimes[sceneNum].RemoveAt(fastestTimes[sceneNum].Count - 1);
}
// File management
static public void Create()
{
if (m_Instance == null)
{
m_Instance = new PlayerProgress();
}
m_Instance.saveFile = Application.persistentDataPath + "/save.bin";
if (File.Exists(m_Instance.saveFile))
{
// If we have a save, we read it.
m_Instance.Read();
}
else
{
// If not we create one with default data.
NewSave();
}
}
static public void NewSave()
{
Debug.Log("This is a new save!");
m_Instance.tokens = 0;
m_Instance.premium = 0;
m_Instance.totalBonusCount = 0;
m_Instance.totalScore = 0;
m_Instance.ftueLevel = 0;
m_Instance.rank = 0;
for (int i = 0; i < GameControllerMain.sceneNames.Length; ++i){
m_Instance.fastestTimes *= new List<FastestTimeEntry>();*
-
}*
-
m_Instance.Save();*
-
}*
public void Read()
{
BinaryReader r = new BinaryReader(new FileStream(saveFile, FileMode.Open));
int ver = r.ReadInt32();
tokens = r.ReadInt32();
// Save contains the version they were written with. If data are added bump the version & test for that version before loading that data.
if(ver >= 1)
{
premium = r.ReadInt32();
-
for (int i = 0; i < GameControllerMain.sceneNames.Length; ++i)*
-
{*
_ fastestTimes = new List();_
_ fastestTimes*.Clear();
int count = r.ReadInt32();
for (int j = 0; j < count; ++j)
{
Debug.Log(“Reading a fastest time entry”);
FastestTimeEntry entry = new FastestTimeEntry();*_
* entry.name = r.ReadString();*
* entry.time = r.ReadSingle();*
* entry.score = r.ReadInt32();*
* entry.sceneNum = r.ReadInt32();*
* entry.bonusCount = r.ReadInt32();*
_ fastestTimes*.Add(entry);
}*_
* }*
* previousName = r.ReadString();*
* licenseAccepted = r.ReadBoolean();*
* ftueLevel = r.ReadInt32();*
rank = r.ReadInt32();
* totalBonusCount = r.ReadInt32();*
* totalScore = r.ReadInt32();*
}
r.Close();
}
public void Save()
{
BinaryWriter w = new BinaryWriter(new FileStream(saveFile, FileMode.OpenOrCreate));
w.Write(s_Version);
w.Write(tokens);
w.Write(premium);
* // Write fastestTimes*
* for (int i = 0; i < GameControllerMain.sceneNames.Length; ++i){*
_ w.Write(fastestTimes*.Count);
for(int j = 0; j < fastestTimes.Count; ++i)
{
//w.Write(fastestTimes.name);
w.Write(fastestTimes[j].time);
w.Write(fastestTimes[j].sceneNum);
w.Write(fastestTimes[j].score);
w.Write(fastestTimes[j].bonusCount);
}
}*_
* // Write name.*
* w.Write(previousName);*
w.Write(licenseAccepted);
w.Write(ftueLevel);
w.Write(rank);
* w.Write(totalBonusCount);*
* w.Write(totalScore);*
w.Close();
}