Skip to main content

Use the AGS Game SDK to log in - Login with device ID - (Unity module)

Last updated on November 25, 2024

Unwrap the wrapper

In this tutorial, you will learn how to implement device ID logins into your game using the AccelByte Gaming Services (AGS) Game SDK.

Byte Wars uses the AuthEssentialsWrapper class as a wrapper to cache and handle login-related functionalities with the AGS Game SDK. This provides modularity without overriding engine classes.

The AuthEssentialsWrapper class wraps the ApiClient and User class provided by the AGS Game SDK. The User class handles account-related interactions with AGS that provides the ability to authenticate users and obtain access tokens. After a successful authentication, it will allow you to utilize the AGS features as a user.

The diagram below explains how the AuthEssentialsWrapper connects the LoginHandler to use the AGS Game SDK functionalities.

Login with Device ID Flow Unity Byte Wars device ID

In this tutorial, you will learn how to call the Login function in User class from AuthEssentialsWrapper and set up the OnLoginCompleted callback to receive the login response from AGS.

What's in the Starter Pack

The starter class AuthEssentialsWrapper_Starter has been provided for you to modify. It is available in the Resources section.

  • AuthEssentialsWrapper_Starter file: /Assets/Resources/Modules/AuthEssentials/Scripts/AuthEssentialsWrapper_Starter.cs

The AuthEssentialsWrapper_Starter class already contains the AGS Game SDK libraries.

using AccelByte.Api;
using AccelByte.Core;
using AccelByte.Models;

Variables to hold references for the AGS Game SDK have already been defined.

// AGS Game SDK references
private ApiClient apiClient;
private User user;
private UserProfiles userProfiles;
private Lobby lobby;

AuthEssentialsModels is a file that holds any model data used in AuthEssentialsWrapper_Starter. It is available in the Resources section.

  • AuthEssentialsModels file: /Assets/Resources/Modules/AuthEssentials/Scripts/AuthEssentialsModels.cs

The AuthEssentialsModels contains LoginType, an enum that defines the type of login methods.

public enum LoginType
{
DeviceId
...
}

Implement logins using the AGS Game SDK

  1. Open Byte Wars in Unity. Then, open AuthEssentialsWrapper_Starter.cs and add the code below to get the AGS Game SDK's ApiClient, which holds the reference to the User class to access login functions.

    void Awake()
    {
    apiClient = AccelByteSDK.GetClientRegistry().GetApi();
    user = apiClient.GetUser();
    userProfiles = apiClient.GetUserProfiles();
    lobby = apiClient.GetLobby();
    }
  2. Declare a local variable to store the data of the current logged-in user, which can be accessed from another script later.

    public TokenData UserData;
  3. Since the login process is asynchronous, create a callback function called OnLoginCompleted to receive the login response from AGS. To keep it modular, add the AGS Game SDK's Result and ResultCallback as parameters so the ResultCallback method can later proceed with the login result.

    private void OnLoginCompleted(Result<TokenData, OAuthError> result, ResultCallback<TokenData, OAuthError> customCallback = null)
    {
    if (!result.IsError)
    {
    BytewarsLogger.Log($"The user successfully logged in with Device ID: {result.Value.platform_user_id}");

    GameData.CachedPlayerState.playerId = result.Value.user_id;
    UserData = result.Value;

    GetUserProfile();
    CheckLobbyConnection();
    }
    else
    {
    BytewarsLogger.Log($"The user failed to log in with Device ID. Error Message: {result.Error.error}");
    GameData.CachedPlayerState.platformId = string.Empty;
    }

    customCallback?.Invoke(result);
    }
    note

    The callback function above saves the player's user ID in the game data and invokes two functions: GetUserProfile() and CheckLobbyConnection(). These two functions are explained in the next section.

  4. Implement the Login method. Add local variables below to store the required values when calling the Login method.

    private PlatformType platformType;
    private string platformToken;
  5. In our AuthEssentialsWrapper_Starter class, let's add a function named LoginWithDeviceId with a ResultCallback<TokenData, OAuthError> parameter for handling login results. This function will use the LoginWithDeviceId function from the AccelByte SDK's User class to enable logins with device ID.

    public void LoginWithDeviceId(ResultCallback<TokenData, OAuthError> resultCallback)
    {
    BytewarsLogger.Log($"Trying to login with Device ID");
    user.LoginWithDeviceId(result => OnLoginCompleted(result, resultCallback));
    }

User profile and Lobby

In the OnLoginComplete callback implementation from above, there are two functions: GetUserProfile() and CheckLobbyConnection(). Once you have logged in with a device ID, you have the option to use these functions to get the user profile, then check the connection to Lobby.

User profile

One of the actions that can be taken upon logging in is obtaining a user profile. Upon each successful login, token data is generated, which includes the user ID of the player who has logged in. It is recommended that you retrieve the user profile each time the user logs in. This can be accomplished by using a function provided by the AGS Game SDK to retrieve the profile.

To retrieve the user profile, you will use the AGS Game SDK function to get the user profile. The user profile will be used in the friends module that needs a public ID from a player.

private void GetUserProfile()
{
userProfiles.GetUserProfile(result => OnGetUserProfileCompleted(result));
}

OnGetUserProfileCompleted() calls the function to get the user display name.

private void GetUserPublicData(string receivedUserId)
{
user.GetUserByUserId(receivedUserId, OnGetUserPublicDataFinished);
}

Lobby

AGS Lobby ensures a seamless link between your game and its participants via The WebSocket Protocol.

Within the starter file, there is predefined code for your convenience. The function CheckLobbyConnection() verifies the status of the connection to AGS Lobby. This function is also designed to manage incoming notifications from Lobby, covering various states like being connected, disconnected, and in the process of disconnecting. Following the successful events binding, it initiates the lobby.Connect() command.

public void CheckLobbyConnection()
{
if (!lobby.IsConnected)
{
lobby.Connected += OnLobbyConnected;
lobby.Disconnected += OnLobbyDisconnected;
lobby.Disconnecting += OnLobbyDisconnecting;
lobby.Connect();
}
}

Before you quit the game, you must ensure that you properly disconnect from Lobby by using the lobby.Disconnect() method in the OnApplicationQuit() function, which will trigger when a user leaves the game or is stopped by the editor. This step is essential for seamless gameplay and ensuring that all connections are properly closed.

void OnApplicationQuit()
{
lobby.Disconnect();
}

Every time you disconnect from Lobby, the WebSocket will provide a close code to the game client. To address this, the OnLobbyDisconnected() function has been provided, which thoroughly checks the close code and ensures that the user is promptly logged out.

private void OnLobbyDisconnected(WsCloseCode code)
{
BytewarsLogger.Log($"Lobby service disconnected with code: {code}");

HashSet<WsCloseCode> loginDisconnectCodes = new()
{
WsCloseCode.Normal,
WsCloseCode.DisconnectDueToMultipleSessions,
WsCloseCode.DisconnectDueToIAMLoggedOut
};

if (loginDisconnectCodes.Contains(code))
{
lobby.Connected -= OnLobbyConnected;
lobby.Disconnected -= OnLobbyDisconnected;

AuthEssentialsHelper.OnUserLogout?.Invoke();
}
}

Resources