Open vidicunt opened 7 years ago
Can you share more of the log? It will help diagnose the issue.
That's all the log will show me, just this one error.
EDIT: @claywilkinson
12-24 00:58:50.190 I/GMPM (8164): App measurement is starting up 12-24 00:58:50.220 E/GMPM (8164): getGoogleAppId failed with status: 10 12-24 00:58:50.225 E/GMPM (8164): Uploading is not possible. App measurement disabled
What about when you sign in? Did you authenticate successfully? This message has nothing to do with SaveGamesAPI.
@claywilkinson Yes, I'm 100% sure signing in is working fine. This error ONLY appears when I try to upload saved games.
Can you share the complete log? This message has nothing to do with Saved Games.
I've been trying to get cloud saving working for a few weeks now and at one point it seemed to be working and it hasn't worked since. I am no programming wiz and I have no idea how to fix the problem. I have taken snippets from the how to on this and from some other places and I just cant figure it out. It signs in fine and still does now but wont save or load anymore.
An error ive gotten from my phone recently: Failed to read binary data: System.runtime.serializationException: serializationStream supports seeking, but its length is 0
As I said im no expert and ive used code examples from the how to and all over the place..
Code:
using GooglePlayGames; using GooglePlayGames.BasicApi; using GooglePlayGames.BasicApi.SavedGame; using System; using System.Collections; using System.IO; using System.Runtime.Serialization.Formatters.Binary; using UnityEngine; using UnityEngine.UI;
[Serializable] public class CloudData {
public int Level = 0;
public int Score = 0;
public int Dragons = 0;
// Convert class instance to byte array
public static byte[] ToBytes(CloudData data)
{
var formatter = new BinaryFormatter();
using (var stream = new MemoryStream())
{
formatter.Serialize(stream, data);
return stream.ToArray();
}
}
// Convert byte array to class instance
public static CloudData FromBytes(byte[] data)
{
using (var stream = new MemoryStream())
{
var formatter = new BinaryFormatter();
stream.Write(data, 0, data.Length);
stream.Seek(0, SeekOrigin.Begin);
CloudData block = (CloudData)formatter.Deserialize(stream);
return block;
}
}
}
public class CloudSaver : MonoBehaviour {
// Variables
bool userSignedIn = false;
ISavedGameMetadata currentGame = null;
public static CloudSaver singleton;
public Text UserT, DebugT, LevelT, ScoreT, DragonsT;
private string saveString = "GPGStestSave2";
public int level = 0, score = 0, dragons = 0;
void GetUI()
{
UserT = GameObject.Find("UserName").GetComponent<Text>();
DebugT = GameObject.Find("DebugInfo").GetComponent<Text>();
LevelT = GameObject.Find("Level").GetComponent<Text>();
ScoreT = GameObject.Find("Score").GetComponent<Text>();
DragonsT = GameObject.Find("Dragons").GetComponent<Text>();
}
void Awake()
{
Environment.SetEnvironmentVariable("MONO_REFLECTION_SERIALIZER", "yes");
GetUI();
}
// Use this for initialization
void Start()
{
InitPlayServices();
singleton = this;
PlayGamesPlatform.Instance.Authenticate(CallbackSignInUser,true);
}
void Update()
{
LevelT.text = level.ToString();
ScoreT.text = score.ToString();
DragonsT.text = dragons.ToString();
}
// Initialize google play services
void InitPlayServices()
{
PlayGamesClientConfiguration config = new PlayGamesClientConfiguration.Builder()
.EnableSavedGames()
.Build();
PlayGamesPlatform.InitializeInstance(config);
PlayGamesPlatform.DebugLogEnabled = true;
PlayGamesPlatform.Activate();
}
// Sign in the user
public void SignInUser()
{
if (!userSignedIn)
PlayGamesPlatform.Instance.Authenticate(CallbackSignInUser);
else
{
PlayGamesPlatform.Instance.SignOut();
}
}
// The sign in callback
void CallbackSignInUser(bool success)
{
if (success)
{
userSignedIn = true;
UserT.text = "Signed In As: " + Social.localUser.userName;
LoadGame();
}
else { userSignedIn = false; UserT.text = "Failed To Log In!"; }
}
// Read the save game
void ReadSaveGame(string filename, Action<SavedGameRequestStatus, ISavedGameMetadata> callback)
{
// Check if signed in
if (userSignedIn)
{
ISavedGameClient savedGameClient = PlayGamesPlatform.Instance.SavedGame;
savedGameClient.OpenWithAutomaticConflictResolution(filename,
DataSource.ReadCacheOrNetwork,
ConflictResolutionStrategy.UseLongestPlaytime,
callback);
}
}
// Write the save game
void WriteSaveGame(ISavedGameMetadata game, byte[] savedData, Action<SavedGameRequestStatus, ISavedGameMetadata> callback)
{
// Check if signed in
if (userSignedIn)
{
SavedGameMetadataUpdate updatedMetadata = new SavedGameMetadataUpdate.Builder()
.WithUpdatedPlayedTime(TimeSpan.FromMinutes(game.TotalTimePlayed.Minutes + 1))
.WithUpdatedDescription("Saved at: " + DateTime.Now)
.Build();
ISavedGameClient savedGameClient = PlayGamesPlatform.Instance.SavedGame;
savedGameClient.CommitUpdate(game, updatedMetadata, savedData, callback);
}
}
// Save the game
public void SaveGame()
{
// Check if signed in
if (userSignedIn)
{
// Save game callback
Action<SavedGameRequestStatus, ISavedGameMetadata> writeCallback =
(SavedGameRequestStatus status, ISavedGameMetadata game) => {
};
// Read binary callback
Action<SavedGameRequestStatus, byte[]> readBinaryCallback =
(SavedGameRequestStatus status, byte[] data) => {
// Create new save data
CloudData CloudSaveData = CloudData.FromBytes(data);
// These values are hard coded for the purpose of this tutorial.
// Normally, you would replace these values with whatever you want to save.
CloudSaveData.Level += 1;
CloudSaveData.Score += 10;
CloudSaveData.Dragons += 2;
WriteSaveGame(currentGame, CloudData.ToBytes(CloudSaveData), writeCallback);
};
// Read game callback
Action<SavedGameRequestStatus, ISavedGameMetadata> readCallback =
(SavedGameRequestStatus status, ISavedGameMetadata game) => {
// Check if read was successful
if (status == SavedGameRequestStatus.Success)
{
currentGame = game;
PlayGamesPlatform.Instance.SavedGame.ReadBinaryData(game, readBinaryCallback);
}
};
// Replace "MySaveGame" with whatever you would like to save file to be called
ReadSaveGame(saveString, readCallback);
}
}
// Load the game
public void LoadGame()
{
// Check if signed in
if (userSignedIn)
{
// Read binary callback
Action<SavedGameRequestStatus, byte[]> readBinaryCallback =
(SavedGameRequestStatus status, byte[] data) => {
// Check if read was successful
if (status == SavedGameRequestStatus.Success)
{
// Load game data
try
{
CloudData CloudData = CloudData.FromBytes(data);
// We are displaying these values for the purpose of the tutorial.
// Normally you would set the values here.
level = CloudData.Level;
score = CloudData.Score;
dragons = CloudData.Dragons;
}
catch (Exception e)
{
DebugT.text = ("Failed to read binary data: " + e.ToString());
}
}
};
// Read game callback
Action<SavedGameRequestStatus, ISavedGameMetadata> readCallback =
(SavedGameRequestStatus status, ISavedGameMetadata game) => {
// Check if read was successful
if (status == SavedGameRequestStatus.Success)
{
currentGame = game;
PlayGamesPlatform.Instance.SavedGame.ReadBinaryData(game, readBinaryCallback);
}else
{
currentGame = game;
PlayGamesPlatform.Instance.SavedGame.ReadBinaryData(game, readBinaryCallback);
}
};
// Replace "MySaveGame" with whatever you would like to save file to be called
ReadSaveGame(saveString, readCallback);
}
}
//delete save
public void DeleteGameData()
{
// Open the file to get the metadata.
ISavedGameClient savedGameClient = PlayGamesPlatform.Instance.SavedGame;
savedGameClient.OpenWithAutomaticConflictResolution(saveString, DataSource.ReadCacheOrNetwork,
ConflictResolutionStrategy.UseLongestPlaytime, DeleteSavedGame);
}
void DeleteSavedGame(SavedGameRequestStatus status, ISavedGameMetadata game)
{
if (status == SavedGameRequestStatus.Success)
{
ISavedGameClient savedGameClient = PlayGamesPlatform.Instance.SavedGame;
savedGameClient.Delete(game);
DebugT.text = "Save Deleted!";
}
else
{
// handle error
DebugT.text = "Error Deleting Save!";
}
}
}
Please some help would be appreciated
@ColmLeonard - can you open a separate issue and include the log from when you are authenticating on the device to when it tries to read your saved game?
Can you check for success in readBinaryCallback before reading the bytes? From the error message your getting it looks like that is failing, or it is reading an empty save game.
Whenever I try to upload saved game, I get this error in logcat:
Uploading is not possible. App measurement disabled