Hello, I get this error when I run my game in unity: NullReferenceException: Object reference not set to an instance of an object PlayFab.PlayFabMultiplayerAgentAPI.Start () (at Assets/PlayFabSDK/MultiplayerAgent/PlayFabMultiplayerAgentAPI.cs:84) AgentListener.Start () (at Assets/2_Scripts/AgentListener.cs:17)
I have tested it on LocalMultiplayer multiple times and it works fine there I guess? (goes through all the steps and ends with the server being active) I believe this error is causing my player count and other connections to the server to not work because the MPAAPI cant even get past the first step. I followed the Unity Mirror sample (copied all the component's into my project). Been trying to fix this error for a week now.
here is my AgentListener.cs
using System.Collections;
using UnityEngine;
using PlayFab;
using System;
using PlayFab.Networking;
using System.Collections.Generic;
using PlayFab.MultiplayerAgent.Model;
using System.Linq;
public class AgentListener : MonoBehaviour {
private List<ConnectedPlayer> _connectedPlayers;
public bool Debugging = true;
// Use this for initialization
void Start () {
_connectedPlayers = new List<ConnectedPlayer>();
PlayFabMultiplayerAgentAPI.Start();
PlayFabMultiplayerAgentAPI.IsDebugging = Debugging;
PlayFabMultiplayerAgentAPI.OnMaintenanceCallback += OnMaintenance;
PlayFabMultiplayerAgentAPI.OnShutDownCallback += OnShutdown;
PlayFabMultiplayerAgentAPI.OnServerActiveCallback += OnServerActive;
PlayFabMultiplayerAgentAPI.OnAgentErrorCallback += OnAgentError;
UnityNetworkServer.Instance.OnPlayerAdded.AddListener(OnPlayerAdded);
UnityNetworkServer.Instance.OnPlayerRemoved.AddListener(OnPlayerRemoved);
// get the port that the server will listen to
// We *have to* do it on process mode, since there might be more than one game server instances on the same VM and we want to avoid port collision
// On container mode, we can omit the below code and set the port directly, since each game server instance will run on its own network namespace. However, below code will work as well
// we have to do that on process
var connInfo = PlayFabMultiplayerAgentAPI.GetGameServerConnectionInfo();
// make sure the ListeningPortKey is the same as the one configured in your Build settings (either on LocalMultiplayerAgent or on MPS)
const string ListeningPortKey = "gameport";
var portInfo = connInfo.GamePortsConfiguration.Where(x=>x.Name == ListeningPortKey);
if(portInfo.Count() > 0)
{
Debug.Log(string.Format("port with name {0} was found in GSDK Config Settings.", ListeningPortKey));
UnityNetworkServer.Instance.Port = portInfo.Single().ServerListeningPort;
}
else
{
string msg = string.Format("Cannot find port with name {0} in GSDK Config Settings. If you are running locally, make sure the LocalMultiplayerAgent is running and that the MultiplayerSettings.json file includes correct name as a GamePort Name. If you are running this sample in the cloud, make sure you have assigned the correct name to the port", ListeningPortKey);
Debug.LogError(msg);
throw new Exception(msg);
}
StartCoroutine(ReadyForPlayers());
}
IEnumerator ReadyForPlayers()
{
yield return new WaitForSeconds(.5f);
PlayFabMultiplayerAgentAPI.ReadyForPlayers();
}
private void OnServerActive()
{
UnityNetworkServer.Instance.StartListen();
Debug.Log("Server Started From Agent Activation");
}
private void OnPlayerRemoved(string playfabId)
{
ConnectedPlayer player = _connectedPlayers.Find(x => x.PlayerId.Equals(playfabId, StringComparison.OrdinalIgnoreCase));
_connectedPlayers.Remove(player);
PlayFabMultiplayerAgentAPI.UpdateConnectedPlayers(_connectedPlayers);
}
private void OnPlayerAdded(string playfabId)
{
_connectedPlayers.Add(new ConnectedPlayer(playfabId));
PlayFabMultiplayerAgentAPI.UpdateConnectedPlayers(_connectedPlayers);
}
private void OnAgentError(string error)
{
Debug.Log(error);
}
private void OnShutdown()
{
Debug.Log("Server is shutting down");
foreach(var conn in UnityNetworkServer.Instance.Connections)
{
conn.Connection.Send<ShutdownMessage>(new ShutdownMessage());
}
StartCoroutine(Shutdown());
}
IEnumerator Shutdown()
{
yield return new WaitForSeconds(5f);
Application.Quit();
}
private void OnMaintenance(DateTime? NextScheduledMaintenanceUtc)
{
Debug.LogFormat("Maintenance scheduled for: {0}", NextScheduledMaintenanceUtc.Value.ToLongDateString());
foreach (var conn in UnityNetworkServer.Instance.Connections)
{
conn.Connection.Send<MaintenanceMessage>(new MaintenanceMessage() {
ScheduledMaintenanceUTC = (DateTime)NextScheduledMaintenanceUtc
});
}
}
}
Here is my UnityNetworkServer.cs
namespace PlayFab.Networking
{
using System;
using System.Collections.Generic;
using UnityEngine;
using Mirror;
using UnityEngine.Events;
public class UnityNetworkServer : NetworkManager
{
public static UnityNetworkServer Instance { get; private set; }
public PlayerEvent OnPlayerAdded = new PlayerEvent();
public PlayerEvent OnPlayerRemoved = new PlayerEvent();
public int MaxConnections = 100;
public int Port = 7777; // overwritten by the code in AgentListener.cs
public List<UnityNetworkConnection> Connections
{
get { return _connections; }
private set { _connections = value; }
}
private List<UnityNetworkConnection> _connections = new List<UnityNetworkConnection>();
public class PlayerEvent : UnityEvent<string> { }
// Use this for initialization
public override void Awake()
{
base.Awake();
Instance = this;
NetworkServer.RegisterHandler<ReceiveAuthenticateMessage>(OnReceiveAuthenticate);
}
public void StartListen()
{
this.GetComponent<TelepathyTransport>().port = (ushort)Port;
NetworkServer.Listen(MaxConnections);
}
public override void OnApplicationQuit()
{
base.OnApplicationQuit();
NetworkServer.Shutdown();
}
private void OnReceiveAuthenticate(NetworkConnection nconn, ReceiveAuthenticateMessage message)
{
var conn = _connections.Find(c => c.ConnectionId == nconn.connectionId);
if(conn != null)
{
conn.PlayFabId = message.PlayFabId;
conn.IsAuthenticated = true;
OnPlayerAdded.Invoke(message.PlayFabId);
}
}
public override void OnServerConnect(NetworkConnectionToClient conn)
{
base.OnServerConnect(conn);
Debug.LogWarning("Client Connected");
var uconn = _connections.Find(c => c.ConnectionId == conn.connectionId);
if (uconn == null)
{
_connections.Add(new UnityNetworkConnection()
{
Connection = conn,
ConnectionId = conn.connectionId,
LobbyId = PlayFabMultiplayerAgentAPI.SessionConfig.SessionId
});
}
}
[Obsolete]
public override void OnServerError(NetworkConnectionToClient conn, Exception ex)
{
base.OnServerError(conn, ex);
Debug.Log(string.Format("Unity Network Connection Status: exception - {0}", ex.Message));
}
public override void OnServerDisconnect(NetworkConnectionToClient conn)
{
base.OnServerDisconnect(conn);
var uconn = _connections.Find(c => c.ConnectionId == conn.connectionId);
if (uconn != null)
{
if (!string.IsNullOrEmpty(uconn.PlayFabId))
{
OnPlayerRemoved.Invoke(uconn.PlayFabId);
}
_connections.Remove(uconn);
}
}
}
[Serializable]
public class UnityNetworkConnection
{
public bool IsAuthenticated;
public string PlayFabId;
public string LobbyId;
public int ConnectionId;
public NetworkConnection Connection;
}
public class CustomGameServerMessageTypes
{
public const short ReceiveAuthenticate = 900;
public const short ShutdownMessage = 901;
public const short MaintenanceMessage = 902;
}
public struct ReceiveAuthenticateMessage : NetworkMessage
{
public string PlayFabId;
}
public struct ShutdownMessage : NetworkMessage {}
[Serializable]
public struct MaintenanceMessage : NetworkMessage
{
public DateTime ScheduledMaintenanceUTC;
}
}
And here is line 84 of the PlayFabMultiplayerAgentAPI where I get the second part of my null exception
_baseUrl = string.Format("http://{0}/v1/sessionHosts/{1}/heartbeats", _gsdkconfig.HeartbeatEndpoint, _gsdkconfig.SessionHostId);
I really dont know what is wrong. I tried rebuilding everything multiple times and tested it locally.