GameService y tablas de clasificación en Unity
Tags: unity3d, hmscore, huaweimobileservices, android
Published: 2021-02-24 16:18:40

Introducción:
En este artículo, aprenderemos cómo integrar Game Service y obtener tablas de clasificación en Unity utilizando el plugin Huawei HMS Core App Services.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lmp4gao839n7a066dv8p.jpg)
Requisitos:
Unity IDE
Código visual
Dispositivo HMS

Consideraciones:
Para las bibliotecas de App Gallery Connect y Game Service usaremos una versión específica, verifica si hay una versión más nueva disponible.
Pasos para la integración:
Crea un proyecto de Unity
Abre Unity Hub y crea un proyecto (en nuestro caso, un proyecto 2D). El nombre del proyecto será UnityHmsCore.
En Unity, ve a Windows> Asset Store, busca HMS Core App Services, haga clic en Importar.
![Alt Text](https://huawei-latinoamerica.medium.com/gameservice-y-tablas-de-clasificaci%C3%B3n-en-unity-653a9ff82ec6)

Cambiar plataforma: Haz click en Configuración de compilación, selecciona Android y presiona Cambiar plataforma.
![Alt Text](https://miro.medium.com/max/1478/1*AfcWIy7n1utEJeo7sf5mow.png)

Selecciona Configuración del reproductor> Configuración de publicación> Administrador de almacén de claves y crea un nuevo archivo de almacén de claves de la siguiente manera.
![Alt Text](https://huawei-latinoamerica.medium.com/gameservice-y-tablas-de-clasificaci%C3%B3n-en-unity-653a9ff82ec6)
![Alt Text](https://miro.medium.com/max/1123/1*2gwbokBhPuKMy_HTGSZkLw.png)

Actualiza el nombre del paquete.
En Configuración del proyecto> Configuración de publicación, habilita las siguientes opciones.
![Alt Text](https://miro.medium.com/max/748/1*59BsjBtHshfAUxPU3HX_Dw.png)

En el terminal de la línea de comandos, ejecute el siguiente comando y obtenga la clave SHA:
```
keytool -list -v -keystore D:\yourpath\UnityHmsCore.keystore
```
![Alt Text](https://huawei-latinoamerica.medium.com/gameservice-y-tablas-de-clasificaci%C3%B3n-en-unity-653a9ff82ec6)
Crea y configura el proyecto en AppGallery
Navegue a AGC Console y cree un nuevo proyecto con el mismo nombre que el proyecto de Unity (en este caso, UnityHmsCore).

![Alt Text](https://miro.medium.com/max/1060/1*BOVoXqXZlUYBc40cU9n0qA.png)
Agregar aplicación
![Alt Text](https://huawei-latinoamerica.medium.com/gameservice-y-tablas-de-clasificaci%C3%B3n-en-unity-653a9ff82ec6)

Guarde la clave SHA en la consola AGC.
![Alt Text](https://miro.medium.com/max/1475/1*gmTUxmKuucarHAol6KEuUw.png)

Habilitar el kit de autenticación y el servicio de juegos
![Alt Text](https://huawei-latinoamerica.medium.com/gameservice-y-tablas-de-clasificaci%C3%B3n-en-unity-653a9ff82ec6)

Vaya a Mis aplicaciones y seleccione Operar> Logros
![Alt Text](https://huawei-latinoamerica.medium.com/gameservice-y-tablas-de-clasificaci%C3%B3n-en-unity-653a9ff82ec6)
Pulsa Crear y completa la información
![Alt Text](https://miro.medium.com/max/6000/1*Yi4rs0j1pYo9aQKO64Pvqg.png)
Descargue agconnect-services.json y cópielo en Assets> Plugins> Android en el proyecto de Unity.
En LaucherTemplate agregue el complemento y las dependencias
```
apply   plugin: 'com.huawei.agconnect'
    implementation 'com.huawei.agconnect:agconnect-core:1.4.1.300'           
    implementation 'com.huawei.hms:base:5.0.0.301'
    implementation 'com.huawei.hms:hwid:5.0.3.301'
    implementation 'com.huawei.hms:game:5.0.1.302'
```
En MainTemplate agregue las dependencias:
```
implementation 'com.huawei.agconnect:agconnect-core:1.4.1.300'           
    implementation 'com.huawei.hms:base:5.0.0.301'
    implementation 'com.huawei.hms:hwid:5.0.3.301'
```
En BaseProjectTemplate, agregue esto tanto en los repositorios de buildscript como en todos los repositorios de proyectos y en la ruta de clases de App Gallery Connect.
```
maven { url 'https://developer.huawei.com/repo/' }
classpath 'com.huawei.agconnect:agcp:1.2.1.301'
```
Debe verse así:
```
allprojects {
        buildscript {
            repositories {**ARTIFACTORYREPOSITORY**
                google()
                jcenter()
                maven { url 'https://developer.huawei.com/repo/' }
            }
            dependencies {
                classpath 'com.android.tools.build:gradle:3.4.0'
                classpath 'com.huawei.agconnect:agcp:1.2.1.301'
                **BUILD_SCRIPT_DEPS**
            }
        }
        repositories {**ARTIFACTORYREPOSITORY**
            google()
            jcenter()
            flatDir {
                dirs "${project(':unityLibrary').projectDir}/libs"
            }
            maven { url 'https://developer.huawei.com/repo/' }
        }
}
```
Vaya a Archivo> Configuración de compilación> Player Settings > Player y actualice el nombre de la empresa y el nombre del paquete

![Alt Text](https://miro.medium.com/max/990/1*jLe0yobhTf8_0Ka0_Hh7MQ.png)

Crear GameObjects y codificación
Agregaremos el objeto de juego TEXT, haga clic en GameObject> UI> TEXT y cambiaremos el nombre del objeto creado a InfoTxt (mostraremos información en este texto).
Agregue un input, haga clic en GameObject> UI> Campo de entrada, y cambie el nombre a LeaderboardScoreInputField
Ahora, agregaremos algunos botones, hacemos clic en GameObject> UI> Button, y cambiamos el nombre del objeto creado a GetLeaderboardSwitchStatusBtn.

Repita el último paso 4 veces y cambie el nombre a los siguientes nombres:
SetLeaderboardSwitchStatusBtn
SubmitScoreBtn
GetAllLeaderboardsIntent
GetLeaderboardsDataBtn
Cree un GameObject vacío, haga clic en GameObject> Create Empty y cambie el nombre del objeto a LeaderboardManager.
Ahora en cada botón, debe agregar un método de clic, seleccionar un botón y en el parámetro onClick () presionar + y luego decir Ninguno (Objeto) y seleccionar LeaderboardManager. Después de eso, seleccione el método al que llamará este botón (el nombre del método es similar al nombre del botón).
![Alt Text](https://miro.medium.com/max/1750/1*6ORNUdLOLXZz-E2Hv6m4QA.png)

Repite este proceso con todos los botones.
La escena debe verse así:

![Alt Text](https://miro.medium.com/max/1750/1*UOm8uCgUci6ezz2W4PK6_A.png)

Seleccione LeaderboardManager y arrastre su InfoTxt al campo InfoTxt en su secuencia de comandos (en el panel Inspector). Haz lo mismo LeaderboardScoreInputField
Reemplace LeaderboardID con su ID de la tabla de clasificación de su AppGallery Console.
LeaderboardManager debe tener este aspecto:
![Alt Text](https://miro.medium.com/max/1750/1*aZXtZ-Uz9-AHsxQDqtqBfA.png)
Ahora codifiquemos, creemos el siguiente script:

```
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.HuaweiAppGallery;
using UnityEngine.HuaweiAppGallery.Listener;
using UnityEngine.HuaweiAppGallery.Model;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class LeaderboardService : MonoBehaviour
{
    public Text infoTxt;
    public InputField LeadearboardScoreInputField;
    public string leadearboardID = "4FABF3A54E9E38591EE599CB20B5FFD258C52A04173F6F9D5C3EF3AD5F73B15C";    //replace this ID with the ID that you get from AppGallery Connect console
    private static string leaderboardString = "";
    
    // Start is called before the first frame update
    void Start()
    {
        HuaweiGameService.AppInit();
        onAuth();
    }
    
    public void onAuth()
    {
        try
        {
            infoTxt.text = "starting Init";
            HuaweiGameService.Init();
            infoTxt.text = "starting login";
            HuaweiGameService.SilentSignIn(iLoginListener);
            infoTxt.text = "finshed login";
        }
        catch(Exception ex)
        {
            infoTxt.text = ex.ToString();
        }
    }
// Update is called once per frame
    void Update()
    {
        StartCoroutine(ExampleCoroutine());
    }
IEnumerator ExampleCoroutine()
    {
        //yield on a new YieldInstruction that waits for 5 seconds.
        yield return new WaitForSeconds(3);
infoTxt.text = leaderboardString;
    }
public void onGetLeaderboardSwitchStatusClick()
    {
        HuaweiGameService.GetLeaderboardSwitchStatus(new LeaderboardSwitchStatusListener());
    }
public void onSetLeaderboardSwitchStatusClick()
    {
        HuaweiGameService.SetLeaderboardSwitchStatus(1, new LeaderboardSwitchStatusListener());
    }
public void onSetScoreClick()
    {
        try
        {
            int score = int.Parse(LeadearboardScoreInputField.text);
            HuaweiGameService.AsyncSubmitScore(leadearboardID, score, new SubmitScoreListener());
        }
        catch(Exception ex)
        {
            infoTxt.text = "Integer parse error";
        }
    }
public void onGetAllLeaderboardsIntentClick()
    {
        HuaweiGameService.GetAllLeaderboardsIntent(new GetLeaderboardIntentListener());
    }
public void onGetLeaderboardsDataClick()
    {
        HuaweiGameService.GetLeaderboardsData(true, new GetLeaderboardsListener());
    }
public void onGoBackClick()
    {
        SceneManager.LoadScene("MainScene", LoadSceneMode.Single);
    }
public class LeaderboardSwitchStatusListener : ILeaderboardSwitchStatusListener
    {
        public void OnFailure(int code, string message)
        {
            leaderboardString = "Error code: " + code + ", message: " + message;
        }
public void OnSuccess(int statusValue)
        {
            leaderboardString = "Status value: " + statusValue;
        }
    }
public class SubmitScoreListener : ISubmitScoreListener
    {
        public void OnFailure(int code, string message)
        {
            leaderboardString = "Error code: " + code + ", message: " + message;
        }
public void OnSuccess(ScoreSubmission scoreSubmission)
        {
            leaderboardString = "LeaderboardId: " + scoreSubmission.LeaderboardId + ", PlayerId" + scoreSubmission.PlayerId + ", ScoreResults" + scoreSubmission.ScoreResults;
        }
    }
public class GetLeaderboardIntentListener : IGetLeaderboardIntentListener
    {
        public void OnFailure(int code, string message)
        {
            throw new NotImplementedException();
        }
public void OnSuccess(AndroidJavaObject intent)
        {
            AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
            AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
currentActivity.Call("startActivity", intent);
        }
    }
public class GetLeaderboardsListener : IGetLeaderboardsListener
    {
        public void OnFailure(int code, string message)
        {
            leaderboardString = message;
        }
public void OnSuccess(List<LeaderboardProxy> leaderboards)
        {
            leaderboardString = "";
            foreach (var leaderboard in leaderboards)
            {
                leaderboardString += string.Format("LeaderboardId: {0}, LeaderboardDisplayName: {1} \n\n", leaderboard.LeaderboardId, leaderboard.LeaderboardDisplayName);
            }
        }
    }
}
```

Explicación del código:
Primero, en el método Start () iniciamos los Servicios de juego y autenticamos al usuario
```
void Start()
    {
        HuaweiGameService.AppInit();
        onAuth();
    }
    
    public void onAuth()
    {
        try
        {
            infoTxt.text = "starting Init";
            HuaweiGameService.Init();
            infoTxt.text = "starting login";
            HuaweiGameService.SilentSignIn(iLoginListener);
            infoTxt.text = "finshed login";
        }
        catch(Exception ex)
        {
            infoTxt.text = ex.ToString();
        }
    }
```
En el método Update (), mostramos los valores que obtenemos de Game Services. Considere que la cadena leaderboardString es estática, por lo que podemos actualizar este valor desde los oyentes.
```
// Update is called once per frame
    void Update()
    {
        StartCoroutine(ExampleCoroutine());
    }
IEnumerator ExampleCoroutine()
    {
        //yield on a new YieldInstruction that waits for 5 seconds.
        yield return new WaitForSeconds(3);
infoTxt.text = leaderboardString;
    }
```
En el método onSetLeaderboardSwitchStatusClick, podemos habilitar o deshabilitar las tablas de clasificación para este usuario (1 está habilitado, 0 está deshabilitado).
En el método onGetLeaderboardSwitchStatusClick, podemos obtener si las tablas de clasificación están habilitadas o no.
En el método onSetScoreClick, podemos actualizar nuestra puntuación.
En onGetAllLeaderboardsIntentClick, llamamos a una actividad de intención que muestra la lista de clasificación (pero esta lista se vaciará hasta que el juego se publique en la tienda)
En onGetLeaderboardsDataHaga clic para obtener la lista de tablas de clasificación (sin la necesidad de lanzar el juego).
Resultado (cuando presiona el botón GetLeaderboardsData):
![Alt Text](https://miro.medium.com/max/1750/1*s2tOuCGDsSLYzN_R-xzLlw.png)