Search Unity

Bug Cloud Save and Serializable objects throwing errors

Discussion in 'Cloud Save' started by LiterallyJeff, Mar 12, 2023.

  1. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,807
    Hello,

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

    The list is of type "List<AssetReference>". 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:
    Code (CSharp):
    1. List<AssetReference> items; // passed in parameter
    2. Dictionary<string, object> dataDictionary = new()
    3. {
    4.     { "EquippedItems", items }
    5. };
    6.  
    7. 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?
     
    Last edited: Mar 12, 2023
  2. rambod

    rambod

    Unity Technologies

    Joined:
    Mar 2, 2018
    Posts:
    58
    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.
     
    LiterallyJeff likes this.
  3. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,807
    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.
     
    Last edited: Mar 15, 2023
  4. icosajim

    icosajim

    Joined:
    Mar 28, 2015
    Posts:
    2
    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.
     
  5. JParish2590

    JParish2590

    Joined:
    Jan 8, 2014
    Posts:
    32
    So i tried this and the json adds backslashes to the json when converted as an object
     
  6. IainUnity3D

    IainUnity3D

    Unity Technologies

    Joined:
    Oct 5, 2022
    Posts:
    36
    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:

    Code (CSharp):
    1. using System.Collections.Generic;
    2. using Unity.Services.Authentication;
    3. using Unity.Services.CloudSave;
    4. using Unity.Services.CloudSave.Models;
    5. using Unity.Services.Core;
    6. using UnityEngine;
    7.  
    8. public class CloudSaveSample : MonoBehaviour
    9. {
    10.     private async void Awake()
    11.     {
    12.         await UnityServices.InitializeAsync();
    13.         await AuthenticationService.Instance.SignInAnonymouslyAsync();
    14.     }
    15.  
    16.     public async void SaveData()
    17.     {
    18.         var playerData = new Dictionary<string, object>{
    19.           {"firstKeyName", "a text value"},
    20.           {"secondKeyName", 123}
    21.         };
    22.         await CloudSaveService.Instance.Data.Player.SaveAsync(playerData);
    23.         Debug.Log($"Saved data {string.Join(',', playerData)}");
    24.     }
    25.  
    26.     public async void LoadData()
    27.     {
    28.         var playerData = await CloudSaveService.Instance.Data.Player.LoadAsync(new HashSet<string> {
    29.           "firstKeyName", "secondKeyName"
    30.         });
    31.  
    32.         if (playerData.TryGetValue("firstKeyName", out var firstKey)) {
    33.             Debug.Log($"firstKeyName value: {firstKey.Value.GetAs<string>()}");
    34.         }
    35.  
    36.         if (playerData.TryGetValue("secondKeyName", out var secondKey)) {
    37.             Debug.Log($"secondKey value: {secondKey.Value.GetAs<int>()}");
    38.         }
    39.     }
    40. }
     
    kmowers and LiterallyJeff like this.
  7. DangerDano

    DangerDano

    Joined:
    Jun 8, 2019
    Posts:
    1
    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) upload_2023-12-14_13-13-27.png
     
  8. IainUnity3D

    IainUnity3D

    Unity Technologies

    Joined:
    Oct 5, 2022
    Posts:
    36
    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.