Cloud Save and Serializable objects throwing errors

Hello,

I’m currently trying to save a list of player-selected cosmetic items to Cloud Save service.

The list is of type “List”. I have had no problems serializing and saving these objects locally to a file using JsonUtility.

I am now experimenting with moving certain save data into the cloud.

However, when I try to send the same data to Cloud Save, I’m getting this error:

My code:

List<AssetReference> items; // passed in parameter
Dictionary<string, object> dataDictionary = new()
{
    { "EquippedItems", items }
};

await CloudSaveService.Instance.Data.ForceSaveAsync(dataDictionary);

I’m assuming that the Dictionary value “object” is valid for any serializable type, correct?

What is happening here? I can serialize these objects with no issue locally, so why would there be an issue with Cloud Save? Are there some serialization limitations specific to Cloud Save I’m not aware of?

Thanks for flagging this @LiterallyJeff , we’ll take a look on our end. In the meantime, one workaround is using JsonUtility to serialise the dictionary into JSON then upload that into Cloud Save.

1 Like

Looks like saving out just the AssetGUIDs string from the AssetReferences, and then loading them at runtime using “new AssetReference(guid)” and loading assets via Addressables.LoadAssetAsync / InstantiateAsync using that AssetReference as the key can work just fine, and the string array is way friendlier for json and CloudSave.

Anyone else seeing this error and not knowing what’s up, for us once we dug in, we found a “can only call this from the main thread” inner exception. We were trying to call it outside of the proper scope. So moved it in to a coroutine and all was well.

So i tried this and the json adds backslashes to the json when converted as an object

Since this post, we’ve updated the Cloud Save SDK to improve the API surface.

You can upgrade to the latest release using the Package Manager to get version Cloud Save 3.0.

As an example of how to save and load an object using v3:

using System.Collections.Generic;
using Unity.Services.Authentication;
using Unity.Services.CloudSave;
using Unity.Services.CloudSave.Models;
using Unity.Services.Core;
using UnityEngine;

public class CloudSaveSample : MonoBehaviour
{
    private async void Awake()
    {
        await UnityServices.InitializeAsync();
        await AuthenticationService.Instance.SignInAnonymouslyAsync();
    }

    public async void SaveData()
    {
        var playerData = new Dictionary<string, object>{
          {"firstKeyName", "a text value"},
          {"secondKeyName", 123}
        };
        await CloudSaveService.Instance.Data.Player.SaveAsync(playerData);
        Debug.Log($"Saved data {string.Join(',', playerData)}");
    }

    public async void LoadData()
    {
        var playerData = await CloudSaveService.Instance.Data.Player.LoadAsync(new HashSet<string> {
          "firstKeyName", "secondKeyName"
        });

        if (playerData.TryGetValue("firstKeyName", out var firstKey)) {
            Debug.Log($"firstKeyName value: {firstKey.Value.GetAs<string>()}");
        }

        if (playerData.TryGetValue("secondKeyName", out var secondKey)) {
            Debug.Log($"secondKey value: {secondKey.Value.GetAs<int>()}");
        }
    }
}
2 Likes

I get this error when running this code trying to load data from cloud save:

NotImplementedException: The method or operation is not implemented.
Unity.Services.CloudSave.Internal.Models.DeleteItem400OneOfJsonConverter.CanConvert (System.Type objectType) (at ./Library/PackageCache/com.unity.services.cloudsave@3.0.0/Runtime/com.unity.services.cloudsave.internal/Runtime/Models/DeleteItem400OneOf.cs:172) 9530263--1344994--upload_2023-12-14_13-13-27.png

If you can make a new thread for the issue, as it’s a different error, and include the code you are using to load/save (and maybe an example of a payload) happy to take a look.