2
\$\begingroup\$

In my Unity mobile game, I need multiplayer online functionalities. All the players should be visible in the world at any given time (of course, with some filtering), and a player should be able to connect at any time. Let's say that, for the purpose of this question, only 100 players at the time will log into the game.

My first try involved using Unity's built-in NetworkManager, but the two problems that arose are that:

  1. One player is always the host, meaning that if that player logs out all the other players.
  2. I did not manage to make it work on two different networks.

The implementation I used comes from this tutorial.

Next try was using an extension of NetworkLobbyManager, that allows through the Matchmaking system to solve problem 2.

This is my implementation:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Networking.Match;
using UnityEngine.SceneManagement;

public class AutoLobbyManager : NetworkLobbyManager {

    protected int currentPage = 0;
    protected int previousPage = 0;

    public void CreateOrJoin() {
        StartMatchMaker();
        RequestPage(0);
    }

    public void OnMatchListReceived(bool success, string extendedInfo, List<MatchInfoSnapshot> matches)
    {
        if (matches.Count == 0) {
            // Server does not exist yet. Create one.
            CreateMatch();
            return;
        } 

        // There is then a server. Join it.
        JoinMatch(matches[0]);


    }

    public void RequestPage(int page) {
        matchMaker.ListMatches(page, 1, "", true, 0, 0, OnMatchListReceived);
    }


    public void CreateMatch() {
        matchMaker.CreateMatch( "Main Match", (uint)maxPlayers, true, "", "", "", 0, 0, OnMatchCreate);
    }


    void JoinMatch(MatchInfoSnapshot match) {
        matchMaker.JoinMatch(match.networkId, "", "", "", 0, 0, OnMatchJoined);
    }


    public override void OnMatchCreate(bool success, string extendedInfo, MatchInfo matchInfo) {
        base.OnMatchCreate(success, extendedInfo, matchInfo);
        Debug.Log("Match created!");
        ServerChangeScene(playScene);
    }

     public override void OnClientSceneChanged(NetworkConnection conn) {
         string loadedSceneName = SceneManager.GetSceneAt(0).name;
         if (loadedSceneName == lobbyScene) {
           if (client.isConnected)
               CallOnClientEnterLobby();
         } else {
           CallOnClientExitLobby();
         }

         OnLobbyClientSceneChanged(conn);
    }

    void CallOnClientEnterLobby() {
        OnLobbyClientEnter();
        foreach (var player in lobbySlots)
        {
            if (player == null)
                continue;

            player.readyToBegin = false;
            player.OnClientEnterLobby();
        }
    }

    void CallOnClientExitLobby() {
        OnLobbyClientExit();
        foreach (var player in lobbySlots)
        {
            if (player == null)
                continue;

            player.OnClientExitLobby();
        }
    }

}

This makes possible to create a Lobby if there is no Lobby, and join the first if there is. It works, if we remove the highlighted line here:

public override void OnMatchCreate(bool success, string extendedInfo, 
MatchInfo matchInfo) {
    base.OnMatchCreate(success, extendedInfo, matchInfo);
    Debug.Log("Match created!");
    ***** ServerChangeScene(playScene); *****
}

Because this starts the game. If that line is activated (since I want to start the game as soon as possible), when a client tries to connect, the Server logs:

NetworkLobbyManager can't accept new connection [hostId: 0 connectionId: 1 isReady: False channel count: 2], not in lobby and game already in progress.

And the client is not added to the game. I understand that lobbies usually work like that, but:

1. Is it possible to add a client after a game is added, with NetworkLobbyManager?

2. Is it the right approach to achieve a multiplayer, non-lobby-based, non-host-based, online game in Unity?

\$\endgroup\$
1
+50
\$\begingroup\$

First and foremost no, you may not add players to an already started game with lobbies because they were designed to host short term games with a set number of players. Because of the rigid structur they can simplify the code they use, but as you noticed it does restrict its use a fair bit.

I would suggest looking into the parent class of the network lobby manager, the network manager, directly as it seems to have all the pieces needed for you to make a system of the type you desire, although it may require a bit more work.

That being said the unity asset store is wide and I would not be surprised to hear that there is a premade system that works the way you intend.

\$\endgroup\$
  • 1
    \$\begingroup\$ Thanks for your answer! I ended up making a son class of NetworkManager, borrowing a few features from the Matchmaker's system. I will eventually look into the asset store for a more professional solution. \$\endgroup\$ – Simone Chelo Aug 22 '18 at 10:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.