I created a very simple scene in order to understand how CloudSave works. I have one object called DatabaseManager that contains the following:
public class DatabaseManager : MonoBehaviour {
async void Awake() {
await UnityServices.InitializeAsync();
await AuthenticationService.Instance.SignInAnonymouslyAsync();
Debug.Log($"Player id:{AuthenticationService.Instance.PlayerId}");
}
public static async void SaveScore(int score) {
var playerData = new Dictionary<string, object>{
{"score", score},
};
await CloudSaveService.Instance.Data.Player.SaveAsync(playerData);
}
public static async Task<int> LoadScore() {
var playerData = await CloudSaveService.Instance.Data.Player.LoadAsync(new HashSet<string> {"score"});
if (playerData.TryGetValue("score", out var scoreVar)) {
int score = scoreVar.Value.GetAs<int>();
Debug.Log($"loaded score value: {score}");
return score;
} else {
throw new Exception("Could not load score");
}
}
}
On another object, I have the following code:
public class Score : MonoBehaviour {
[SerializeField] int score = 0;
async void Start() {
score = await DatabaseManager.LoadScore();
}
public async void IncreaseScore() {
score++;
await DatabaseManager.SaveScore(score);
}
}
where the function IncreaseScore() is called when a button is clicked.
It sometimes works, but sometimes I get the following exception while trying to load the score:
CloudSaveException: Access token is missing - ensure you are signed in through the Authentication SDK and try again.
...
Unity.Services.CloudSave.Internal.PlayerDataService.LoadAsync (System.Collections.Generic.ISet`1[T] keys) (at ./Library/PackageCache/com.unity.services.cloudsave/Runtime/com.unity.services.cloudsave.internal/Runtime/PlayerDataService.deprecated.cs:126)
DatabaseManager.LoadScore () (at Assets/Scripts/DatabaseManager.cs:44)
Score.Start () (at Assets/Score.cs:8)
I guess it is because the “LoadScore” function is called before the login process is finished. Indeed, when I add the following line at the start of Score.Start:
await Awaitable.WaitForSecondsAsync(0.1f);
the score is loaded with no error.
But, this is just an arbitrary waiting time - it does not seem like the right solution.
What is the correct way to read data immediately when the scene starts?