I’m upgrading my game to be able to save fastest completion time for each level using serialization. I’ve tested on the editor and on PC as standalone and it works fine. Running it on Android however, it doesn’t seem like it is writing the data thus leaving fastest time record empty.
Here’s the coding that deals with the saving and loading the best time:
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
public class PlayTimer : MonoBehaviour {
public Text timerText;
public bool gameEnd = false;
public Text currentBestTime;
public Text yourTime;
private float startTime;
public string finalTime;
float t;
float minutes;
float seconds;
float milliseconds;
float totalMs;
float totalBest;
float bestMinutes;
float bestSeconds;
float bestMilliseconds;
public int level;
public float targetGold;
public float targetSilver;
public GameObject goldMedal;
public GameObject silverMedal;
public GameObject bronzeMedal;
TimeData timer = new TimeData();
void Start () {
startTime = Time.time;
Load ();
}
// Update is called once per frame
void Update () {
if (gameEnd) {
finalTime = timerText.text;
yourTime.text = timerText.text;
totalMs = ((minutes * 60) * 1000) + (seconds * 1000) + milliseconds;
if (totalMs <= targetGold) {
goldMedal.SetActive (true);
} else if (totalMs <= targetSilver) {
silverMedal.SetActive (true);
} else {
bronzeMedal.SetActive (true);
}
if (totalMs < totalBest) {
//Debug.Log (totalMs);
//Debug.Log (totalBest);
Save ();
}
return;
}
t = Time.time - startTime;
minutes = ((int)t / 60);
seconds = (t % 60);
milliseconds = (t * 1000);
milliseconds = milliseconds % 1000;
timerText.text = minutes.ToString("00") + ":" + seconds.ToString("00") + ":" + milliseconds.ToString("00");
}
public void Save(){
//Debug.Log ("Saving...");
BinaryFormatter bf = new BinaryFormatter ();
FileStream stream = File.Open (Application.persistentDataPath + "/timer.sav", FileMode.OpenOrCreate);
timer.minute[level] = minutes;
timer.second[level] = seconds;
timer.millisecond[level] = milliseconds;
if (totalMs <= targetGold) {
timer.medal [level] = 3;
} else if (totalMs <= targetSilver) {
timer.medal [level] = 2;
} else {
timer.medal [level] = 1;
}
bf.Serialize (stream, timer);
stream.Close (); //finalize the saving
}
public void Load(){
//Debug.Log ("Loading...");
if (File.Exists (Application.persistentDataPath + "/timer.sav")) {
BinaryFormatter bf = new BinaryFormatter ();
FileStream stream = File.Open (Application.persistentDataPath + "/timer.sav", FileMode.Open, FileAccess.Read);
timer = (TimeData)bf.Deserialize(stream);
stream.Close ();
bestMinutes = timer.minute[level];
bestSeconds = timer.second[level];
bestMilliseconds = timer.millisecond[level];
totalBest = ((bestMinutes * 60) * 1000) + (bestSeconds * 1000) + bestMilliseconds;
if (bestMilliseconds > 0.0) {
SetBestTime (true);
}
} else {
SetBestTime (false);
//Debug.LogError ("File does not exist.");
}
}
public void SetBestTime(bool Set){
if (Set) {
currentBestTime.text = "Best Time: " + bestMinutes.ToString("00") + ":" + bestSeconds.ToString("00") + ":" + bestMilliseconds.ToString("00");
} else {
currentBestTime.text = "Best Time: --:--:--";
}
}
}
[Serializable]
public class TimeData {
public float[] minute;
public float[] second;
public float[] millisecond;
public int[] medal;
public TimeData() {
minute = new float[50];
second = new float[50];
millisecond = new float[50];
medal = new int[50];
}
}
I’ve been trying to find solution and fixes like use persistentDataPath, making sure that the Write Access is set to External, double checking the AdroidManifest.xml and still to no avail.
This is my first time doing serialization on mobile so I’m not sure what else I could be missing since the test on PC seems to be working fine. Is there something I’m missing? I need to have this feature working by end of the month.