#I'm a bit lost trying to get Cloud Save

1 messages · Page 1 of 1 (latest)

errant crypt
#

This is the full code on my server, pretty much copied from the docs:

        public async Task SavePlayerInfo(IExecutionContext context, IGameApiClient gameApiClient, string key, object value)
        {
            try
            {
                Dictionary<string, object> playerData = new Dictionary<string, object>
                {
                    { "playerName", "Pascal" },
                };
                _ = await gameApiClient.CloudSaveData.SetProtectedItemAsync(context, context.ServiceToken, context.ProjectId,
                    context.PlayerId, new SetItemBody("playerData", playerData));
                _logger.LogInformation("Data saved for playerId {PlayerId}", context.PlayerId);
            }
            catch (ApiException ex)
            {
                _logger.LogError("Failed to save data. Error: {Error}", ex.Message);
                throw new Exception($"Failed to save data for playerId {context.PlayerId}. Error: {ex.Message}");
            }
        }```
#

When using the default access class (the one from the docs, not sure if it's default or public) I could see the data in the UGS dashboard

#

This is the code on my client, pretty much copy/pasted from the docs too:

        {
            var playerData = await CloudSaveService.Instance.Data.Player.LoadAsync(new HashSet<string> { "playerData" }, new LoadOptions(new ProtectedReadAccessClassOptions()));
            if (playerData.TryGetValue("playerData", out var keyName))
            {
                Debug.Log($"playerData: {keyName.Value.GetAs<string>()}");
            }
        }```
#

I'm not sure if the protected access class is supposed to show up in the UGS dashboard? I guess it should? If so then my data is not begin saved, though the server returns a success message?

crimson anchor
#

Hi there!

I just checked on this and it looks like viewing player data in different access classes is not yet live in the Dashboard for everyone.

We've been designing the UI for Cloud Save to bring it all in the one place (Game Data, Player Data, Player Files, Indexes for Queries, etc) and the final parts of that work are just wrapping up now.

I'm hesitant to say next week but I'm quietly optimistic it will be next week or so. We had intended for it to be wrapped up last month but realised there were still some gaps in CLI / direct REST API access, so we rolled in addressing those as part of that work, so that the surface for the product feels consistent across the Dashboard, Unity SDK, Cloud Code SDK, REST API and Unity CLI, and that pushed the rollout back a bit.

#

I want to also acknowledge we have some gaps in our coverage of how to use Cloud Save with Cloud Code.

If you haven't seen it already, the Quest System use case might be helpful:
https://docs.unity.com/ugs/en-us/manual/cloud-code/manual/modules/use-cases/quest-system#Quest_controller

The Unity SDK Tutorial has examples of using Cloud Save from Unity directly (version 3.x of the Unity SDK has the best experience, and is not breaking over version 2.x do upgrade if you are on version 2.x!):
https://docs.unity.com/ugs/en-us/manual/cloud-save/manual/tutorials/unity-sdk

The biggest thing that folks trip up on, especially with other versions of the Cloud Save SDK (i.e. version 2.x), is serialisation. This is a lot simpler in recent versions of the SDK and explicit examples of how to save and fetch objects are included in the sample that comes with the Cloud Save SDK, this sample can also be found here:
https://docs.unity.com/ugs/en-us/manual/cloud-save/manual/tutorials/unity-sdk-sample

(The biggest gap in Cloud Save documentation that I think we have is probably that we don't yet have a similar set of tutorial pages for using Cloud Save from Cloud Code.)

errant crypt
#

None of these examples show how to work with the protected access class though

#

I'm getting a Unity.Services.CloudSave.Internal.Http.JsonObject in my result, but I have no idea how to access the values in that

#

I did try a Count on my result, I get 1 when I use the key I saved and 0 when I use a random fake key, so the data should be saved, I just can't figure out how to access it

#
Unity.Services.CloudSave.Models.Item testItem = playerData["playerData"];
Debug.Log(testItem);
Debug.Log(testItem.Key);
Debug.Log(testItem.Value);
Debug.Log(testItem.Value.GetAsString());```
Well this finally gets me my saved data as a string, but it can't be intended like this? There must be a simpler solution?
#

Alright, here's the short version:


            if (playerData.TryGetValue("playerData", out var keyName))
            {
                //Debug.Log($"keyName: {keyName.Value.GetAs<string>()}");
                Debug.Log(keyName.Value.GetAsString());
            }```
#

Debug.Log($"keyName: {keyName.Value.GetAs<string>()}");
This line is in the docs, but doesn't work, it gives an error

#

Maybe because my value is json and not a string, hmm

#
        {
            var playerData = await CloudSaveService.Instance.Data.Player.LoadAsync(new HashSet<string> { "playerData" }, new LoadOptions(new ProtectedReadAccessClassOptions()));

            if (playerData.ContainsKey("playerData"))
            {
                //Debug.Log($"keyName: {keyName.Value.GetAs<string>()}");
                string playerDataJSON = playerData["playerData"].Value.GetAsString();
                Dictionary<string, object> playerDataDic = JsonConvert.DeserializeObject<Dictionary<string, object>>(playerDataJSON);

                foreach (KeyValuePair<string, object> entry in playerDataDic)
                {
                    Debug.Log(entry.Key + ": " + entry.Value);
                }
            }
        }```
Here's the full working example 🙂
#

Any way you could enable the protected player data access class in my UGS dashboard?

crimson anchor
#

Oh thanks for sharing!

I was going to say hmm yes that could be it, I'm mindful we need some actual examples on the docs site and we have identified there might not be parity between how the Unity SDK vs the Cloud Code SDK behave in some cases.

We very much want to solve for this, we've added a lot to the service over the last few months and we haven't resolved that, but is something we plan to do (and reflect on what we can add to the Cloud Code SDK to make it easier to use with data serialised from Unity, e.g. sharing a model between both).

#

Any way you could enable the protected player data access class in my UGS dashboard?
I'm not sure there is at the moment, but I can get back to you tomorrow on that.

In the mean time if you were to save the data in the default access class you should be able to check it's being written correclty (and just swap the method name out).

You can also use logging to more view data from Cloud Code. I appreciate that's not ideal, but might help in the interim.

errant crypt
#

I will only be using the protected class for now, so that would be great

#

but yeah I can see it now anyway in my client so it's fine

wet timber
errant crypt
#

I'm happy to help u get started if you have more questions, but please look at the docs first

wet timber
#

Hey thank you so much. I'll look at these docs. I actually found another post of yours where you shared the API call you were making to save protected data. Right now I'm trying to set up a proof of concept but it's definitely a struggle. I have successfully deployed a Cloud Code script and made a call to it (following Unity tutorial) but right now I'm trying to create a trigger to call my function when a leaderboard is reset.

#

So far I've created a trigger and deployed it using CLI. Everything looks correct to me but I'm not seeing the Trigger in my Unity dashboard. Appreciate the help, thanks!

wet timber
#

Ok update it looks like the Trigger WAS uploaded properly - it just doesn't show up in the Dashboard! This seems to be a running theme with Unity Gaming Services...

simple crest