Skip to main content

Implement Authentication (in Unity) | Link and Unlink account using PlayerPrefs

In this blog post, we'll delve into the process of implementing authentication in Unity, along with user account linking and unlinking using PlayerPrefs. Let's break down each step, from setting up the UI canvas to managing player data effectively.

Introduction: Understanding Authentication in Unity

Authentication is crucial for creating secure user experiences in Unity projects. By implementing authentication, developers can enable features such as user accounts and personalised settings. In this guide, we'll explore how to integrate authentication into a Unity project using PlayerPrefs, Unity's built-in system for storing player preferences.

Let's start with a playback of the final result.

Fig 1. Authentication in Unity | Playback

Setting Up the UI Canvas: Creating User-Friendly Interfaces

The first step is to create a UI canvas to house our authentication panels. We'll design three main panels: Registration, Login/Authentication, and Linked Account. These panels will guide users through account creation, login, and account management.

Registration Panel: Signing Up New Players
The Registration panel allows new players to create an account by entering a username and password. When users submit their information, a web call with a POST request is made to the backend to create a new player account. (Backend implemented is discussed in one of the previous posts).

➣ Input username and password in respective fields in the panel UI
➣ Click on Register action to trigger a registration call
➣ Make a JSON string out of the input in the format as supported by the backend:
    {"username": username, "password": plain_password}
➣ Send a POST request using UnityWebRequest, passing the JSON string in the request body and with the content-type of "application/json".
➣ Notify progress by changing text of the Register button to "Registering..."
➣ Once the response is back after the return of request.SendWebRequest(), change the text back to notify of a completed progress.
➣ Show appropriate message to the user in the UI about the response. The response text from the call will be stored in, request.downloadHandler.text

🟢 Registration snippet 🟨 C# 🟦 Unity3D
public void RegisterStart() { StartCoroutine(Register()); }

IEnumerator Register() {

  string jsonString =
      "{\"username\":\"" + reg_username.text + "\", \"password\":\"" + reg_password.text + "\"}";
  UnityWebRequest request = UnityWebRequest.Post(
      "https://masters-of-mischief-3.onrender.com/register", jsonString, "application/json");

  regBtnText.text = "Registering ...";
  yield return request.SendWebRequest();
  Debug.Log(request.downloadHandler.text);
  if (request.result != UnityWebRequest.Result.Success) {
    infoReg.text = "Couldn't register. Try again";
    infoReg.color = Color.red;
  } else {
    infoReg.text = "Registration Successful! username: " + reg_username.text;
    infoReg.color = Color.green;
  }
  regBtnText.text = "Register";
  reg_username.text = "";
  reg_password.text = "";
}

Login/Authentication Panel: Accessing Player Accounts
The Login/Authentication panel allows existing players to log in by verifying their credentials with the backend. Upon successful authentication, the player's data is saved in PlayerPrefs, establishing a session and linking the account to the device.

➣ Input username and password in respective fields in the panel UI
➣ Click on Link Account action to trigger a login call
➣ Make a JSON string out of the input in the format as supported by the backend:
    {"username": username, "password": plain_password}
➣ Send a POST request using UnityWebRequest, passing the JSON string in the request body and with the content-type of "application/json".
➣ Notify progress by changing text of the call-to-action button to "Authenticating..."
➣ Once the response is back after the return of request.SendWebRequest(), change the text back to notify of a completed progress.
➣ Show appropriate message to the user in the UI about the response. The response text from the call will be stored in, request.downloadHandler.text
➣ Upon successful authentication, the server responds with json string of the player data.
➣ Store the data in PlayerPrefs, under the key "linked_account".

🟢 Authnetication snippet🟨 C#🟦 Unity3D
public void AuthenticateStart() { StartCoroutine(Authenticate()); }

IEnumerator Authenticate() {

  string jsonString =
      "{\"username\":\"" + log_username.text + "\", \"password\":\"" + log_password.text + "\"}";
  UnityWebRequest request = UnityWebRequest.Post(
      "https://masters-of-mischief-3.onrender.com/authenticate", jsonString, "application/json");

  logBtnText.text = "Authenticating ...";
  yield return request.SendWebRequest();
  if (request.result != UnityWebRequest.Result.Success) {
    infoLog.text = "Couldn't authenticate. Try again";
    infoLog.color = Color.red;
  } else {
    string data = request.downloadHandler.text;
    PlayerPrefs.SetString("linked_account", data);
  }
  logBtnText.text = "Link Account";
  log_username.text = "";
  log_password.text = "";

  CheckAndApplyForLinkedAccount();
}

Linked Account Panel: Managing Account
The third one, that pops up in place of the Authentication panel is a Linked Account panel. The Linked Account panel is displayed when a linked user account is detected in PlayerPrefs. It provides access to account information, including the username. Users can also logout, which deletes the PlayerPrefs key "linked_account".

Fig 2. Linked Account panel in action

Managing Player Data: Storing Data Securely with PlayerPrefs

PlayerPrefs provides a secure solution for storing player preferences, including authentication-related information like usernames. By leveraging PlayerPrefs, developers can ensure that player data is securely stored locally on the device.

Player Data Class: Structuring Player Information
The key "linked_account" stores string of player account data. It is fetched and converted into an object of PlayerDataSer class. The PlayerDataSer class is a model class that stores player data retrieved from PlayerPrefs. It encapsulates player properties for easy retrieval and manipulation within the Unity environment.

🟢 PlayerDataSer class🟨 C#🟦 Unity3D
public class PlayerDataSer {
  public int id;
  public string username;
}

Once an object is created using JSONUtility.FromJSON<Class>(jsonString), the username is displayed in the Linked Account Panel along with an option to Logout.

Handling Account Links and Logout: Ensuring Security and Convenience

Logout functionality is integrated for securely logging out and clearing locally stored account data. Logout is nothing but a simple deletion of the PlayerPrefs key. After login or logout, the system checks for linked accounts in PlayerPrefs. Depending on the presence of a linked account, the Authentication or Linked Account panel is displayed.

🟢 Check For Linked Account🟨 C#🟦 Unity3D
void CheckAndApplyForLinkedAccount() {
  if (PlayerPrefs.HasKey("linked_account")) {
    linkedPanel.SetActive(true);
    PlayerDataSer playerData =
        JsonUtility.FromJson<PlayerDataSer>(PlayerPrefs.GetString("linked_account"));
    linkedText.text = playerData.username;
    loginPanel.SetActive(false);
    return;
  }

  linkedPanel.SetActive(false);
  loginPanel.SetActive(true);
}

Comments

Popular posts from this blog

Creating and Hosting the Game Backend using Node.js in Render

This is the first development blog post in a series  for "Masters of Mischief".  This post specifically is about the development of a backend for our 3D multiplayer game.

How I Set Up GitHub Collaboration and CI/CD with GitHub Actions for our Unity Game Project

Transitioning to GitHub collaboration and CI/CD for "Masters of Mischief" was a game-changer. It all started with the frustration of the old-school ZIP file transfers among developers, waiting for one another to finish their tasks before diving in. That approach was inefficient, to say the least. So, we decided to bid farewell to that headache and revamp our workflow.