OnClientConnect is never called on the client?

Hi there,

I cobbled together a NetworkManager subclass for the express purpose of being able to use the MatchMaker (I’m building a quick prototype with no need for lobbies or choosing servers, I just want the server to spin up and the client to connect to the first available and toss you in the game.).

The code that follows is almost entirely copy pasted from various places in the UNET documentation.

OnClientConnected is never called here, which I’m guessing is why OnServerAddPlayer is never called either. Why is OnClientConnected not called?

I’m on Unity 5.1.

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
using UnityEngine.Networking.Match;
using UnityEngine.Networking.Types;
using UnityEngine.UI;

public class CustomNetworkManager : NetworkManager {

    [SerializeField] private Text _debugTextPrefab = null;
    [SerializeField] private Transform _debugTextParent = null;
    private bool _matchCreated = false;

    enum DebugLogType
    {
        Info,
        Warning,
        Error
    }

    void DebugLog(string log, DebugLogType type = DebugLogType.Info)
    {
        Text debugText = Instantiate<Text>(_debugTextPrefab);
        debugText.transform.SetParent(_debugTextParent, false);

        debugText.text = log;

        if (type == DebugLogType.Warning)
        {
            debugText.color = Color.blue;
        }

        if (type == DebugLogType.Error)
        {
            debugText.color = Color.red;
        }
    }

    public override void OnServerAddPlayer(NetworkConnection conn, short playerControllerId)
    {
        DebugLog("OnServerAddPlayer called");

        GameObject player = (GameObject)Instantiate(playerPrefab, Vector3.zero, Quaternion.identity);
        player.transform.SetParent(transform, false);
        player.GetComponent<Player>().Init();
        NetworkServer.AddPlayerForConnection(conn, player, playerControllerId);
    }
   
    public void Create()
    {
        StartMatchMaker();
        matchMaker.CreateMatch(
            "match1",
            (uint)2,
            true,
            "",
            OnMatchCreate);
    }

    public void Join()
    {
        StartMatchMaker();
        matchMaker.ListMatches(0, 20, "", OnMatchList);
    }

    public override void OnMatchCreate(CreateMatchResponse matchResponse)
    {
        if (matchResponse.success)
        {
            DebugLog("Create match succeeded");
            _matchCreated = true;
            Utility.SetAccessTokenForNetwork(matchResponse.networkId, new NetworkAccessToken(matchResponse.accessTokenString));
            NetworkServer.Listen(new MatchInfo(matchResponse), 9000);
        }
        else
        {
            DebugLog("Create match failed", DebugLogType.Error);
        }
    }
   
    public override void OnMatchList(ListMatchResponse matchListResponse)
    {
        if (matchListResponse.success && matchListResponse.matches != null)
        {
            matchMaker.JoinMatch(matchListResponse.matches[0].networkId, "", OnMatchJoined);
        }
    }

    public void OnMatchJoined(JoinMatchResponse matchJoin)
    {
        if (matchJoin.success)
        {
            DebugLog("Join match succeeded");
            if (_matchCreated)
            {
                DebugLog("Match already set up, aborting...", DebugLogType.Warning);
                return;
            }
            Utility.SetAccessTokenForNetwork(matchJoin.networkId, new NetworkAccessToken(matchJoin.accessTokenString));

//            NetworkClient myClient = new NetworkClient();
//            myClient.Connect(new MatchInfo(matchJoin));
            NetworkClient myClient = StartClient(new MatchInfo(matchJoin));
            myClient.RegisterHandler(MsgType.Connect, OnConnected);
            DebugLog("Start client called.");
        }
        else
        {
            DebugLog("Join match failed", DebugLogType.Error);
        }
    }

    // called when connected to a server
    public override void OnClientConnect(NetworkConnection conn)
    {
        base.OnClientConnect(conn);
        DebugLog("ClientScene.AddPlayer called");
    }
   
    // called when disconnected from a server
    public override void OnClientDisconnect(NetworkConnection conn)
    {
        StopClient();
    }
   
    // called when a network error occurs
    public override void OnClientError(NetworkConnection conn, int errorCode)
    {
        DebugLog("Client error: " + errorCode);
    }

    public void OnConnected(NetworkMessage msg)
    {
        DebugLog("Connected!");
    }
}

because you replaced the handler for the MsgType.Connect message?

Oh, I just grabbed that code from the Unity Manual, here: http://docs.unity3d.com/Manual/UNetMatchMaker.html

I didn’t think that would be a problem - since the parameters are different for OnClientConnect (takes a NetworkConnection) and OnConnected (takes a NetworkMessage), I figured OnClientConnect would be called automatically no matter what.

Is NetworkClient capable of automatically detecting what parameters the handler needs?

NetworkManager has two entry which called OnCllinetConnect
First

        internal void OnClientConnectInternal(NetworkMessage netMsg)
        {
            if (LogFilter.logDebug)
            {
                Debug.Log("NetworkManager:OnClientConnectInternal");
            }
            netMsg.conn.SetMaxDelay(this.m_MaxDelay);
            if (string.IsNullOrEmpty(this.m_OnlineScene) || this.m_OnlineScene == this.m_OfflineScene)
            {
                this.OnClientConnect(netMsg.conn);
            }
            else
            {
                NetworkManager.s_ClientReadyConnection = netMsg.conn;
            }
        }

In usual this won’t enter, because every body set a meaningful onlinescene

Second

        private void FinishLoadScene()
        {
            if (this.client != null)
            {
                if (NetworkManager.s_ClientReadyConnection != null)
                {
                    this.OnClientConnect(NetworkManager.s_ClientReadyConnection);
                    NetworkManager.s_ClientReadyConnection = null;
                }
            }
            else if (LogFilter.logDev)
            {
                Debug.Log("FinishLoadScene client is null");
            }
            if (NetworkServer.active)
            {
                NetworkServer.SpawnObjects();
                this.OnServerSceneChanged(NetworkManager.networkSceneName);
            }
            if (this.IsClientConnected() && this.client != null)
            {
                this.RegisterClientMessages(this.client);
                this.OnClientSceneChanged(this.client.connection);
            }
        }

If the first is not set, this second entry will be last chance you can enter. But there is a bug fix
in 5.2.2p1

  • (725363) - Networking: Fixed missing Connect callback for local client

maybe because you have added NetworkManager to gameobject instead of CustomNetworkManager?