- Home /
Binaryformatter android files not reading properly
This seems simple so I'm hoping someone just says "Here you go dummy".
Everything works in the Unity Editor and iOS. But on Android 90% of the time it does not deserialize properly and resets the data to 0's. It does find the file according to the logs and supposedly opens it, but everything is set to 0. Unity 4.6 is what I'm using.
Again, everything works in the editor and on iOS. But on Android most of the time it logs:
Games Played loaded from file: 0
Here's the code: using UnityEngine; using System; using System.Collections; using System.Runtime.Serialization.Formatters.Binary; using System.IO; using UnityEngine.SocialPlatforms; using UnityEngine.SocialPlatforms.GameCenter; #if UNITY_ANDROID using GooglePlayGames; #endif
public class GameControl : MonoBehaviour {
public float bestDistance;
public float lastDistance;
public float totalDistance;
public float gamesPlayed;
private string dataFileName = "/ttstuff.dat";
void OnEnable() {
LoadData ();
}
void OnDisable() {
SaveData ();
}
public void SaveData() {
#if UNITY_IPHONE
Environment.SetEnvironmentVariable("MONO_REFLECTION_SERIALIZER","yes");
#endif
BinaryFormatter bf = new BinaryFormatter ();
FileStream file = File.Open(Application.persistentDataPath + dataFileName, FileMode.Create);
PlayerData data = new PlayerData ();
data.bestDistance = bestDistance;
data.lastDistance = lastDistance;
data.totalDistance = totalDistance;
data.gamesPlayed = gamesPlayed;
bf.Serialize (file, data);
file.Close ();
}
public void LoadData() {
Debug.Log ("Datafile: " + Application.persistentDataPath + dataFileName);
#if UNITY_IPHONE
Environment.SetEnvironmentVariable("MONO_REFLECTION_SERIALIZER","yes");
#endif
if (File.Exists (Application.persistentDataPath + dataFileName)) {
Debug.Log ( "Data file exists" );
BinaryFormatter bf = new BinaryFormatter ();
FileStream file = File.Open (Application.persistentDataPath + dataFileName, FileMode.Open, FileAccess.Read );
Debug.Log ("File: " + file.ToString() );
System.Object obj = bf.Deserialize(file);
Debug.Log ("System Object: " + obj.ToString() );
PlayerData data = (PlayerData) obj;
Debug.Log ("Data: " + obj.ToString() );
Debug.Log ("File deserialized" );
file.Close ();
gamesPlayed = data.gamesPlayed;
Debug.Log ("Games played loaded from file: " + data.gamesPlayed.ToString() );
bestDistance = data.bestDistance;
totalDistance = data.totalDistance;
lastDistance = data.lastDistance;
} else {
Debug.Log ( "Data file does not exist. Setting defaults." );
// Set defaults
gamesPlayed = 0;
bestDistance = 0;
totalDistance = 0;
lastDistance = 0;
}
}
}
[System.Serializable]
class PlayerData
{
public float bestDistance;
public float lastDistance;
public float totalDistance;
public float gamesPlayed;
}
If anyone uses a different way to save off scores, I'd be interested in that too ... maybe it's time to just use User Prefs ... :(
I tried switching this to a BinaryWriter/BinaryReader and changed all the floats to doubles, it still just writes out 00 00 00 00 everywhere.
So I've tried a bunch of things and nothing works for Android, and then it hit me. This may have started occuring since I started signing the app. Is it possible that you can't side load a signed AP$$anonymous$$ and have it access it's storage? I'll try an unsigned app again. But if that was the case, how could you verify that it's working after signing
@sysameca, put that down in an answer format. The problem was that I was Saving/Loading onEnable and onDisable. Even with the Singleton, it was calling those functions and it kept saving 0's, then loading, or sometimes loading before it saved.
Adding the boolean to make sure it only loaded once fixed the problem!
Now everyone can buy the game on Google Play here: https://play.google.com/store/apps/details?id=com.kenroland.tinytanic :D
Answer by sysameca · Nov 19, 2014 at 04:53 PM
Unfortunately i don't have any Android device in hand and can't see how you set your variables so it's kind of hard to spot the bug. Eventually i wrote a slightly different save load script in case you want to check if it works on the Android device in order to understand where the problem can come from.
using UnityEngine;
using System.Collections;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
public class PersistentDataManager : MonoBehaviour
{
private string m_dataPath = "/gameData.dat";
public GameData gameData { get; private set; }
void Start()
{
LoadData();
Debug.Log(gameData.firstRun);
Debug.Log(gameData.bestDistance);
Debug.Log(gameData.lastDistance);
Debug.Log(gameData.totalDistance);
Debug.Log(gameData.gamesPlayed);
FirstRun();
}
private void SaveData()
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
FileStream stream = File.Open(Application.persistentDataPath + m_dataPath, FileMode.OpenOrCreate);
binaryFormatter.Serialize(stream, gameData);
stream.Close();
}
private void LoadData()
{
if (File.Exists(Application.persistentDataPath + m_dataPath))
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
FileStream stream = File.Open(Application.persistentDataPath + m_dataPath, FileMode.Open, FileAccess.Read);
System.Object obj = (GameData)binaryFormatter.Deserialize(stream);
stream.Close();
}
else
{
gameData = new GameData();
}
}
private void FirstRun()
{
if (gameData.firstRun == true)
{
gameData.firstRun = false;
gameData.bestDistance = 3;
gameData.lastDistance = 1;
gameData.totalDistance = 14;
gameData.gamesPlayed = 1;
SaveData();
}
}
private void OnDisable()
{
SaveData();
}
}
[System.Serializable]
public class GameData
{
public bool firstRun = true;
public float bestDistance = 0.0f;
public float lastDistance = 0.0f;
public float totalDistance = 0.0f;
public float gamesPlayed = 0.0f;
}
Basically it will save some values only one time and the second time you run the game it will test wheter you get them.
Your answer
Follow this Question
Related Questions
Serializing to disk sometimes fails on Android, but on iOS works fine 1 Answer
Serialize Data - After Update 1 Answer
Serialization: Marshal.StructureToPtr does not work "always" 0 Answers
Which types are actually serializable? Is the documentation incorrect or am I? 3 Answers
Saving HashSet using BinaryFormat 1 Answer