Skip to main content

Login

The first section of this tutorial is to create a login screen for the user to sign into their Genies account.

Setup the Scene

The first step is to create a scene for the player to move around in and have a camera following it.

Open Unity Project

Follow the Getting Started tutorial for directions on how to create a Unity project with the Genies Avatar SDK installed.

Open a New Scene

In the Project window, find a folder named Scenes and double click the SampleScene asset to open it.

Sample Scene

tip

This is scene is included by default when creating a new Unity project. If for some reason your Unity project does not have this folder or asset, then create a new folder named Scenes and create a new scene named SampleScene.

Add the Ground Plane

Create a ground object using the Create > 3D Object > Plane option in the Hierarchy window.

Ground Plane

Add a Free Look Camera

Create a camera using the Create > Cinemachine > Targeted Cameras > FreeLook Camera option in the Hierarchy window. Make sure to disable it in the Inspector window.

Free Look

info

A FreeLook Camera is useful tool from the Cinemachine package for creating third person cameras that follow the player.

Create a Login UI

The next step is to create a login screen UI for the user to login to their Genies account.

Open the Simulator Window

Click the top-left dropdown menu in the Game window and select Simulator. Then select a mobile device.

Simulator Window

Create a UI Canvas

In the Hierarchy window, select the Create > UI > Canvas option and name it Login Canvas. In the Inspector window, set the UI Scale Mode property to Scale With Screen Size and set the Reference Resolution to X: 1080 and Y: 1920.

Login Canvas

Create UI

Add the following UI elements as children to the Login Canvas:

  • (Optional) Panel object for a background
  • Text object named Status Text
  • Button object named Instant Login Button
  • Button object named Logout Button
  • Input Field object named Email Input Field
  • Button object named Submit Email Button
  • Input Field object named OTP Input Field
  • Button object named Submit OTP Button
  • Button object named Resend OTP Button
  • Button object named Signup Button

Login UI

tip

You may need to import the TextMeshPro packages if the text is not appearing. See the Common Issues page for a breakdown.

Create the Login Controller Script

Now the login screen needs logic so it calls the API methods to login the user to their Genies account.

Create a New Script

In the Hierarchy window, select the Login Canvas object. In the Inspector window, click the Add Component button near the bottom and then select the bottom option to New Script. Name the script LoginController.

Create Script

Add Code to the Script

Open the LoginController script.

Initial Code

Start by adding this initial code to create object references for the UI elements:

using UnityEngine;
using Genies.Sdk;
using TMPro;
using UnityEngine.UI;

public class LoginController : MonoBehaviour
{
[Header("UI References")]
[SerializeField] private TMP_Text statusText;
[SerializeField] private Button instantLoginButton;
[SerializeField] private Button logoutButton;
[SerializeField] private TMP_InputField emailInputField;
[SerializeField] private Button submitEmailButton;
[SerializeField] private TMP_InputField otpInputField;
[SerializeField] private Button submitOTPButton;
[SerializeField] private Button resendOTPButton;
[SerializeField] private Button signupButton;
}

On Submit Email Function

Add this function to the LoginController class:

    // Triggered when the user clicks the "Submit Email" button
private async void OnSubmitEmail()
{
string email = emailInputField.text;
statusText.text = $"Email submitted: {email}";
(bool success, string errorMessage) = await AvatarSdk.StartLoginEmailOtpAsync(email);
if (success)
{
statusText.text = "OTP sent successfully. Please check your email.";
}
else
{
statusText.text = "Error sending OTP: " + errorMessage;
}
}
info

This function uses StartLoginEmailOtpAsync to submit the inputted email and start the OTP login process. If it is a valid email, then the user should receive a email with an OTP verification code.

On Resend OTP Function

Add this function to the LoginController class:

    // Triggered when the user clicks the "Resend OTP" button
private async void OnResendOTP()
{
statusText.text = "Resending OTP...";
(bool success, string errorMessage) = await AvatarSdk.ResendEmailCodeAsync();
if (success)
{
statusText.text = "OTP resent successfully. Please check your email.";
}
else
{
statusText.text = "Error resending OTP: " + errorMessage;
}
}
info

This function uses ResendEmailCodeAsync to resend a new OTP to the email that requested the initial OTP. It's good practice to have this functionality in case the first OTP failed to send or the user deleted the message by mistake.

On Submit OTP Function

Add this function to the LoginController class:

    // Triggered when the user clicks the "Submit OTP" button
private async void OnSubmitOTP()
{
string otpCode = otpInputField.text;
statusText.text = $"OTP submitted: {otpCode}";
(bool success, string errorMessage) = await AvatarSdk.SubmitEmailOtpCodeAsync(otpCode);
if (success)
{
statusText.text = "OTP verified successfully. User logged in.";
}
else
{
statusText.text = "Error verifying OTP: " + errorMessage;
}
}
info

This function uses SubmitEmailOtpCodeAsync to submit the inputted OTP verification code. If the code is correct, then it will sign in the user to their Genies account and create authorization credential tokens so that user can instant login the next time.

On Instant Login Function

Add this function to the LoginController class:

    // Triggered when the user clicks the "Instant Login" button
private async void OnInstantLogin()
{
statusText.text = "Attempting instant login...";
var result = await AvatarSdk.TryInstantLoginAsync();
if (result.isLoggedIn)
{
statusText.text = "Instant login successful.";
}
else
{
statusText.text = "Instant login failed.";
}
}
info

This function uses TryInstantLoginAsync to login using stored authorization credential tokens instead of doing the OTP workflow. This will only work if the user has signed in before with the OTP workflow.

On User Login Function

Add this function to the LoginController class:

    // Triggered when the user successfully logs in
private void OnUserLogin()
{
statusText.text = "User logged in.";
this.gameObject.SetActive(false);
}
info

This function deactivates the login UI object to hide it once the user is logged in.

On Logout Function

Add this function to the LoginController class:

    // Triggered when the user clicks the "Logout" button
private async void OnLogout()
{
statusText.text = "Logging out...";
await AvatarSdk.LogOutAsync();
statusText.text = "Logged out.";
}
info

This function uses LogOutAsync to log out the user if they are logged in to their Genies account.

On Signup Function

Add this function to the LoginController class:

    // Triggered when the user clicks the "Sign Up" button
public void OnSignUp()
{
Application.OpenURL(AvatarSdk.UrlGeniesHubSignUp);
}
info

This function uses the UrlGeniesHubSignUp parameter to open the Developer Portal signup website on the user's browser.

Start Function

Add this function to the LoginController class:

    private void Start()
{
statusText.text = "Ready";

// Button listeners
submitEmailButton.onClick.AddListener(OnSubmitEmail);
submitOTPButton.onClick.AddListener(OnSubmitOTP);
logoutButton.onClick.AddListener(OnLogout);
instantLoginButton.onClick.AddListener(OnInstantLogin);
resendOTPButton.onClick.AddListener(OnResendOTP);
signupButton.onClick.AddListener(OnSignUp);

// Event listeners
AvatarSdk.Events.UserLoggedIn += OnUserLogin;
}
info

This function will add listeners to all the button click events and also to the AvatarSdk.Events.UserLoggedIn event which is fired when a user logs in.

On Destroy Function

Add this function to the LoginController class:

    private void OnDestroy()
{
// Remove button listeners
submitEmailButton.onClick.RemoveListener(OnSubmitEmail);
submitOTPButton.onClick.RemoveListener(OnSubmitOTP);
logoutButton.onClick.RemoveListener(OnLogout);
instantLoginButton.onClick.RemoveListener(OnInstantLogin);
resendOTPButton.onClick.RemoveListener(OnResendOTP);
signupButton.onClick.RemoveListener(OnSignUp);

// Clean up event listeners
AvatarSdk.Events.UserLoggedIn -= OnUserLogin;
}
info

This function will remove all button and event listeners when the script is destroyed. It is good coding practice to cleanup event listeners when destroying an object to avoid memory leak.

Add the UI References

Save the code and return to Unity. In the Hierarchy window, select the Login Canvas object. Drag and drop all the needed objects from the Hierarchy window into the reference input fields in the Inspector window.

Add References

Test the Code

Enter Play mode. You should be able to login which will hide the login UI.

Test Code