How to Integrate Huawei Account kit - unity3d

Currently I'm using Huawei Plugin From EvilMindDev.
Below is AccountManager script.
using HuaweiMobileServices.Id;
using HuaweiMobileServices.Utils;
using System;
using UnityEngine;
namespace HmsPlugin
{
public class AccountManager : MonoBehaviour
{
public static AccountManager GetInstance(string name = "AccountManager") => GameObject.Find(name).GetComponent<AccountManager>();
private static HuaweiIdAuthService DefaultAuthService
{
get
{
Debug.Log("[HMS]: GET AUTH");
var authParams = new HuaweiIdAuthParamsHelper(HuaweiIdAuthParams.DEFAULT_AUTH_REQUEST_PARAM).SetIdToken().CreateParams();
Debug.Log("[HMS]: AUTHPARAMS AUTHSERVICE" + authParams);
var result = HuaweiIdAuthManager.GetService(authParams);
Debug.Log("[HMS]: RESULT AUTHSERVICE"+ result);
return result;
}
}
public AuthHuaweiId HuaweiId { get; private set; }
public Action<AuthHuaweiId> OnSignInSuccess { get; set; }
public Action<HMSException> OnSignInFailed { get; set; }
private HuaweiIdAuthService authService;
// Start is called before the first frame update
void Awake()
{
Debug.Log("[HMS]: AWAKE AUTHSERVICE");
authService = DefaultAuthService;
Debug.Log("DefaultAuthService : "+DefaultAuthService);
Debug.Log("authService : "+authService);
}
public void SignIn()
{
Debug.Log("[HMS]: Sign in " + authService);
authService.StartSignIn((authId) =>
{
HuaweiId = authId;
Debug.Log("HuaweiId : "+HuaweiId);
OnSignInSuccess?.Invoke(authId);
}, (error) =>
{
HuaweiId = null;
OnSignInFailed?.Invoke(error);
});
}
public void SignOut()
{
Debug.Log("authService.SignOut");
authService.SignOut();
HuaweiId = null;
}
}
}
Below is AccountSignIn script.
using HuaweiMobileServices.Id;
using HuaweiMobileServices.Utils;
using UnityEngine;
using UnityEngine.UI;
using HmsPlugin;
public class AccountSignIn : MonoBehaviour
{
private const string NOT_LOGGED_IN = "No user logged in";
private const string LOGGED_IN = "{0} is logged in";
private const string LOGIN_ERROR = "Error or cancelled login";
private Text loggedInUser;
private AccountManager accountManager;
// Start is called before the first frame update
void Start()
{
loggedInUser = GameObject.Find("LoggedUserText").GetComponent<Text>();
loggedInUser.text = NOT_LOGGED_IN;
//accountManager = AccountManager.GetInstance();
accountManager = GetComponent<AccountManager>();
accountManager.OnSignInSuccess = OnLoginSuccess;
accountManager.OnSignInFailed = OnLoginFailure;
LogIn();
}
public void LogIn()
{
accountManager.SignIn();
}
public void LogOut()
{
accountManager.SignOut();
loggedInUser.text = NOT_LOGGED_IN;
}
public void OnLoginSuccess(AuthHuaweiId authHuaweiId)
{
loggedInUser.text = string.Format(LOGGED_IN, authHuaweiId.DisplayName);
}
public void OnLoginFailure(HMSException error)
{
loggedInUser.text = LOGIN_ERROR;
}
}
Everytime I try to SignIn it will give me this error.
This is HuaweiIdAuthService.
Even if I try the demo provided will give me the same error.
If I try debug using Android Studio it will still give me the same error.
public void SignIn()
{
Debug.Log("[HMS]: Sign in " + authService);
authService.StartSignIn((authId) =>
{
HuaweiId = authId;
Debug.Log("HuaweiId : "+HuaweiId);
OnSignInSuccess?.Invoke(authId);
}, (error) =>
{
HuaweiId = null;
OnSignInFailed?.Invoke(error);
});
}
the authService doesn't return anything. Where can I get that from ?

It is a null pointer. Please check for unassigned objects. If you cannot find anything, please delete project and install again cause sometimes these kind of things happening.

This plugin have 2 branch for Unity 2019 and Unity 2018.
You should activate Account Kit API in Huawei Appgallery
Check configuration AndroidManifest file
Check Agconnect-service.json file

Related

How to check if unity video ads ready to show or loaded

I'm using Unity Ads in my game. In older version i check if unity video ads are ready to show then call a method to show ads like this
public bool IsVideoReady()
{
if (Advertisement.IsReady())
return true;
else
return false;
}
But in new version i dont know how to check if unity video ads are ready or loaded to show.
My new script is
using UnityEngine;
using UnityEngine.Advertisements;
public class AdsInitializer : MonoBehaviour, IUnityAdsInitializationListener, IUnityAdsLoadListener, IUnityAdsShowListener
{
[SerializeField] string _androidGameId;
[SerializeField] string _iOSGameId;
string _gameId;
[SerializeField] bool _testMode = true;
private void Awake()
{
if (Advertisement.isInitialized)
{
Debug.Log("Advertisement is Initialized");
LoadRewardedAd();
}
else
{
InitializeAds();
}
}
public void InitializeAds()
{
_gameId = (Application.platform == RuntimePlatform.IPhonePlayer) ? _iOSGameId : _androidGameId;
Advertisement.Initialize(_gameId, _testMode, this);
}
public void OnInitializationComplete()
{
Debug.Log("Unity Ads initialization complete.");
LoadInerstitialAd();
LoadBannerAd();
}
public void OnInitializationFailed(UnityAdsInitializationError error, string message)
{
Debug.Log($"Unity Ads Initialization Failed: {error.ToString()} - {message}");
}
public void LoadInerstitialAd()
{
Advertisement.Load("Interstitial_Android", this);
}
public void LoadRewardedAd()
{
Advertisement.Load("Rewarded_Android", this);
}
public void OnUnityAdsAdLoaded(string placementId)
{
Debug.Log("OnUnityAdsAdLoaded");
Advertisement.Show(placementId,this);
}
public void OnUnityAdsFailedToLoad(string placementId, UnityAdsLoadError error, string message)
{
Debug.Log($"Error showing Ad Unit {placementId}: {error.ToString()} - {message}");
}
public void OnUnityAdsShowFailure(string placementId, UnityAdsShowError error, string message)
{
Debug.Log("OnUnityAdsShowFailure");
}
public void OnUnityAdsShowStart(string placementId)
{
Debug.Log("OnUnityAdsShowStart");
Time.timeScale = 0;
Advertisement.Banner.Hide();
}
public void OnUnityAdsShowClick(string placementId)
{
Debug.Log("OnUnityAdsShowClick");
}
public void OnUnityAdsShowComplete(string placementId, UnityAdsShowCompletionState showCompletionState)
{
Debug.Log("OnUnityAdsShowComplete "+showCompletionState);
if (placementId.Equals("Rewarded_Android") && UnityAdsShowCompletionState.COMPLETED.Equals(showCompletionState))
{
Debug.Log("rewared Player");
}
Time.timeScale = 1;
Advertisement.Banner.Show("Banner_Android");
}
public void LoadBannerAd()
{
Advertisement.Banner.SetPosition(BannerPosition.BOTTOM_CENTER);
Advertisement.Banner.Load("Banner_Android",
new BannerLoadOptions
{
loadCallback = OnBannerLoaded,
errorCallback = OnBannerError
}
);
}
void OnBannerLoaded()
{
Advertisement.Banner.Show("Banner_Android");
}
void OnBannerError(string message)
{
}
}
i just want to know how to check if unity interstital or rewarded ads are ready before showing them.
because in new versions Advertisment.isReady() is not working any more

photon pun2 unity playfab email and password auth

i want to make email auth with playfab and photon istead of custom id auth shown in photon quickstart guide playfab. i tried this script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Realtime;
using Photon.Pun;
using PlayFab;
using PlayFab.ClientModels;
using TMPro;
public class pfauth : MonoBehaviour
{
#region objects
[Header (" register ")]
public TMP_InputField user;
public TMP_InputField email;
public TMP_InputField pass;
public GameObject regpanel;
[Header(" login ")]
public TMP_InputField luser;
public TMP_InputField lpass;
public GameObject loginpanel;
[Header(" Other gameobjects ")]
public TMP_Text message;
public bool IsAuthenticated = false;
public GameObject prpo;
public float sec;
private string _playFabPlayerIdCache;
LoginWithPlayFabRequest loginrequest;
#endregion
public void Start() //set the loginpanel as disable at start
{
loginpanel.SetActive(false);
regpanel.SetActive(true);
}
public void login()
{
loginrequest = new LoginWithPlayFabRequest();
loginrequest.Username = luser.text;
loginrequest.Password = lpass.text;
PlayFabClientAPI.LoginWithPlayFab(loginrequest, \\in this line how can i call requestphotontoken result => {
//if account found
message.text = "welcome back" + user.text + "loging in...";
StartCoroutine("waitforempty"); //hide the text after few seconds
IsAuthenticated = true;
Debug.Log("logged in");
}, error => {
message.text = "Sorry! Failed to login(" + error.ErrorMessage + ")";
StartCoroutine("waitforempty"); //hide the text after few seconds
Debug.Log(error.ErrorDetails);
IsAuthenticated = false;
}, null);
}
public void register()
{
RegisterPlayFabUserRequest request = new RegisterPlayFabUserRequest();
request.Email = email.text;
request.Password = pass.text;
request.Username = user.text;
PlayFabClientAPI.RegisterPlayFabUser(request, \\in this line how can i call requestphotontoken result =>
{
message.text = "Your account has been created!";
StartCoroutine("waitforempty"); //hide the text after few seconds
prpo.SetActive(true);
}, error =>
{
message.text = "Sorry! Failed to create your account(" + error.ErrorMessage + ")";
StartCoroutine("waitforempty"); //hide the text after few seconds
});
}
public void regpan()
{
loginpanel.SetActive(false);
regpanel.SetActive(true);
}
public void logbak()
{
loginpanel.SetActive(true);
regpanel.SetActive(false);
}
IEnumerator waitforempty() //hide the text after few seconds
{
yield return new WaitForSeconds(sec);
message.text = " ";
}
private void RequestPhotonToken(LoginResult obj)
{
LogMessage("PlayFab authenticated. Requesting photon token...");
//We can player PlayFabId. This will come in handy during next step
_playFabPlayerIdCache = obj.PlayFabId;
PlayFabClientAPI.GetPhotonAuthenticationToken(new GetPhotonAuthenticationTokenRequest()
{
PhotonApplicationId = PhotonNetwork.PhotonServerSettings.AppSettings.AppIdRealtime
}, AuthenticateWithPhoton, OnPlayFabError);
}
/*
* Step 3
* This is the final and the simplest step. We create new AuthenticationValues instance.
* This class describes how to authenticate a players inside Photon environment.
*/
private void AuthenticateWithPhoton(GetPhotonAuthenticationTokenResult obj)
{
LogMessage("Photon token acquired: " + obj.PhotonCustomAuthenticationToken + " Authentication complete.");
//We set AuthType to custom, meaning we bring our own, PlayFab authentication procedure.
var customAuth = new AuthenticationValues { AuthType = CustomAuthenticationType.Custom };
//We add "username" parameter. Do not let it confuse you: PlayFab is expecting this parameter to contain player PlayFab ID (!) and not username.
customAuth.AddAuthParameter("username", _playFabPlayerIdCache); // expected by PlayFab custom auth service
//We add "token" parameter. PlayFab expects it to contain Photon Authentication Token issues to your during previous step.
customAuth.AddAuthParameter("token", "");
//We finally tell Photon to use this authentication parameters throughout the entire application.
PhotonNetwork.AuthValues = customAuth;
Debug.Log(PhotonNetwork.ConnectUsingSettings().ToString());
}
private void OnPlayFabError(PlayFabError obj)
{
LogMessage(obj.GenerateErrorReport());
}
public void LogMessage(string message)
{
Debug.Log("PlayFab + Photon Example: " + message);
}
}
but in the "PlayFabClientAPI.LoginWithPlayFab(loginrequest, \in this line how can i call requestphotontoken" result line in both login and register void when i try to call RequestPhotonToken i shows this error-
Cannot convert methord group to function
please help
Photon PUN 2
Playfab latest

Read Events from EventHub in Unity3D and HoloLens

We are trying to show events from an Azure EventHub in our HoloLens application. When we run our project in Unity 3D, it works and paint the data from the events.
But when we deploy the same solution on the HoloLens, we don't receive events and also we don't receive any error.
Here is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Microsoft.MixedReality.Toolkit.UI;
using TMPro;
using System;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using Azure.Messaging.EventHubs;
using Azure.Messaging.EventHubs.Processor;
using Azure.Storage.Blobs;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Microsoft.MixedReality.Toolkit.Examples.Demos
{
[AddComponentMenu("Scripts/MRTK/Examples/SliderLunarLander")]
public class Manager : MonoBehaviour
{
[SerializeField]
public Animator helice2;
public TextMeshPro textovelocidad;
public EventProcessorClient processor;
public BlobContainerClient storageClient;
private const string storageConnectionString = "XXXX";
private const string blobContainerName = "XXXX";
private const string eventHubsConnectionString = "XXXX";
private const string consumerGroup = "hololens";
private const string EventHubName = "XXXX";
private float? speedValue;
private string errorText = string.Empty;
private CancellationToken cancellationToken;
async void Start()
{
errorText = "Init EventReader...";
storageClient = new BlobContainerClient(storageConnectionString, blobContainerName);
var clientOptions = new EventProcessorClientOptions()
{
ConnectionOptions = new EventHubConnectionOptions ()
{
TransportType = EventHubsTransportType.AmqpWebSockets
}
};
processor = new EventProcessorClient
(
storageClient,
consumerGroup,
eventHubsConnectionString,
clientOptions
);
processor.ProcessEventAsync += processEventHandler;
processor.ProcessErrorAsync += processErrorHandler;
errorText = "Start EventReader...";
await processor.StartProcessingAsync();
try
{
//The processor performs its work in the background; block until cancellation
//to allow processing to take place.
errorText = "Infinite Loop...";
await Task.Delay(Timeout.Infinite);
}
catch (TaskCanceledException tcex)
{
//This is expected when the delay is canceled.
textoError.text = tcex.Message;
}
//Debug.Log("Device client initialited...");
}
public void OnSliderUpdated(SliderEventData eventData)
{
helice2.speed = eventData.NewValue;
}
async void OnDestroy()
{
try
{
await processor.StopProcessingAsync();
}
finally
{
//To prevent leaks, the handlers should be removed when processing is complete.
processor.ProcessEventAsync -= processEventHandler;
processor.ProcessErrorAsync -= processErrorHandler;
}
}
private void Update()
{
if (speedValue != null)
{
helice2.speed = float.Parse(speedValue.ToString());
}
textovelocidad.text = (helice2.speed).ToString("F2") + " r.p.m.";
textovelocidad.text += " | " + infoText;
textoError.text = errorText;
}
async Task processEventHandler(ProcessEventArgs eventArgs)
{
try
{
// Write the body of the event to the console window
//Console.WriteLine("\tRecevied event: {0}", Encoding.UTF8.GetString(eventArgs.Data.Body.ToArray()));
infoText = " Event Received ";
string json = Encoding.UTF8.GetString(eventArgs.Data.Body.ToArray());
var deviceTurbine = JsonSerializer.Deserialize<DeviceTurbine>(json);
if (deviceTurbine != null)
{
speedValue = deviceTurbine.speed;
}
// Update checkpoint in the blob storage so that the app receives only new events the next time it's run
await eventArgs.UpdateCheckpointAsync(eventArgs.CancellationToken);
}
catch (Exception ex)
{
// Handle the exception from handler code
// Debug.LogError(ex.Message);
errorText = ex.Message;
}
}
Task processErrorHandler(ProcessErrorEventArgs eventArgs)
{
try
{
// Write details about the error to the console window
//Console.WriteLine($"\tPartition '{ eventArgs.PartitionId}': an unhandled exception was encountered. This was not expected to happen.");
//Console.WriteLine(eventArgs.Exception.Message);
errorText = eventArgs.Exception.Message;
}
catch
{
// Handle the exception from handler code
errorText = eventArgs.Exception.Message;
}
return Task.CompletedTask;
}
}
class DeviceTurbine
{
private float _speed;
private DateTime _timestamp;
private string _deviceId;
public float speed
{
get; set;
}
public DateTime timestamp
{
get;set;
}
public string deviceId
{
get; set;
}
}
}

Using admob rewarded ad in unity singleton pattern

I am using admob ads in my app and they are working fine. But when i try to do something after a ad close or reward earned call back my code breaks. Following is my adMob script
public class AdMobScript : MonoBehaviour
{
...
public event Action OnReviveRewardEarned;
public event Action OnReviveAdLoaded;
public event Action OnReviveAdClosed;
private void LoadReviveRewardedAd()
{
reviveRewardedAd = new RewardedAd(adReviveRewardedId);
reviveRewardedAd.OnAdLoaded += ReviveAdLoaded;
reviveRewardedAd.OnUserEarnedReward += ReviveEarnedReward;
reviveRewardedAd.OnAdClosed += ReviveAdClosed;
AdRequest request = new AdRequest.Builder().Build();
reviveRewardedAd.LoadAd(request);
}
private void ReviveAdClosed(object sender, EventArgs e)
{
LoadReviveRewardedAd();
if (isRewardErned)
{
isRewardErned = false;
OnReviveRewardEarned.Invoke();
}
else
OnReviveAdClosed.Invoke();
}
private void ReviveEarnedReward(object sender, Reward e)
{
isRewardErned = true;
}
private void ReviveAdLoaded(object sender, EventArgs e)
{
//reviveButton.interactable = true;
OnReviveAdLoaded.Invoke();
}
public void ShowAdToRevive()
{
if (reviveRewardedAd.IsLoaded())
{
reviveRewardedAd.Show();
}
}
...
}
In the callbacks i am calling my adManager script which is in term using adMob script. Here is the code for it.
public class AdManager : MonoBehaviour
{
...
private void Start() {
AdMobScript.instance.OnReviveAdClosed += ReviveAdClosed;
AdMobScript.instance.OnReviveAdLoaded += ReviveAdLoaded;
AdMobScript.instance.OnReviveRewardEarned += ReviveReward;
}
#region ReviveAds
private void ReviveReward() {
//game crash here
backButton.gameObject.SetActive(true);
reviveButton.gameObject.SetActive(false);
noThanksButton.gameObject.SetActive(false);
manager.Revive();
}
private void ReviveAdLoaded() {
reviveButton.interactable = true;
}
private void ReviveAdClosed() {
//game crash here
reviveButton.interactable = false;
}
public void ShowAdToRevive() {
AdMobScript.instance.ShowAdToRevive();
}
...
}
After either ad close or reward earned my game crashes (error log says
get_gameObject can only be called from the main thread
). There must be something i am doing wrong. Can anyone please point me to the right direction?
The reason for the problem - you trying to manipulate with MonoBehaviors, not in main thread.
Just write simple scheduler which calls the events in the Unity thread, like this:
Scheduler:
using System;
using UnityEngine;
public class Scheduler : MonoBehaviour
{
public static Scheduler instance;
public event Action secondTick = delegate { };
private float seconds = 0;
private void Awake()
{
instance = this;
}
private void Update()
{
seconds += Time.unscaledDeltaTime;
if (seconds >= 1.0f)
{
seconds -= 1.0f;
secondTick.Invoke();
}
}
}
Updated AdMobScript:
public class AdMobScript : MonoBehaviour
{
...
private bool onRewardEarnedCall = false;
private bool onRewardAdLoaded = false;
private bool onRewardAdClosed = false;
public event Action OnReviveRewardEarned;
public event Action OnReviveAdLoaded;
public event Action OnReviveAdClosed;
private void LoadReviveRewardedAd()
{
reviveRewardedAd = new RewardedAd(adReviveRewardedId);
reviveRewardedAd.OnAdLoaded += ReviveAdLoaded;
reviveRewardedAd.OnUserEarnedReward += ReviveEarnedReward;
reviveRewardedAd.OnAdClosed += ReviveAdClosed;
AdRequest request = new AdRequest.Builder().Build();
reviveRewardedAd.LoadAd(request);
Scheduler.instance.secondTick += OnSecondTick;
}
private void OnSecondTick()
{
if(onRewardAdClosed)
{
onRewardAdClosed = false;
OnReviveAdClosed.Invoke();
}
if(onRewardEarnedCall)
{
OnReviveRewardEarned.Invoke();
onRewardEarnedCall = false;
}
if(onRewardAdLoaded)
{
OnReviveAdLoaded.Invoke();
onRewardAdLoaded = false;
}
}
private void ReviveAdClosed(object sender, EventArgs e)
{
LoadReviveRewardedAd();
if (isRewardErned)
{
isRewardErned = false;
onRewardEarnedCall = true;
}
else
onRewardAdClosed = true;
}
private void ReviveEarnedReward(object sender, Reward e)
{
isRewardErned = true;
}
private void ReviveAdLoaded(object sender, EventArgs e)
{
//reviveButton.interactable = true;
onRewardAdLoaded = true;
}
public void ShowAdToRevive()
{
if (reviveRewardedAd.IsLoaded())
{
reviveRewardedAd.Show();
}
}
...
}
This is a very simple and not optimize solution but this will solve your problem.

JoinRandomRoom no joined in the same room with 2 players?

this is my code...
public class AutoLog : MonoBehaviourPunCallbacks
{
public void Connect()
{
if (!PhotonNetwork.IsConnected)
{
if (PhotonNetwork.ConnectUsingSettings())
{
log.text += "\nConnected to Server";
}
else
{
log.text += "\nFalling Connecting to Server";
}
}
}
public override void OnConnectedToMaster()
{
connect.interactable = false;
join.interactable = true;
}
............
public void JoinRandom()
{
if (!PhotonNetwork.JoinRandomRoom())
{
log.text += "\nFail Joinned Room";
}
}
any idea what can happen or how to solve
public override void OnJoinRandomFailed(short returnCode, string message)
{
log.text += "\nNo Rooms to Join, creating one...";
if(PhotonNetwork.CreateRoom(null, new Photon.Realtime.RoomOptions() { MaxPlayers = maxPlayer }))
{
log.text += "\nRoom Create";
}
else
{
log.text += "\nFail Creating Room";
}
}
public override void OnJoinedRoom()
{
log.text += "\nJoinned";
}
}
when 2 players enter they don't join the same room, each player creates another room.
I use Photon2 for unity.
any idea what can happen or how to solve
You can use this script and easily you will join you both players in a single room. This script is working on my project. make sure you set the Photon App ID which create from photon dashboard.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine;
using Photon.Pun;
using Photon.Realtime;
public class AutoLog : MonoBehaviourPunCallbacks
{
string gameVersion = "1";
private byte maxPlayersPerRoom = 2;
public GameObject controlPanel;
public GameObject progressLabel;
bool isConnecting;
void Awake()
{
// #Critical
// this makes sure we can use PhotonNetwork.LoadLevel() on the master client and all clients in the same room sync their level automatically
PhotonNetwork.AutomaticallySyncScene = true;
}
void Start()
{
// Connect();
progressLabel.SetActive(false);
controlPanel.SetActive(true);
}
public void Connect()
{
isConnecting = true;
progressLabel.SetActive(true);
controlPanel.SetActive(false);
// we check if we are connected or not, we join if we are , else we initiate the connection to the server.
Debug.Log(PhotonNetwork.IsConnected);
if (PhotonNetwork.IsConnected)
{
// #Critical we need at this point to attempt joining a Random Room. If it fails, we'll get notified in OnJoinRandomFailed() and we'll create one.
PhotonNetwork.JoinRandomRoom();
}
else
{
// #Critical, we must first and foremost connect to Photon Online Server.
PhotonNetwork.GameVersion = gameVersion;
PhotonNetwork.ConnectUsingSettings();
Debug.Log("<color=green>Connected </color>");
}
}
public override void OnConnectedToMaster()
{
if (isConnecting)
{
Debug.Log(" OnConnectedToMaster() ");
// #Critical: The first we try to do is to join a potential existing room. If there is, good, else, we'll be called back with OnJoinRandomFailed()
PhotonNetwork.JoinRandomRoom();
}
}
public override void OnDisconnected(DisconnectCause cause)
{
PhotonNetwork.Disconnect();
Debug.LogWarningFormat("OnDisconnected()", cause);
// progressLabel.SetActive(false);
//controlPanel.SetActive(true);
}
public override void OnJoinRandomFailed(short returnCode, string message)
{
Debug.Log("OnJoinRandomFailed() ");
// #Critical: we failed to join a random room, maybe none exists or they are all full. No worries, we create a new room.
PhotonNetwork.CreateRoom(null, new RoomOptions { MaxPlayers = maxPlayersPerRoom });
}
public override void OnJoinedRoom()
{
Debug.Log(" OnJoinedRoom() ");
Debug.Log(PhotonNetwork.IsConnected);
if (PhotonNetwork.CurrentRoom.PlayerCount == 1)
{ PhotonNetwork.LoadLevel(1);
Debug.Log("Master Connected in Room");
// #Critical
// Load the Room Level.
}
if (PhotonNetwork.CurrentRoom.PlayerCount == 2)
{
PhotonNetwork.LoadLevel(1);
}
}
}
If you connect to Photon Cloud, make sure that all clients connect to the same virtual application (AppId + AppVersion) and connect to the same servers (same region).
Go through the "Matchmaking Checklist" carefully.