Multiplayer Lobby (Lobby Multi-jugador)
Host Migration (Migración de anfitrión)

Network Clients (clientes de red) y Servers (servidores)

Muchos juegos multijugador serán capaces de utilizar el NetworkManager para manejar las conexiones, pero todavía es posible utilizar unas clases directamente de un nivel menor como lo son NetworkServer y NetworkClient.

Cuando se utilice el HLAPI, cada juego debe tener un servidor que aloje el juego. Entonces cada participante en un juego multi-jugador puede ser un cliente, un servidor dedicado, o una comunicación de un servidor y un cliente al mismo tiempo. Este rol de combinación es un caso común de un juego multi-jugador sin un servidor dedicado.

Para los juegos multi-jugador sin servidores dedicados, uno de los juegos ejecutando el juego actúa como un “Servidor” para el juego. En esa instancia en particular del jugador del juego, esta estaría ejecutando un “Local Client” (cliente local) en vez de un cliente normal remoto. El cliente local utiliza las mismas escenas de Unity y objetos como el servidor, y se comunica internamente utilizando colas de mensajes en vez de enviar mensajes a través de la red. Pero, para el código HLAPI y los sistemas, el cliente local es simplemente otro cliente, por lo que todo el código de usuario es casi el mismo sin importar si un cliente es local o remoto. Esto hace que sea fácil que un juego funcione en modo multi-jugador y stand-alone con el mismo código.

Un patrón común para juegos multi-jugador es tener un objeto que maneja el estado de red del juego. Abajo hay el inicio de un script de un NetworkManager. Este script estaría adjunto a un game object que esté en la escena inicial del juego. Tiene una UI y funciones del manejo de teclado simples que permiten que el juego empiece en diferentes modos de network (red). Para un juego real, este podría ser un menú más llamativo con opciones como “Start Single Player Game” (empezar un juego de un solo jugador) and “Start Multiplayer Game” (empezar un juego multi-jugador).

using UnityEngine;
using UnityEngine.Networking;

public class MyNetworkManager : MonoBehaviour {
    
    public bool isAtStartup = true;
    
    NetworkClient myClient;

    void Update () 
    {
        if (isAtStartup)
        {
            if (Input.GetKeyDown(KeyCode.S))
            {
                SetupServer();
            }
            
            if (Input.GetKeyDown(KeyCode.C))
            {
                SetupClient();
            }
            
            if (Input.GetKeyDown(KeyCode.B))
            {
                SetupServer();
                SetupLocalClient();
            }
        }
    }
    
    void OnGUI()
    {
        if (isAtStartup)
        {
            GUI.Label(new Rect(2, 10, 150, 100), "Press S for server");     
            GUI.Label(new Rect(2, 30, 150, 100), "Press B for both");       
            GUI.Label(new Rect(2, 50, 150, 100), "Press C for client");
        }
    }   
}

Este esqueleto de código llama funciones de configuración para empiecen las cosas. Abajo hay funciones de configuración simple para cada uno de los escenarios. Estas funciones crean un servidor, o el tipo de cliente adecuado para cada escenario. Tenga en cuenta que el cliente remoto asume que el servidor está en la misma maquina (127.0.0.1), para un juego real esto esto sería direcciones IP conocidas o algo proporcionado por el sistema de Match Making.

    // Create a server and listen on a port
    public void SetupServer()
    {
        NetworkServer.Listen(4444);
        isAtStartup = false;
    }
    
    // Create a client and connect to the server port
    public void SetupClient()
    {
        myClient = new NetworkClient();
        myClient.RegisterHandler(MsgType.Connect, OnConnected);     
        myClient.Connect("127.0.0.1", 4444);
        isAtStartup = false;
    }
    
    // Create a local client and connect to the local server
    public void SetupLocalClient()
    {
        myClient = ClientScene.ConnectLocalServer();
        myClient.RegisterHandler(MsgType.Connect, OnConnected);     
        isAtStartup = false;
    }

Los clientes en este código registran una función callback para el evento de conexión MsgType.Connect. Este es un mensaje integrado del HLAPI que se invoca cuando un cliente se conecta al servidor. En este caso, el código para el manejador en el cliente es:

    // client function
    public void OnConnected(NetworkMessage netMsg)
    {
        Debug.Log("Connected to server");
    }

Esto es suficiente para poner en marcha una aplicación multi-jugador. Ahora sería posible enviar mensajes en red utilizando NetworkClient.Send and NetworkServer.SendToAll, sin embargo, enviar mensajes es una manera de interactuar con el sistema de bajo nivel.

Multiplayer Lobby (Lobby Multi-jugador)
Host Migration (Migración de anfitrión)