Search Unity

Question Usernames and saving the data

Discussion in 'Leaderboards' started by rbitard, May 1, 2023.

  1. rbitard

    rbitard

    Joined:
    Jan 11, 2022
    Posts:
    197
    Hello,
    My users ask me when they could change their displayed name, do you have an ETA ? (or I missed something in the documentation :D)

    Is there a way at the moment to prevent the user from losing his score when updating the game ?

    Thanks in advance,
     
  2. MiTschMR

    MiTschMR

    Joined:
    Aug 28, 2018
    Posts:
    489
    If you choose to use a preview version, you can implement this feature: https://docs.unity3d.com/Packages/com.unity.services.authentication@2.5/changelog/CHANGELOG.html
    The service uses the player name set by the Authentication service and if it doesn't have one it will generate one.

    What do you mean with that?
     
    IainUnity3D likes this.
  3. Brogan89

    Brogan89

    Joined:
    Jul 10, 2014
    Posts:
    244
    There is
    AuthenticationService.Instance.UpdatePlayerNameAsync()
    which is in
    "com.unity.services.authentication": "2.5.0-pre.3"
    package.

    However, I found it wasn't working for everyone. So I'm currently using CloudCode/CloudSave to get usernames.

    I admit it is a very hodge-podge way of going about it, but at least it's reliable.
     
    Last edited: May 2, 2023
  4. rbitard

    rbitard

    Joined:
    Jan 11, 2022
    Posts:
    197
    Thanks for the link I'll check it out. Currently to my users when they download a new version of my app it changes their authent, it's probably because they are anonymously logged in, if I change that it probably will work but I will need to implement authent providers, do you think I'm right ?
    Oh thanks a lot !
    It's odd it's not working with everyone, did you open a ticket ?
     
  5. Brogan89

    Brogan89

    Joined:
    Jul 10, 2014
    Posts:
    244
    For anyone interested in using CloudCode/CloudData to get/set usernames...



    The cloud code used I got from the docs mostly

    but create a cloud code script with parameters playerId (string) and keys (json), which will be a json array on the client.

    Code (JavaScript):
    1. const { DataApi } = require('@unity-services/cloud-save-1.2');
    2.  
    3. module.exports = async ({ params, context, logger }) => {
    4.  
    5.   logger.debug("params: " + JSON.stringify(params));
    6.   logger.debug("context: " + JSON.stringify(context));
    7.  
    8.   const { projectId } = context;
    9.   const { playerId, keys } = params;
    10.  
    11.   logger.info("PlayerId: " + playerId);
    12.   logger.info("Keys: " + JSON.stringify(keys));
    13.  
    14.   // Initialize the cloud save API client
    15.   const cloudSaveAPI = new DataApi(context);
    16.  
    17.   let returnData = {};
    18.  
    19.   // Access the save data for the specified player
    20.   const otherPlayerSave = await cloudSaveAPI.getItems(projectId, playerId, keys);
    21.  
    22.   logger.info("Data: " + JSON.stringify(otherPlayerSave.data.results));
    23.  
    24.   for (let i =0; i < otherPlayerSave.data.results.length; i++){
    25.     let key = otherPlayerSave.data.results[i].key;
    26.     let value = otherPlayerSave.data.results[i].value;
    27.     returnData[key] = value;
    28.   }
    29.  
    30.   // Return the JSON result to the client
    31.   return returnData;
    32. };

    Then on clide side you can use code similar to this


    Code (CSharp):
    1.         /// <summary>
    2.         /// Get players data from keys given. No keys will assign all keys
    3.         /// </summary>
    4.         /// <param name="playerId"></param>
    5.         /// <param name="keys"></param>
    6.         /// <returns></returns>
    7.         public static async UniTask<Dictionary<string, string>> GetPlayerData(string playerId, params string[] keys)
    8.         {
    9.             SanitiseKeys(ref keys);
    10.  
    11.             var arguments = new Dictionary<string, object>
    12.             {
    13.                 [nameof(playerId)] = playerId,
    14.                 [nameof(keys)] = keys
    15.             };
    16.        
    17.             var res = await FetchAsync("get-cloud-data", arguments);
    18.             var data = JObject.Parse(res).ToObject<Dictionary<string, string>>();
    19.    
    20.             // you can create your own c# classes here and return it if you want
    21.  
    22.             return data;
    23.         }
    24.  
    25.  
    26.  
    27.         private static async UniTask<string> FetchAsync(string function, Dictionary<string, object> arguments)
    28.         {
    29. #if UNITY_EDITOR
    30.             var sw = Stopwatch.StartNew();
    31.             Debug.Log($"[CloudCode] {function} fetching data {Json.Serialize(arguments)}s");
    32. #endif
    33.  
    34.             var (isTimedOut, res) = await CloudCodeService.Instance
    35.                 .CallEndpointAsync(function, arguments)
    36.                 .AsUniTask()
    37.                 .TimeoutWithoutException(TimeSpan.FromMilliseconds(TIME_OUT));
    38.  
    39. #if UNITY_EDITOR
    40.             Debug.Log($"[CloudCode] {function} returns in {sw.ElapsedMilliseconds / 1000f:0.0}s");
    41.             sw.Stop();
    42. #endif
    43.        
    44.             if (!isTimedOut)
    45.                 return res;
    46.  
    47.             Debug.LogError($"[CloudCode] {function} Timed out");
    48.             return null;
    49.         }
    Then on client you can get any key from cloud data like "Username"
    GetPlayerData("playerId", "Username")




    Should get you started anyway :)