User Login
The Genies Avatar SDK allows developers to let users log into their Genies account.
Login Flow
Anonymous Login
The Genies Avatar SDK also allows developers to give their users the option of anonymous login. That would mean it logs in the user to a guest account so they can still load an Avatar but not need to create or log into a Genies account.
An anonymous login can be overwritten by initiating an OTP Login flow. No logout is necessary to change the logged-in user from an anonymous user to a Genies account user.
OTP Login
The One-Time Passwords (OTP) flow is when a user submits their email and they receive a one-time use code in their email. They then need to verify the code to complete the login.

Login API
Genies Sdk Library
using Genies.Sdk;
The Genies.Sdk library contains methods and events for logging a user into their Genies accounts.
IGenies User Object
IGeniesUser geniesUser;
geniesUser.UserId;
geniesUser.Username;
The IGeniesUser object is returned when getting a reference to the user's Genies account. It contains the user's information such as user ID and username.
Login Events
//Invoked when a user logs in.
AvatarSdk.Events.UserLoggedIn;
//Invoked when a user logs out.
AvatarSdk.Events.UserLoggedOut;
//Invoked when an OTP code request succeeds. Provides the email.
AvatarSdk.Events.LoginEmailOtpCodeRequestSucceeded;
//Invoked when an OTP code request fails. Provides the email and failure reason.
AvatarSdk.Events.LoginEmailOtpCodeRequestFailed;
//Invoked when an OTP code submission succeeds. Provides the submitted code.
AvatarSdk.Events.LoginEmailOtpCodeSubmissionSucceeded;
//Invoked when an OTP code submission fails. Provides the submitted code and failure reason.
AvatarSdk.Events.LoginEmailOtpCodeSubmissionFailed;
//Invoked when an anonymous sign-in fails. Provides the applicationId and failure reason.
AvatarSdk.Events.LoginAnonymousFailed
//Invoked when an anonymous sign-in succeeds. Provides the applicationId used.
AvatarSdk.Events.LoginAnonymousSucceeded
These events are fired when the corresponding login action occurs. They can be subscribed to using listener methods.
Login Booleans
//Gets whether the OTP login flow is awaiting code submission.
AvatarSdk.IsAwaitingEmailOtpCode;
//Gets whether a user is currently logged in.
AvatarSdk.IsLoggedIn;
These booleans will track specific conditions of the login flow.
Url Genies Hub Sign Up String
AvatarSdk.UrlGeniesHubSignUp;
This string is the Developer Portal URL to direct users that need to sign up for a Genies account.
Start Login Anonymous Async Function
AvatarSdk.StartLoginAnonymousAsync();
This function will log in the user to a guest account. Their user Avatar definition will be a default definition and the user data will not be stored persistently.
Is User Signed In Anonymously Function
AvatarSdk.IsUserSignedInAnonymously();
This function checks if the current logged in user is anonymous.
Try Instant Login Async Function
AvatarSdk.TryInstantLoginAsync();
This function will attempt to use a user's cached credentials to instantly login. It will return a tuple indicating success and the username.
If a user logs in, then their credentials will be cached which allows them to instantly login the next session. Logging them out will remove the cached credentials.
Start Login Email OTP Async Function
AvatarSdk.StartLoginEmailOtpAsync(string);
This function will take in a string representing the email and starts the OTP login flow by submitting the email to receive a verification code. It will return a tuple indicating success and an optional failure reason.
Submit Email OTP Code Async Function
AvatarSdk.SubmitEmailOtpCodeAsync(string);
This function will take in a string OTP code and submits the code to complete the OTP login flow. It will return a tuple indicating success and an optional failure reason.
Resend Email Code Async Function
AvatarSdk.ResendEmailCodeAsync();
This function resends the OTP verification code to the email from the current OTP login flow. It will return a tuple indicating success and an optional failure reason.
Log Out Async Function
AvatarSdk.LogOutAsync();
This function logs out the current user.
Get User Name Async Function
AvatarSdk.GetUserNameAsync();
This function gets the username of the currently logged in user.
Get User Id Async Function
AvatarSdk.GetUserIdAsync();
This function gets the user ID of the currently logged in user.
Get Logged In User Async Function
AvatarSdk.GetLoggedInUserAsync();
This function gets the IGeniesUser object of the currently logged in user.
Get User Async Function
AvatarSdk.GetUserAsync(string, string);
This function gets the IGeniesUser object given a user ID and username.
Examples
Anonymous Login Flow
using UnityEngine;
using Genies.Sdk;
public class LoginTest : MonoBehaviour
{
private async void Start()
{
var (succeeded, failReason) = await AvatarSdk.StartLoginAnonymousAsync();
if (succeeded)
{
Debug.Log("User logged in anonymously");
}
else
{
Debug.Log("Failed to login anonymously because: " + failReason);
}
}
}
Simple Login Flow
This example shows the OTP login flow for a user to sign into their Genies account.
using UnityEngine;
using Genies.Sdk;
using TMPro;
using UnityEngine.UI;
public class LoginTest : MonoBehaviour
{
[Header("UI References")]
[SerializeField] private TMP_InputField emailInputField;
[SerializeField] private Button submitEmailButton;
[SerializeField] private TMP_InputField otpInputField;
[SerializeField] private Button submitOTPButton;
[SerializeField] private TMP_Text statusText;
[SerializeField] private Button logoutButton;
[SerializeField] private Button instantLoginButton;
[SerializeField] private Button resendOTPButton;
[SerializeField] private Button signupButton;
private void Start()
{
statusText.text = "Ready";
submitEmailButton.onClick.AddListener(OnSubmitEmail);
submitOTPButton.onClick.AddListener(OnSubmitOTP);
logoutButton.onClick.AddListener(OnLogout);
instantLoginButton.onClick.AddListener(OnInstantLogin);
resendOTPButton.onClick.AddListener(OnResendOTP);
signupButton.onClick.AddListener(OnSignup);
AvatarSdk.Events.UserLoggedIn += OnUserLogin;
}
private void OnDestroy()
{
submitEmailButton.onClick.RemoveListener(OnSubmitEmail);
submitOTPButton.onClick.RemoveListener(OnSubmitOTP);
logoutButton.onClick.RemoveListener(OnLogout);
instantLoginButton.onClick.RemoveListener(OnInstantLogin);
resendOTPButton.onClick.RemoveListener(OnResendOTP);
signupButton.onClick.RemoveListener(OnSignup);
AvatarSdk.Events.UserLoggedIn -= OnUserLogin;
}
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;
}
}
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;
}
}
private void OnUserLogin()
{
statusText.text = "User logged in.";
}
private async void OnInstantLogin()
{
statusText.text = "Attempting instant login...";
var result = await AvatarSdk.TryInstantLoginAsync();
if (result.isLoggedIn)
{
statusText.text = $"Instant Login Succeeded for username: {result.username}";
}
else
{
statusText.text = "Instant Login Failed";
}
}
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;
}
}
private async void OnLogout()
{
statusText.text = "Logging out...";
await AvatarSdk.LogOutAsync();
statusText.text = "Logged out.";
}
private void OnSignup()
{
statusText.text = "Opening signup page...";
Application.OpenURL(AvatarSdk.UrlGeniesHubSignUp);
}
}