Desenvolvimento & Produção

Como criar um ranking online na Unity usando a PlayFab e o Facebook

Como criar um ranking online na Unity usando a PlayFab e o Facebook

Coloque seu nome e email para receber meus melhores conteúdos:

Este é um artigo convidado escrito por Leonardo Thurler sobre como criar um ranking online multiplataforma utilizando a integração do Facebook e da Playfab na Unity, que é uma das game engines mais utilizadas por desenvolvedores atualmente.

Leonardo é cientista da computação e trabalha com análise de sistemas, desenvolvendo jogos em seu tempo livre.

Ele também é aluno da Academia de Produção de Jogos, nosso treinamento online com cursos, entrevistas e uma comunidade incrível de desenvolvedores de games.

O Leonardo já escreveu outro artigo aqui no PDJ sobre como calcular o tamanho da câmera ortográfica na Unity e, agora, ele irá te ensinar como integrar o Facebook com a Playfab na Unity para criar um ranking online multiplataforma e estimular a competitividade entre seus jogadores.

Antes de você começar, devo dizer o seguinte: este é um daqueles artigos que você coloca nos favoritos e estuda nos mínimos detalhes, para garantir que vai aprender o máximo possível.

Então pegue um café e delicie-se com esse artigo magnífico do Leonardo Thurler.

Com vocês, Leonardo Thurler

Olá pessoal,

Ultimamente a maioria dos jogos mobile têm integração com o Facebook e uma espécie de ranking com as pontuações dos melhores jogadores ou algo desse tipo.

Com isso, vejo muitas pessoas procurando uma forma de colocar esse tipo de comportamento no seu jogo, e nem sempre conseguem encontrar informações ensinando como fazer tal coisa.

Neste artigo eu busco mostrar como você pode integrar o seu jogo com o Facebook e além disso usar esta integração para gerar um ranking online através do site do PlayFab.

A integração com o Facebook utilizada neste artigo funciona nas plataformas Android (4.0.3+) e iOS, w essa limitação vem do próprio SDK oficial do Facebook.

Caso queiram baixar o projeto ou o APK construído neste artigo, seguem os links:

>> Download do Projeto

>> APK (Android 4.0.3+)

PlayFab – O que é e como configurar

O PlayFab é um serviço que oferece servidores online para armazenar dados do seu jogo.

Esses dados podem ser informações do usuário, pontuação dos jogadores, catálogo de itens virtuais, moedas virtuais e outras coisas.

Ele possui uma versão paga e uma versão gratuita, e tudo que vamos utilizar neste tutorial vai ser feito na versão gratuita.

Caso queira saber mais sobre as limitações e benefícios de cada versão, acesse este link.

Sabendo do que se trata o PlayFab, podemos ir ao ponto que interessa, que é criar o nosso jogo dentro do serviço para futuramente colocar essas informações na Unity.

Para utilizar os serviços do PlayFab é preciso que você acesse o site do serviço e se cadastre.  Após efetuarem o cadastro e fazer o login no site, eles já criaram um Studio e um jogo para você e é possível editar tanto os dados do Studio quanto do jogo. Como pode ser visto na imagem abaixo:

unity-playfab-1

Na imagem acima é possível visualizar o campo “Title ID” que fica abaixo do nome do jogo. Esse código será utilizado na Unity para ser possível realizar a integração.

Ao clicar em cima do nome do jogo você é redirecionado para uma página com várias informações sobre o seu jogo, mas vamos direto às duas abas que nos interessam: as abas Settings e Players.

Na aba Settings é preciso configurar o jogo para permitir que o jogador consiga atualizar os dados dele no servidor, isso pode ser feito marcando a opção conforme demonstrado abaixo:

Unity

Ao acessar a aba Players é possível ver que ainda não tem nenhum jogador, porém vamos configurar um Leaderboard, que será o nosso ranking.

Para fazer isso basta acessar a área de player, a aba Leaderboard e clicar no botão “New Leaderboard”.

É preciso definir o “Statistic name” do Leaderboard. Esse campo representa o nome do campo que terá os valores da pontuação do jogador. Vamos criá-lo com o nome de Score.

O outro campo é autoexplicativo e serve para resetar os valores do ranking de forma automática de acordo com o tempo. Após configurar o Leaderboard vocês devem ter uma tela como a imagem abaixo:

unity-playfab-3

Agora que temos tudo configurado no PlayFab, vamos ao Facebook criar e configurar o nosso jogo para futuramente utilizá-lo na Unity.

Facebook – Para desenvolvedores

Para utilizar os serviços do Facebook no seu jogo, você precisa de uma conta de desenvolvedor na rede social. Para fazer isto basta acessar esta página e se registrar.

Ao se registrar e logar você deve selecionar a plataforma do seu jogo, nesse caso vamos escolher a opção Android e clicar em “Skip and Create App ID”.

Após clicar nessa opção, é necessário digitar o “Display Name” que é o nome do jogo e selecionar a categoria do seu jogo conforme indicado na imagem abaixo:

unity-playfab-4

Após criar o aplicativo, será apresentada uma tela com várias informações sobre seu aplicativo uma informação importante é o App Id que será utilizado pela Unity para realizar a integração.

Nesse momento, o seu aplicativo tem acesso às funcionalidades padrão como acessar os dados públicos do usuário e acessar a sua lista de amigos que estão utilizando o jogo.

Agora nós vamos ao projeto na Unity, porém iremos voltar ao Facebook mais tarde para configurar alguns dados do nosso projeto na Unity.

Unity – Utilizando os SDK do Facebook e PlayFab

Agora que temos o nosso jogo configurado no PlayFab e parcialmente configurado no Facebook, vamos ao projeto na Unity.

O nosso projeto irá utilizar o SDK do Facebook e o SDK do PlayFab para facilitar a integração, esses SDKs podem ser encontrados nos seguintes links:  PlayFab e Facebook Developers.

Após baixar os SDKs, basta importá-los para o projeto. Isso pode ser feito dando um duplo clique nos arquivos com a extensão “.unitypackage” com o projeto aberto na Unity. Após importar os SDK o seu projeto deve ficar assim:

unity-playfab-5

É possível visualizar que na parte superior da tela apareceu tanto um menu chamado “PlayFab” quanto um menu chamado “Facebook”. Ao clicar no menu Facebook e em Edit Settings, serão apresentados os campos para configurar o nosso aplicativo no projeto, conforme visto abaixo:

unity-playfab-61

O “App Name” é o nome do seu aplicativo, o “App Id” é o Id que foi gerado lá no Facebook. Para configurar um projeto Android no Facebook temos que usar os dados da seção “Android Build Facebook Setting” (Em alguns computadores o campo “Debug Android Key Hash” não é apresentado, mas existem diversos tutorias sobre como resolver esse problema como o deste link, caso isso aconteça e esse tutorial não resolva, dê uma procurada no Google).

Com isso vamos voltar ao site do Facebook e terminar de configurar o nosso aplicativo. Ao acessar a página do nosso aplicativo no Facebook vamos na aba Settings e clicamos e “Add Platform” e selecionamos a plataforma Android. Após fazer isso precisamos inserir os dados que são encontrados na tela da Unity além de um e-mail para contato, conforme pode ser visto na imagem abaixo:

unity-playfab-7

Após configurar a plataforma Android vamos na aba “App Review” para ativar o nosso aplicativo para o público. Caso você não ative o aplicativo para o público apenas você e os usuários configurados no seu aplicativo como testadores ou desenvolvedores poderão utilizá-lo.

unity-playfab-8

Agora com tudo configurado, vamos voltar na Unity e construir a cena para realizar a integração. Primeiro, iremos criar uma classe estática que servirá para guardar os dados do usuário no jogo. Segue abaixo o script da classe criada:

using UnityEngine;
using System.Collections;

public static class FacebookAndPlayFabInfo
{
    //Id do usuário no PlayFab
    public static string userPlayFabId = "";
    //Id do usuário no Facebook
    public static string userFacebookId = "";
    //Nome do usuário no Facebook
    public static string userName = "";
    //Indica se o usuário já está logado no PlayFab
    public static bool isLoggedOnPlayFab = false;
    //Indica se os dados do leaderboard já foram carregados.
    public static bool leaderboardLoaded = false;
    //Indica se os dados do leaderboard estão sendo carregados.
    public static bool leaderboardIsLoading = false;
}

Para realizar as funções de se logar com o Facebook e o PlayFab vamos criar outro script. Mas antes precisamos entender o que é um método que funciona em uma chamada assíncrona.

Quando tentamos realizar alguma ação que envolva internet, não podemos parar toda a execução do jogo até que os dados da internet sejam retornados para o nosso jogo.

Então, para que seja possível fazer essas conexões com a internet sem que o jogo trave, o SDK do Facebook e do PlayFab funcionam com funções que são executadas em paralelo à execução do jogo, então ao mesmo tempo que o jogo está rodando tem outro processo tentando se conectar com a internet e esperando o resultado dessa conexão, isso seria uma chamada assíncrona.

E quando essa chamada termina eles ativam uma função de Callback informando o resultado do processamento. Isso será mais fácil de visualizar no código do script que vamos criar, segue o código abaixo. 🙂

using UnityEngine;
using System.Collections;
using Facebook.Unity;
using UnityEngine.UI;
using System.Collections.Generic;
using PlayFab;
using PlayFab.ClientModels;
using Facebook.MiniJSON;
using System;

public class FacebookAndPlayFabFunctions : MonoBehaviour
{
    //Title Id do seu jogo no site do PlayFab
    public string gameTitleId = "";
    
    void Start()
    {
        //Usado para inicializar o sdk do facebook.
        FB.Init(InitCallback, null, null);
        //Usado para indicar ao sdk do PlayFab o Id do seu jogo.
        PlayFabSettings.TitleId = gameTitleId;
    }

    private void InitCallback()
    {
        //Verifica se foi possível inicializar o sdk do facebook.
        if (FB.IsInitialized)
        {
            //Ativa o sdk do facebook no jogo.
            FB.ActivateApp();
        }
    }

    //Usado para realizar o login no facebook e no playfab ao mesmo tempo.
    public void Login()
    {
        // Usado para verificar se o usuário já está logado, caso não esteja ele tenta logar.
        if (!FB.IsLoggedIn)
        {
            //Cria a lista de permissões que o aplicativo utilizará, essas são as permissões padrão.
            List<string> permissions = new List<string>() { "public_profile", "email", "user_friends" };

            //Utiliza o SDK do Facebook para realizar o login, utilizando as permissões e indicando a função de callback.
            FB.LogInWithReadPermissions(permissions, LoginFacebookCallBack );
        }
    }

    private void LoginFacebookCallBack( ILoginResult loginResult)
    {
        //Caso o resultado seja nulo, deu algum erro no login.
        if (loginResult == null)
        {
            Debug.Log("Não foi possível logar no facebook.");
            return;
        }

        //Verifica se o retorno não foi um erro, ou algum tipo de cancelamento caso não seja nenhum desses tipos indica
        //que foi possível realizar o login com o facebook com sucesso.
        if (string.IsNullOrEmpty(loginResult.Error) && !loginResult.Cancelled && !string.IsNullOrEmpty(loginResult.RawResult))
        {
            Debug.Log("Sucesso ao Logar no Facebook.");

            //Aqui verificamos se o usuário já está logado no PlayFab e caso não esteja tenta realizar o login.
            if (!FacebookAndPlayFabInfo.isLoggedOnPlayFab)
            {
                //O PlayFab possuí vários tipos de login, neste artigo vamos utilizar o Login com o facebook
                //então nessa parte configuramos uma chamada para o PlayFab se Logar através dos dados do usuário
                //no facebook.
                LoginWithFacebookRequest loginFacebookRequest = new LoginWithFacebookRequest()
                {
                    //Indica o TitleId do seu jogo no PlayFab.
                    TitleId = PlayFabSettings.TitleId,
                    //Indica o token de acesso do usuário no Facebook, esse token só é gerado se o usuário já estiver
                    //logado no facebook
                    AccessToken = Facebook.Unity.AccessToken.CurrentAccessToken.TokenString,
                    //Indica para criar uma conta automaticamente dentro do seu jogo no PlayFab para este usuário, 
                    //caso ele já não possua uma
                    CreateAccount = true
                };

                //Utiliza o SDK do PlayFab para realizar o login, utilizando a chamada e indicando as funções de callback
                //de sucesso e de error.
                PlayFabClientAPI.LoginWithFacebook(loginFacebookRequest, PlayFabLoginSucessCallBack, PlayFabErrorCallBack);
            }
        }
        else
            Debug.Log("Não foi possível logar no facebook.");
    }

    private void PlayFabLoginSucessCallBack( PlayFab.ClientModels.LoginResult playfabLoginResult )
    {
        Debug.Log("Sucesso ao Logar no PlayFab.");

        //Armazena o Id do PlayFab na classe estática e com isso é possível utilizar esses dados em outros scripts.
        FacebookAndPlayFabInfo.userPlayFabId = playfabLoginResult.PlayFabId;

         //Utiliza o SDK do Facebook para consultar os dados, indicando a função de callback. O valor "/me" indica
        //que estou buscando os dados do usuário que está logado. O valor HttpMethod.GET indica que a nossa chamada ao
        //facebook tem a intenção de somente coletar dados.
        FB.API("/me", HttpMethod.GET, CollectLoggedUserInfoCallback);
    }

     private void CollectLoggedUserInfoCallback(IGraphResult result)
    {
        //Caso o resultado seja nulo, deu algum erro ao coletar os dados.
        if (result == null)
        {
            Debug.Log("Não foi possível coletar os dados do usuário no Facebook.");
            return;
        }

        //Verifica se o retorno não foi um erro, ou algum tipo de cancelamento caso não seja nenhum desses tipos indica
        //que foi possível coletar os dados do facebook com sucesso.
        if (string.IsNullOrEmpty(result.Error) && !result.Cancelled && !string.IsNullOrEmpty(result.RawResult))
        {
            Debug.Log("Sucesso ao coletar os dados da conta do usuário no Facebook");

            try
            {
                //A resposta do Facebook vem em formato de Json e com isso nós convertemos o Json para um Dictionary
                //para ser mais facil de coletar os dados
                Dictionary<string, object> dict = Json.Deserialize(result.RawResult) as Dictionary<string, object>;
                string userFacebookName = dict["name"] as string;
                string userFacebookId = dict["id"] as string;

                //Exibe o Json de resposta no console da Unity
                Debug.Log(dict.ToJson());

                //Chamada usada para atualizar o nome do Usuario no playFab com o id do Facebook. Isto irá permitir 
                //que futuramente seja possível coletar as informações desse usuário ao exibir o resultado do Leaderboard.
                //Neste ponto foi utilizado o Id do Facebook ao invés do Nome do usuário no Facebook porque o campo
                //Display Name no PlayFab deve ser único e não passar de 25 caracters. Sendo assim o Id do facebook
                //nos atende muito bem pois ele é um id único por usuário e não ultrapassa esse limite.
                UpdateUserTitleDisplayNameRequest request = new UpdateUserTitleDisplayNameRequest();
                request.DisplayName = userFacebookId;

                PlayFabClientAPI.UpdateUserTitleDisplayName(request, UpdateUserTitleDisplayNameSucessCallback, PlayFabErrorCallBack);

                //Atualiza as informações da classe estática indicando que o usuário está logado no PlayFab
                //e informando o Id do facebook e o nome do usuário. Com isso é possível utilizar esses dados em outros scripts.
                FacebookAndPlayFabInfo.isLoggedOnPlayFab = true;
                FacebookAndPlayFabInfo.userFacebookId = userFacebookId;
                FacebookAndPlayFabInfo.userName = userFacebookName;          
            }
            //Usado caso o Facebook não tenha retornado o id ou o nome do usuário.
            catch (KeyNotFoundException e)
            {
                Debug.Log("Não foi possível coletar os dados do usuário no Facebook. Erro: " + e.Message);
            }
        }
        else
            Debug.Log("Não foi possível coletar os dados do usuário no Facebook.");
    }

    private void UpdateUserTitleDisplayNameSucessCallback(UpdateUserTitleDisplayNameResult result)
    {
        //Exibe no console da Unity que atualizou o campo com sucesso.
        Debug.Log("O campo Display Name do usuário no PlayFab foi atualizado com sucesso.");
    }

    private void PlayFabErrorCallBack( PlayFabError playfabError)
    {
        //Exibe no console da Unity as informações do erro.
        Debug.Log(playfabError.ErrorMessage);
        Debug.Log(playfabError.ErrorDetails);
    }
}

Agora, vamos adicionar um objeto com o nosso script na cena da Unity e criar um botão que irá executar a função de Login do nosso script. Como pode ser observado nas imagens abaixo:

unity-playfab-9

Repare que foi adicionado um objeto com o script que criamos e o TitleId do meu jogo no PlayFab foi preenchido através do Editor da Unity.

unity + playfab

Nesta imagem, foi adicionado um botão na cena através do comando clique com o botão direto do mouse na “Hierarchy” e depois selecionar UI e Button.

Após isso eu mudei a imagem e o texto do botão, mas o ponto importante é a parte do “On Click”, que pode ser vista na imagem acima, que está indicando que deve ser chamado o método de Login do objeto que possui o script que criamos.

Agora quando você inicia o jogo e clica no botão, aparece uma mensagem parecida com esta aqui:

unity-playfab-11

Não se preocupe, você está no caminho certo. Isso acontece porque o SDK do Facebook não dá suporte ao editor da Unity, porém é possível testar os comportamentos de sucesso, de cancelar e de error através dos botões que são apresentados.

Para testar o sucesso temos que clicar no botão “Find Access Token” com isso irá apresentar uma tela similar a esta:

unity-playfab-12

Vale ressaltar que para aparecer esta tela você precisa estar logado com o usuário que criou o aplicativo no Facebook. Caso o User Token não esteja sendo apresentado você precisa clicar no link que está à frente dele. Agora você precisa copiar o conteúdo desse User Token e colar dentro da caixa de texto da mensagem na Unity e depois clicar no botão de sucesso. Como pode ser visto abaixo:

unity-playfab-13

Após clicar no botão “Send Sucess” deve ser apresentado no console as informações de sucesso:

unity-playfab-14

Agora se formos na aba Players do nosso jogo no site do PlayFab podemos observar que foi criado um jogador lá.

unity-playfab-15

O nome fica preenchido com o ID do Facebook do usuário, como atualizamos via código. Com isso, temos nosso Login com o Facebook e com o PlayFab funcionando corretamente.

Agora vamos criar uma nova função que serve para armazenar e atualizar o Score do jogador no PlayFab. Essa função deve ser adicionada no Script “FacebookAndPlayFabFunctions”.

public void UpdateScore(int score)
    {
        //Verifica se o usuário está logado no PlayFab, pois só é possível alterar o score caso ele esteja logado.
        if( FacebookAndPlayFabInfo.isLoggedOnPlayFab )
        {
            //Usado para passar o valor para o PlayFab. O nome do campo Score deve ser identico ao usado no Leadeboard
            //no site do PlayFab. Caso quisesssem armazenar o nome do jogador poderiam criar um Dictionary<string, string>
            Dictionary<string, int> stats = new Dictionary<string, int>();
            //Ao adicionar o valor para o servidor sempre é preciso definir uma chave ( nesse caso "Score") para identificar
            //o que é o dado que você está passando e o outro parâmetro é o valor.
            stats.Add("Score", score);

            //Configura a chamada para atualizar o score no servidor.
            PlayFab.ClientModels.UpdateUserStatisticsRequest request = new PlayFab.ClientModels.UpdateUserStatisticsRequest();
            request.UserStatistics = stats;

            //Utiliza o SDK do PlayFab para atualizar os dados. Informando a chamada e a função de callback de sucesso e erro.
            PlayFabClientAPI.UpdateUserStatistics(request, UpdateUserStatisticsSucessCallback, PlayFabErrorCallBack );
        }
        else
        {
            Debug.Log("Não é possível alterar o Score sem estar logado.");
        }
    }

    private void UpdateUserStatisticsSucessCallback( UpdateUserStatisticsResult updateUserStatisticsResult )
    {
        //Exibe no console da Unity que o dado foi alterado no PlayFab com sucesso.
        Debug.Log("Sucesso ao inserir/atualizar o Score do jogador no PlayFab.");
    }

E então vamos criar um novo botão na cena e colocar para chamar a função UpdateScore ao clicar nele.

unity-playfab-16

Ao executar o jogo e se logar no Facebook e clicar no botão “Inserir Score do Jogador” é possível visualizar as mensagens de sucesso no console da Unity. E ao entrar no site do PlayFab e visualizar os detalhes do Leaderboard que criamos, podemos ver que o Score que adicionamos para o jogador já está lá.

Unity + Playfab

Bem, agora estamos na reta final de construção do nosso Leaderboard do Jogo. Já sabemos como fazer para Logar no Facebook e no PlayFab ao mesmo tempo, como coletar as informações de um usuário através do Facebook e como adicionar valores para o score do jogador. Agora, vamos ver como podemos carregar os dados do Leaderboard do PlayFab e exibir no nosso Jogo.

Para fazer isso vamos criar na cena os objetos de texto que serão atualizados com o nome e a pontuação dos jogadores.

Eu criei 5 espaços para mostrar o ranking dos jogadores. Preste atenção na hierarquia dos objetos e os seus nomes, pois isso será utilizado no script para localizar os objetos e atualizar os dados.

unity-playfab-18

Agora que terminamos de criar os objetos que receberão as informações do nosso Leaderboard, vamos voltar ao Script “FacebookAndPlayFabFunctions” e adicionar as seguintes funções.

public void LoadLeaderBoard()
    {
        //Verifica se o usuário está logado pois só é possível carregar os dados do Leadeboard caso ele esteja logado.
        if( FacebookAndPlayFabInfo.isLoggedOnPlayFab )
        {
            //Configura a chamada para carregar os dados do Leaderboard. Informa qual é a o nome do Leaderboard e quantos
            //resultados deve trazer no máximo.
            PlayFab.ClientModels.GetLeaderboardRequest request = new PlayFab.ClientModels.GetLeaderboardRequest();
            request.MaxResultsCount = 5;
            request.StatisticName = "Score";

            //Atualiza a váriavel para falso indicando que os dados ainda não foram carregados.
            FacebookAndPlayFabInfo.leaderboardLoaded = false;
            //Atualiza a váriavel para verdadeiro indicando que os dados estão sendo carregados.
            FacebookAndPlayFabInfo.leaderboardIsLoading = true;

            //As variáveis acima podem ser usadas em outros scripts que precisem esperar até os dados serem carregados ou 
            //identificar quando começou a carregar para realizar alguma ação dentro do seu jogo.

            //Utiliza o SDK do PlayFab para coletar os dados. Informando a chamada e a função de callback de sucesso e erro.
            PlayFabClientAPI.GetLeaderboard(request, GetLeaderboardSucessCallback, PlayFabErrorCallBack);
        }
        else
        {
            Debug.Log("Não é possível carregar os Dados do Leadeboard sem está logado.");
        }
    }

    private void GetLeaderboardSucessCallback(PlayFab.ClientModels.GetLeaderboardResult result)
    {
        //Verifica se o resultado não veio nulo.
        if( result != null && result.Leaderboard != null )
        {
            //Pega o objeto que representa o Leaderboard.
            GameObject leaderboardGameObject = GameObject.Find("Leadeboard");

            //Percorre cada uma das 5 linhas que podem vir no Leaderboard e atualiza os campos na cena da Unity
            foreach (PlayFab.ClientModels.PlayerLeaderboardEntry leadeboardLine in result.Leaderboard)
            {
                GetUserInfoAndUpdateLeaderboard(leadeboardLine, leaderboardGameObject, result);  
            }
        }
    }

    private void GetUserInfoAndUpdateLeaderboard( PlayFab.ClientModels.PlayerLeaderboardEntry leaderBoardLine, GameObject leaderboardGameObject, GetLeaderboardResult result )
    {
        //Coleta o id do Facebook do usuário que está no rank através do Display Name que atualizamos ao usuário efetuar o login.
        string userFacebookId = leaderBoardLine.DisplayName;

        //Utiliza o SDK do Facebook para coletar as informações do usuário. O valor "/" + userFacebookId serve
        //para indicar de qual usuário queremos os dados. O valor HttpMethod.GET indica que a nossa chamada ao
        //facebook tem a intenção de somente coletar dados.
        FB.API("/" + userFacebookId, HttpMethod.GET,
        //Esta é uma outra forma de criar uma função de callback, o userInfoResult é a váriavel que
        //recebe o resultado que é passado para a função de callback
        (userInfoResult) =>
        {
            //Caso o resultado seja nulo, deu algum erro ao coletar os dados.
            if (userInfoResult == null)
            {
                Debug.Log("Não foi possível coletar os dados do usuário no Facebook.");

                //Verifica se está no ultimo registro do Leadeboard. Para indicar que finalizou o carregamento.
                if (leaderBoardLine.Position + 1 == result.Leaderboard.Count)
                {
                    //Atualiza a váriavel para verdadeiro indicando que os dados ainda já foram carregados.
                    FacebookAndPlayFabInfo.leaderboardLoaded = true;
                    //Atualiza a váriavel para falso indicando que os dados estão já foram carregados.
                    FacebookAndPlayFabInfo.leaderboardIsLoading = false;

                   Debug.Log("Os dados do Leaderboard foram carregados.");
                }

                return;
            }

            //Verifica se o retorno não foi um erro, ou algum tipo de cancelamento caso não seja nenhum desses tipos indica
            //que foi possível coletar os dados do facebook com sucesso.
            if (string.IsNullOrEmpty(userInfoResult.Error) && !userInfoResult.Cancelled && !string.IsNullOrEmpty(userInfoResult.RawResult))
            {
                Debug.Log("Sucesso ao coletar os dados da conta do usuário no Facebook");

                try
                {
                    //A resposta do Facebook vem em formato de Json e com isso nós convertemos o Json para um Dictionary
                    //para ser mais facil de coletar os dados
                    Dictionary<string, object> dict = Json.Deserialize(userInfoResult.RawResult) as Dictionary<string, object>;
                    string userFacebookName = dict["name"] as string;

                    //Pega o objeto que possui as informações de um jogador no Leaderboard.
                    GameObject playerLeadeboardGameObject = leaderboardGameObject.transform.FindChild("Player (" + (leaderBoardLine.Position + 1) + ")").gameObject;

                    //Atualiza o texto com a posiçao do jogador no Leaderboard.
                    playerLeadeboardGameObject.transform.FindChild("Position").GetComponent<Text>().text = (leaderBoardLine.Position + 1).ToString();

                    //Atualiza o texto com o nome do jogador no Facebook.
                    playerLeadeboardGameObject.transform.FindChild("Name").GetComponent<Text>().text = userFacebookName;

                    //Atualiza o texto com o valor do Score do jogador no Leaderboard.
                    playerLeadeboardGameObject.transform.FindChild("Score").GetComponent<Text>().text = leaderBoardLine.StatValue.ToString();

                    //Verifica se está no ultimo registro do Leadeboard. Para indicar que finalizou o carregamento.
                    if (leaderBoardLine.Position + 1 == result.Leaderboard.Count)
                    {
                        //Atualiza a váriavel para verdadeiro indicando que os dados ainda já foram carregados.
                        FacebookAndPlayFabInfo.leaderboardLoaded = true;
                        //Atualiza a váriavel para falso indicando que os dados estão já foram carregados.
                        FacebookAndPlayFabInfo.leaderboardIsLoading = false;

                       Debug.Log("Os dados do Leaderboard foram carregados.");
                    }
                }
                //Usado caso o Facebook não tenha retornado o id ou o nome do usuário.
                catch (KeyNotFoundException e)
                {
                    //Verifica se está no ultimo registro do Leadeboard. Para indicar que finalizou o carregamento.
                    if (leaderBoardLine.Position + 1 == result.Leaderboard.Count)
                    {
                        //Atualiza a váriavel para verdadeiro indicando que os dados ainda já foram carregados.
                        FacebookAndPlayFabInfo.leaderboardLoaded = true;
                        //Atualiza a váriavel para falso indicando que os dados estão já foram carregados.
                        FacebookAndPlayFabInfo.leaderboardIsLoading = false;

                       Debug.Log("Os dados do Leaderboard foram carregados.");
                    }

                    Debug.Log("Não foi possível coletar os dados do usuário no Facebook. Erro: " + e.Message);
                }
            }
            else
            {
                //Verifica se está no ultimo registro do Leadeboard. Para indicar que finalizou o carregamento.
                if (leaderBoardLine.Position + 1 == result.Leaderboard.Count)
                {
                    //Atualiza a váriavel para verdadeiro indicando que os dados ainda já foram carregados.
                    FacebookAndPlayFabInfo.leaderboardLoaded = true;
                    //Atualiza a váriavel para falso indicando que os dados estão já foram carregados.
                    FacebookAndPlayFabInfo.leaderboardIsLoading = false;

                   Debug.Log("Os dados do Leaderboard foram carregados.");
                }

                Debug.Log("Não foi possível coletar os dados do usuário no Facebook.");
            }
        });
    }

Agora vamos adicionar outro botão na cena da Unity e colocar a para chamar a função “LoadLeaderBoard” ao clicar nele e com isso carregar os dados do Leaderboard.

unity-playfab-19

Ao executar o jogo, conectar com o Facebook e apertar o botão de carregar dados do Leaderboard é possível visualizar um resultado semelhante a imagem abaixo:

unity-playfab-20

Eu usei dois usuários para efetuar os testes no jogo, por isso foram retornados dois rankings na imagem acima. Agora vamos criar uma função para compartilhar dados no Facebook. Vamos voltar ao Script “FacebookAndPlayFabFunctions” e adicionar a seguinte função.

public void ShareWithFacebook()
    {
        //Verifica se o usuário está logado pois só é possível compartilhar com o facebook caso ele esteja logado.
        if (FacebookAndPlayFabInfo.isLoggedOnPlayFab)
            FB.ShareLink(new Uri("http://www.leonardothurler.com"), "Título do Compartilhamento", "Conteúdo do Compartilhamento", new Uri("http://i.imgur.com/j4M7vCO.jpg"), null);
        else
            Debug.Log("Não é possível compartilhar com o Facebook sem está logado.");
    }

Agora temos que adicionar um outro botão na cena do facebook e colocar para chamar a função “ShareWithFacebook” no clique desse novo botão.

unity-playfab-21

Ao rodar o jogo, logar no Facebook e clicar no botão de compartilhar com Facebook é apresentado um erro, isto ocorre porque o SDK do Facebook não permite testar esse comportamento de compartilhar dados através do editor da Unity. Para testar este comportamento temos que gerar um Build do jogo no Android ou no IOS e testar em algum dispositivo.

Build no Android – Resolvendo possíveis erros

Bem, pessoal, chegamos a reta final do artigo. Nesta parte vou explicar como resolver os erros que ocorrem ao tentar gerar o build para Android.

O primeiro erro ocorre caso não seja alterado o Bundle Identifier ou a versão mínima de suporte do Android, como o SDK do Facebook só funciona na versão 4.0.3+ do Android é preciso indicar isto na Unity. Para fazer isto, basta clicar em File, depois em Build Settings, selecionar a plataforma Android e selecionar Player Settings.

Assim a aba inspector da Unity apresentará as informações do Build do Android e será preciso configurar os campos mencionados como pode ser visto na imagem abaixo:

unity-playfab-22

Após configurar esses campos e tentar realizar o build novamente será apresentado um erro que é causado ao usar o plugin do PlayFab e do Facebook ao mesmo tempo. Para solucionar este erro basta acessar a pasta Plugins/Android e remover o arquivo “support-v4” ou “support-v4.jar”.

Como pode ser visto na imagem acima o meu projeto já não possui mais este arquivo.

Esse arquivo deve ser removido pois o plugin do Facebook já possui ele e o erro que ocorria era causado pela duplicidade desses arquivos. Agora ao executar o build ele será finalizado corretamente.

Testes no dispositivo Android

As imagens abaixo representam as telas de teste em um dispositivo Android.

unity-playfab-23
unity-playfab-25
unity-playfab-24

A primeira imagem representa quando uso a função de logar com o Facebook, a segunda mostra o teste de publicar o score e consultar o Leaderboard e a terceira imagem é o resultado ao utilizar a função de compartilhar com o Facebook.

Um erro que pode acontecer com algumas pessoas é ao testar o jogo no dispositivo Android o Key Hash configurado no seu aplicativo do Facebook ser diferente do que está sendo usado e apresentado na Unity.

Caso esse erro aconteça será apresentada uma tela com uma mensagem semelhante à imagem abaixo, e para resolver o problema basta seguir o que está escrito na imagem.

unity-playfab-26

Conclusão

Acredito que este artigo possa ajudar a vocês tanto a conhecerem o PlayFab e o Facebook para desenvolvedores.

Além disso espero que vocês tenham aprendido a configuração básica que os seus aplicativos precisam ter nos dois sites para funcionar corretamente, e espero que a utilização dos SDK do PlayFab e do Facebook tenha sido realizada de uma forma clara para que vocês possam entender como funcionam os SDK, como construir funções de Callback em chamadas de funções assíncronas e com isso utilizar eles nos seus projetos.

Alguns desenvolvedores podem notar que teve repetição de códigos e que não separei as funções em muitas classes e nem utilizei um padrão de projeto, fiz dessa forma para facilitar o entendimento das pessoas que são mais leigas na área de programação e acredito que essa forma seja mais didática.

Caso queiram conhecer outras funções que existem no SDK do PlayFab e do Facebook aconselho a olharem nas páginas da PlayFab e Facebook Developers.

Espero que este artigo tenha sido útil e que tenham gostado da leitura. Um abraço e até o próximo artigo!

Comentários finais (por Raphael Dias)

E aí, o que achou do artigo do Leonardo sobre como criar um ranking online na Unity?

Se você quiser saber mais sobre Unity, veja o artigo que produzi sobre desenvolvimento de jogos na Unity e também no texto do Rogério Ranieri sobre como criar um leaderboard em C#.

Agora, eu quero te deixar uma dica

Você quer saber como criar jogos com potencial de vender milhares de cópias e que podem ser desenvolvidos por uma pessoa sozinha ou uma pequena equipe?

Eu preparei um vídeo de 30 minutos explicando como eu faço isso no meu estúdio de games. Acesse essa página para conferir: https://pdj.blog.br/aula-criar-jogos.

Opa,

qual foi a maior sacada que você teve? Conte nos comentários.