Hello all, I’m new to unity and game making. I have been working on my first project for a long while now learning as I go. My game is near complete and I’m trying to get the unity player accounts authentication to work for my webGL build. Everything works properly in the editor but when I post the game on Github or do a build and run it wont let me authenticate. I get this error ‘Unity.Services.Authentication.PlayerAccounts.IBrowserUtils.Bind’ on type ‘’ failed.
I have tried multiple iterations of my login/authentication script. All packages are updated. I originally started building with Version 2021.3.1f1, which did not work so I have also tried version 6000.0.28f1 with no luck as well.
My coding is ugly to begin with and with the multiple iterations has gotten worse but here is is…
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Unity.Services.Core;
using Unity.Services.Authentication;
using Unity.Services.Authentication.PlayerAccounts;//
using System.Threading.Tasks;
using TMPro;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using System;
using System.Text;
//using Unity.Notifications.Android;
//using Unity.Notifications.iOS;
//namespace Unity.Services.Authentication.PlayerAccounts
//{
public class LM : MonoBehaviour
{
[SerializeField] private TextMeshProUGUI ExceptionText;
[SerializeField] private TextMeshProUGUI StatusText;
[SerializeField] public TextMeshProUGUI PlayerIDText;
[SerializeField] private TextMeshProUGUI PlayerNameText;
[SerializeField] private TMP_InputField PlayerNameFieldText;
[SerializeField] private TextMeshProUGUI EmailText;
[SerializeField] private TMP_InputField EmailFieldText;
string m_ExternalIds;
public GameObject loginScreen;
public GameObject loginScreenBG;//
public GameObject notificationScreen;//
[SerializeField] public TextMeshProUGUI notificationText;//
public bool notificationAcknowledged = false;//
public GameObject uPScreen;
public GameObject DRText;
public GameObject WPText;
public bool signedInToAuthenticator;
public bool signedInToPlayerAccount;
public bool logOut;
private bool GameLoaded;
public static bool gameIsLoading;
public long lastNotificationDate;
public GameObject loadProgress;
public Slider slider;
public TextMeshProUGUI progressText;
public void LoadGameBeforeSceneChange()
{
CloudSaveManager.LoadPlayerData1();
CloudSaveManager.LoadPlayerData2();
CloudSaveManager.LoadPlayerDataAfterShop1();
CloudSaveManager.LoadPlayerDataAfterShop2();
CloudSaveManager.LoadPlayerDataAfterShop3();
CloudSaveManager.LoadPlayerDataAfterShop4();
}
public void InputUsername()
{
//PlayerPrefs.SetString("playername", PlayerNameFieldText.text);
PlayerData.PlayerName = PlayerNameFieldText.text;
}
public void InputEmail()
{
PlayerData.Email = EmailFieldText.text;
}
public void GoToMainMenu()
{
PlayerNameText.text = AuthenticationService.Instance.PlayerName;
PlayerData.Email = EmailFieldText.text;
PlayerData.TimesLoggedIn += 1;
PlayerData.Save();
SceneManager.LoadScene("Main Menu");
}
async void Awake()
{
try
{
await UnityServices.InitializeAsync();
PlayerAccountService.Instance.SignedIn += SignInWithUnity;
//PlayerAccountService.Instance.SignedIn += SignInWithUnity;
}
catch (Exception ex)
{
Debug.LogException(ex);
}
//logOut = MainMenu.wantToLogOut;
//if (logOut)
//{
// SignOut();
//}
}
public async void StartSignedInAsync()
{
if (PlayerAccountService.Instance.IsSignedIn)
{
SignInWithUnity();
return;
}
try
{
await PlayerAccountService.Instance.StartSignInAsync();
}
catch (RequestFailedException ex)
{
Debug.LogException(ex);
SetException(ex);
}
}
async void SignInWithUnity()
{
if (signedInToAuthenticator)
{
Debug.LogWarning("Sign-in already in progress. Please wait.");
return;
}
List<Unity.Services.Authentication.Notification> notifications = null;
try
{
await AuthenticationService.Instance.SignInWithUnityAsync(PlayerAccountService.Instance.AccessToken);
m_ExternalIds = GetExternalIds(AuthenticationService.Instance.PlayerInfo);
signedInToAuthenticator = true;
Debug.Log($"PlayerID: {AuthenticationService.Instance.PlayerId}");
Debug.Log("SignIn is Successful");
PlayerData.PlayerID = AuthenticationService.Instance.PlayerId;
CloudSaveManager.LoadTimesLoggedIn();
CloudSaveManager.LoadLastReadNotificationDate();
await Task.Delay(2000); //time in millisecond
string lastNotificationDateString = AuthenticationService.Instance.LastNotificationDate;
long storedNotificationDate = PlayerData.LastReadNotificationDate;
//Debug.Log(lastNotificationDateString);
//Debug.Log(storedNotificationDate);
if (!string.IsNullOrEmpty(lastNotificationDateString) && long.TryParse(lastNotificationDateString, out long lastNotificationDate))
{
if (lastNotificationDate > storedNotificationDate)
{
// Retrieve the notifications from the backend
notifications = await AuthenticationService.Instance.GetNotificationsAsync();
if (notifications != null)
{
PlayerData.LastReadNotificationDate = lastNotificationDate;
CloudSaveManager.SaveLastReadNotificationDate();
await DisplayNotifications(notifications);//
//DisplayNotifications(notifications);
}
else
{
Debug.Log("There are no new notifications");
}
}
}
if (PlayerData.TimesLoggedIn >= 1)
{
LoadGameBeforeSceneChange();
StartCoroutine(loadMainMenuProgress());
}
else
{
SetStatsForFirstTimePlaying();
loginScreen.SetActive(false);
DRText.SetActive(false);
WPText.SetActive(false);
uPScreen.SetActive(true);
}
UpdateUI();
}
catch (AuthenticationException ex)
{
Debug.LogException(ex);
}
catch (RequestFailedException ex)
{
Debug.LogException(ex);
SetException(ex);
// Handle sign-in failure and check for notifications
//if (ex is AuthenticationException authEx && authEx.Notifications != null)
//{
// await DisplayNotifications(authEx.Notifications);
//}
}
}
public void SignOut()
{
AuthenticationService.Instance.SignOut();
if (logOut)
{
//SAVE ALL GAME DATA HERE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
PlayerAccountService.Instance.SignOut();
signedInToPlayerAccount = false;
MainMenu.wantToLogOut = false;
logOut = false;
//PlayerAccountService.Instance.SignOut();
}
UpdateUI();
}
public void CancelSignIn()
{
logOut = true;
}
public void OpenAccountPortal()
{
Application.OpenURL(PlayerAccountService.Instance.AccountPortalUrl);
}
async Task DisplayNotifications(List<Unity.Services.Authentication.Notification> notifications)
{
loginScreen.SetActive(false);
loginScreenBG.SetActive(false);
notificationScreen.SetActive(true);
foreach (var notification in notifications)
{
notificationAcknowledged = false;
notificationText.text = notification.Message;
//Debug.Log("Displaying notification: " + notification.Message);
await WaitForNotificationAcknowledge();
//Debug.Log("Notification acknowledged, continuing to next notification");
}
}
async Task WaitForNotificationAcknowledge()
{
Debug.Log("Waiting for notification to be acknowledged");
while (!notificationAcknowledged)
{
await Task.Yield();
}
Debug.Log("Notification acknowledged, continuing");
}
public void ClickedNotificationWasRead()
{
PlayerData.LastReadNotificationDate = lastNotificationDate;
CloudSaveManager.SaveLastReadNotificationDate();
notificationAcknowledged = true;
}
void SaveLastNotificationReadDate()
{
PlayerData.LastReadNotificationDate = lastNotificationDate;
}
void UpdateUI()
{
var statusBuilder = new StringBuilder();
statusBuilder.AppendLine($"Player Accounts State: <b>{(PlayerAccountService.Instance.IsSignedIn ? "Signed in" : "Signed out")}</b>");
statusBuilder.AppendLine($"Player Accounts Access token: <b>{(string.IsNullOrEmpty(PlayerAccountService.Instance.AccessToken) ? "Missing" : "Exists")}</b>\n");
statusBuilder.AppendLine($"Authentication Service State: <b>{(AuthenticationService.Instance.IsSignedIn ? "Signed in" : "Signed out")}</b>");
if (AuthenticationService.Instance.IsSignedIn)
{
statusBuilder.AppendLine(GetPlayerInfoText());
statusBuilder.AppendLine($"PlayerId: <b>{AuthenticationService.Instance.PlayerId}</b>");
}
StatusText.text = statusBuilder.ToString();
SetException(null);
}
string GetExternalIds(PlayerInfo playerInfo)
{
if (playerInfo.Identities == null)
{
return "None";
}
var sb = new StringBuilder();
foreach (var id in playerInfo.Identities)
{
sb.Append(" " + id.TypeId);
}
return sb.ToString();
}
string GetPlayerInfoText()
{
return $"ExternalIds: <b>{m_ExternalIds}</b>";
}
void SetException(Exception ex)
{
ExceptionText.text = ex != null ? $"{ex.GetType().Name}: {ex.Message}" : "";
}
IEnumerator loadMainMenuProgress()
{
yield return new WaitForSeconds(2f);
PlayerData.TimesLoggedIn += 1;
AsyncOperation operation = SceneManager.LoadSceneAsync("Main Menu");
loadProgress.SetActive(true);
while (operation.isDone == false)
{
float progress = Mathf.Clamp01(operation.progress / .9f);
slider.value = progress;
progressText.text = progress * 100f + "%";
yield return null;
}
}
Can someone please help me figure this out. Thank you very much.