question

infomrvkrt avatar image
infomrvkrt asked

How to Integrate Playfab Login, Score API?

I want to if the players log in, their score’s save and show a leaderboard. I used to only score API. So end of the game players both register then login and fetch their score Playfab. But If it's possible that they use the my current Score API and new login-regester manager script? Both also below. Thanks in advance.

My Login/Register Script (Manager)

 using UnityEngine;
    using PlayFab;
    using PlayFab.ClientModels;
    using TMPro;
    using UnityEngine.UI;
    
    public class PlayFabLoginManager : MonoBehaviour
    {
        [Header("Screens")]
        public GameObject LoginPanel;
        public GameObject RegisterPanel;
    
        [Header("Login Screen")]
        public TMP_InputField LoginEmailField;
        public TMP_InputField LoginPasswordField;
        public Button LoginBtn;
        public Button RegisterBtn;
    
        [Header("Register Screen")]
        public TMP_InputField RegisterEmailField;
        public TMP_InputField RegisterDisplayNameField;
        public TMP_InputField RegisterPasswordwordField;
        public Button RegisterAccountBtn;
        public Button BackBtn;
    
        public void OpenLoginPanel()
        {
            LoginPanel.SetActive(true);
            RegisterPanel.SetActive(false);
        }
    
        public void OpenRegistrationPanel()
        {
            LoginPanel.SetActive(false);
            RegisterPanel.SetActive(true);
        }
    
        public void OnTryLogin()
        {
            string email = LoginEmailField.text;
            string password = LoginPasswordField.text;
    
            LoginBtn.interactable = false;
    
            LoginWithEmailAddressRequest req = new LoginWithEmailAddressRequest
            {
                Email = email,
                Password = password
            };
    
            PlayFabClientAPI.LoginWithEmailAddress(req,
            res =>
            {
                Debug.Log("Login Success");
            },
            err =>
            {
                Debug.Log("Error: " + err.ErrorMessage);
                LoginBtn.interactable = true;
            });
        }
    
        public void OnTryRegisterNewAccount()
        {
            BackBtn.interactable = false;
            RegisterAccountBtn.interactable = false;
    
            string email = RegisterEmailField.text;
            string displayName = RegisterDisplayNameField.text;
            string password = RegisterPasswordwordField.text;
    
            RegisterPlayFabUserRequest req = new RegisterPlayFabUserRequest
            {
                Email = email,
                DisplayName = displayName,
                Password = password,
                RequireBothUsernameAndEmail = false
            };
    
            PlayFabClientAPI.RegisterPlayFabUser(req,
            res =>
            {
                BackBtn.interactable = true;
                RegisterAccountBtn.interactable = true;
                OpenLoginPanel();
                Debug.Log(res.PlayFabId);
            },
            err =>
            {
                BackBtn.interactable = true;
                RegisterAccountBtn.interactable = true;
                Debug.Log("Error: " + err.ErrorMessage);
            });
    
        }

}

My Score API:


using System;

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using PlayFab;
using PlayFab.ClientModels;

public struct HighScore {
    public HighScore(string displayName, int score) {
        DisplayName = displayName;
        Score = score;
    }
    
    public string DisplayName { get; }
    public int Score {get; }
}

public class ScoreAPI : MonoBehaviour
{
    const string HIGH_SCORE_STATISTIC = "HighScore";
    const string PLAYER_ID_PREF = "PlayerId";
    const int HIGH_SCORE_START_POSITION = 0;
    const int HIGH_SCORE_FETCH_COUNT = 10;

    public string playerIdOverride;

    private int latestScore = 250;

    private static ScoreAPI instance;
    public static ScoreAPI Instance
    {
        get { return instance; }
    }

    private void Awake()
    {
        if (instance != null && instance != this)
        {
            Destroy(this.gameObject);
            return;
        }
        instance = this;

        DontDestroyOnLoad(this.gameObject);
    }

    public void SetLatestScore(int score) {
        latestScore = score;
    }

    public void FetchHighScores(Action<HighScore[]>  successCallback, Action<string> errorCallback) {
        // Fetch top high scores from the API
        LoginThen(() => {

                Debug.Log("API: Fetching scores...");
                PlayFabClientAPI.GetLeaderboard(new GetLeaderboardRequest {
                StatisticName = HIGH_SCORE_STATISTIC,
                StartPosition = HIGH_SCORE_START_POSITION,
                MaxResultsCount = HIGH_SCORE_FETCH_COUNT
                }, 
                result=> {
                    HighScore[] scores = new HighScore[result.Leaderboard.Count];
                    for (int i=0; i < result.Leaderboard.Count; i++ ) {                        
                    PlayerLeaderboardEntry entry = result.Leaderboard[i];
                        scores[i] = new HighScore(entry.DisplayName, entry.StatValue);
                    }
                    successCallback(scores);
                }, 
                errorResult => {
                    Debug.LogWarning("Something went wrong with fetching high scores:");
                    Debug.LogError(errorResult.GenerateErrorReport());
                    errorCallback("Error fetching high scores");
                });
            },
            errorMessage => {
                errorCallback(errorMessage);
            });
    }

    public void PublishCurrentScoreWithName(string displayName, Action successCallback, Action<string> errorCallback) {
        // Make two api calls, first to set the name of the current user, then to set their latest score.
        // Always call login first -- less efficient, but avoids having to deal with re-logging in on session timeout
        LoginThen(() => {
            SetDisplayName(displayName, 
                () => {
                    PublishScore(latestScore, 
                        successCallback,
                        errorCallback);
                },
                errorCallback);
            }, 
            errorMessage => {
                errorCallback(errorMessage);
            }
        );
    }

    void SetDisplayName(string displayName, Action successCallback, Action<string> errorCallback) {
        // Make an API call to set the logged-in users current name
        Debug.Log("API: Setting display name...");
        PlayFabClientAPI.UpdateUserTitleDisplayName(new UpdateUserTitleDisplayNameRequest {
            DisplayName=displayName
            
            }, 
        result=> {
            successCallback();
        }, 
        errorResult => {
            Debug.LogWarning("Something went wrong with setting display name:");
            Debug.LogError(errorResult.GenerateErrorReport());
            errorCallback("Error updating high score");
        });
    }

    void PublishScore(int score, Action successCallback, Action<string> errorCallback) {
        // Make an API call to set the latest high score for the logged in user
        Debug.Log("API: Publishing score...");
        PlayFabClientAPI.UpdatePlayerStatistics(new UpdatePlayerStatisticsRequest {
            Statistics = new List<StatisticUpdate> {
                new StatisticUpdate {
                    StatisticName = HIGH_SCORE_STATISTIC,
                    Value = score
                }
            }
        }, 
        result=> {
            successCallback();
        }, 
        errorResult => {
            Debug.LogWarning("Something went wrong with setting high score:");
            Debug.LogError(errorResult.GenerateErrorReport());
            errorCallback("Error updating high score");
        });
    }

    string GetPlayerID() {
        // Return the persistent ID for the current player. This will be auto-generated and
        // stored in preferences. Of course this means if the preferences are removed/editing, this 
        // ID will change

        // To make testing easier, allow overriding this ID from the editor
        if (this.playerIdOverride.Length > 0) {
            return this.playerIdOverride;
        }

        string playerId = PlayerPrefs.GetString(PLAYER_ID_PREF);
        if (playerId == "") {
            playerId = System.Guid.NewGuid().ToString();
            PlayerPrefs.SetString(PLAYER_ID_PREF,playerId);
        }

        return playerId;
    }

    void LoginThen( Action successCallback, Action<string> errorCallback) {
        // Login the user to the API, then call either success or error. Error will be 
        // passed an error message as a string
        Debug.Log("API: Logging in...");
        var request = new LoginWithCustomIDRequest { CustomId = GetPlayerID(), CreateAccount = true};
        PlayFabClientAPI.LoginWithCustomID(request, 
            result => {
                successCallback();
            }, 
            errorResult => {
                Debug.LogWarning("Something went wrong with login:");
                Debug.LogError(errorResult.GenerateErrorReport());
                errorCallback("Error logging into high score server");
            });
    }
}
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

1 Answer

·
Gosen Gao avatar image
Gosen Gao answered

From what I understand, currently, your game’s workflow is like:

  1. Players play the game.
  2. After the game is over, log them in.
  3. Update the score and display a leaderboard.

Usually, we recommend the workflow like this:

  1. Players login first.
  2. They play the game.
  3. After the game is over, update the score and display a leaderboard.

With your new register-login script you should be able to let players register or login first and then start the game process. Just need to refactor the part of code to update score and it should be fine.

10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.