Resumen rápido
- →Un juego online no es "dos juegos conectados": hay que sincronizar el estado entre computadoras mandando paquetes livianos.
- →En Unity, la opción oficial para empezar es Netcode for GameObjects (NGO).
- →La base son 4 piezas: NetworkManager, NetworkObject, NetworkBehaviour con
IsOwnery NetworkTransform. - →Para acciones como disparar se usan RPCs: el cliente le pide al servidor (ServerRpc) y el servidor avisa a todos (ClientRpc).
Hacer un juego multijugador es de las cosas que más se piden y de las que más asustan. La buena noticia es que la base se entiende en una tarde: qué hay que sincronizar, quién controla qué y cómo se mandan los mensajes. Lo difícil viene después, y se construye sobre esto.
Esta guía resume el primer tramo del curso Multijugador en Unity de Codearte, donde se arma un shooter top down online de punta a punta. Al final vas a tener dos jugadores moviéndose y disparando en red.
Qué cambia cuando un juego es online
En un juego single player la computadora decide todo: apretaste espacio, el personaje salta. En un multijugador local (dos joysticks, una PC) tampoco hay mucho problema: si dos disparan, el que apretó primero dispara primero.
En un multijugador online hay dos computadoras, cada una con su pantalla y su joystick. Y aparecen las preguntas difíciles: si los dos disparan al mismo tiempo, ¿quién disparó primero? ¿Quién decide dónde está cada jugador? ¿Quién decide si el disparo pegó?
Sincronización y paquetes
La solución más simple: cada jugador controla solo su personaje y le avisa a la otra computadora lo que hizo (me moví, salté, disparé). Esos avisos viajan en paquetes, unidades de datos con la información mínima para que todos vean lo mismo.
- Estado del jugador: su posición (
Vector3) y su vida (int). Cuatro números, nada más. El modelo 3D no se manda: la otra PC ya lo tiene. - Un pedido: "quiero comprar tal ítem".
- Un evento del servidor: "empezó la partida".
La regla de oro
El estado del juego tiene que ser idéntico en todas las máquinas. Pensá en un ajedrez online donde vos ves tus piezas en un lugar y tu rival las ve en otro: no se puede jugar. Y los paquetes tienen que ser livianos, porque se mandan constantemente.
Ese iconito de conexión que aparece en Rocket League o Call of Duty cuando todo se traba es justamente eso: paquetes que no están llegando.
Qué usar en Unity: Netcode for GameObjects
Unity tuvo su propia solución, UNET, que quedó deprecada. Hoy hay varias opciones:
| Opción | Qué es | Cuándo |
|---|---|---|
| Netcode for GameObjects | La solución oficial de Unity, con GameObjects comunes | La mayoría de los juegos, hasta unas decenas de jugadores |
| Netcode for Entities | La oficial para DOTS/ECS | Muchos jugadores simultáneos, tipo battle royale |
| Mirror, FishNet | Frameworks de la comunidad | Si ya los conocés o necesitás algo puntual |
| Photon | Servicio de terceros | Rápido de arrancar, pero dependés de sus planes y límites |
En el curso se usa Netcode for GameObjects (NGO): es oficial, se integra con los servicios de Unity Gaming Services como Relay y Lobby, y lo que aprendés se transfiere a cualquier otro framework.
Paso a paso: dos jugadores en red
Instalá NGO y creá el NetworkManager
Desde el Package Manager instalá Netcode for GameObjects. Después creá un GameObject vacío con el componente NetworkManager y elegí Unity Transport como transporte. Es el cerebro de la conexión: existe una sola vez y maneja quién está conectado.
Marcá al jugador como objeto de red
Al prefab del jugador agregale un NetworkObject. Eso le da un ID único y le dice al NetworkManager "yo me tengo que sincronizar". Después asignalo como Default Player Prefab en el NetworkManager y verificá que esté en la lista de Network Prefabs.
Solo van en esa lista los objetos que se sincronizan: jugadores, balas, power-ups. Una caja decorativa no.
Cambiá MonoBehaviour por NetworkBehaviour y usá IsOwner
Este es el error número uno. En tu PC hay dos jugadores, y los dos tienen su script con su Update. Si no hacés nada, tu teclado mueve a los dos. Hay que decirle a cada copia: si este jugador no es mío, no hagas nada.
using Unity.Netcode;
using UnityEngine;
public class PlayerController : NetworkBehaviour
{
public float speed = 5f;
public override void OnNetworkSpawn()
{
// Reemplaza al Start: se llama cuando el objeto aparece para todos
}
void Update()
{
if (!IsOwner) return;
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");
transform.position += new Vector3(x, 0, z) * speed * Time.deltaTime;
}
}IsOwner es true solo en la computadora del jugador que creó ese objeto. En todas las demás es false.
Botones de Host y Join
using Unity.Netcode;
using UnityEngine;
using UnityEngine.SceneManagement;
public class Menu : MonoBehaviour
{
public void Host()
{
NetworkManager.Singleton.StartHost();
NetworkManager.Singleton.SceneManager.LoadScene("Game", LoadSceneMode.Single);
}
public void Join()
{
NetworkManager.Singleton.StartClient();
}
}StartHostcrea una sesión nueva.StartClientse une a una existente.- La escena la carga el NetworkManager, no el
SceneManagerde siempre. Así, el que se une aparece automáticamente en la misma escena que el host (requiere Enable Scene Management prendido). NetworkManager.Singletones un acceso global al único NetworkManager de la escena.
Sincronizá la posición con NetworkTransform
Hasta acá cada uno se mueve en su pantalla, pero el otro no lo ve. Agregale un NetworkTransform al jugador y ahorrá ancho de banda: en un top down no hace falta sincronizar la posición Y, ni la rotación en X y Z, ni la escala.
Authority Mode del NetworkTransform está en Server, así que solo el servidor puede mover objetos. Para que cada jugador mueva el suyo, ponelo en Owner. Qué conviene en cada caso es todo un tema: la autoridad.Disparar con RPCs
Una bala no es como la posición, que cambia todo el tiempo: es un evento puntual. Para eso están los RPCs (Remote Procedure Calls), funciones que se ejecutan en otra computadora.
void Update()
{
if (!IsOwner) return;
if (Input.GetMouseButtonDown(0))
ShootServerRpc(firePoint.position, firePoint.forward);
}
[ServerRpc]
void ShootServerRpc(Vector3 position, Vector3 direction)
{
// Solo corre en el servidor
Quaternion rotation = Quaternion.LookRotation(direction);
GameObject bullet = Instantiate(bulletPrefab, position, rotation);
bullet.GetComponent<NetworkObject>().Spawn();
ShootClientRpc();
}
[ClientRpc]
void ShootClientRpc()
{
// Corre en todos los clientes (el host también es cliente)
muzzleFlash.Play();
shootSound.Play();
}- El cliente pide disparar con un
ServerRpc, mandando solo posición y dirección. - El servidor crea la bala y la replica con
NetworkObject.Spawn(). - Los efectos (sonido, fogonazo) son visuales: van en un
ClientRpcpara que todos los vean. - Los nombres tienen que terminar en
ServerRpcyClientRpc, si no NGO tira error.
[Rpc(SendTo.Server)]. Los [ServerRpc] y [ClientRpc] siguen funcionando y son los más fáciles para entender la idea.Cómo probarlo con dos ventanas
Con un solo Unity abierto no tenés con quién conectarte. La forma más simple: en Project Settings, Player, Resolution, prendé Run In Background y poné el modo de pantalla en ventana. Hacé un build, abrilo dos veces, y en una apretá Host y en la otra Join.
Qué sigue después de esto
NetworkVariable
Para estado que tiene que estar igual en todos: vida, puntos, listo o no listo.
Autoridad
Qué decide el servidor y qué el cliente, para evitar trampas.
Relay y Lobby
Para jugar por internet sin abrir puertos y armar salas.
Latencia
Ping, interpolación y técnicas para que el lag no se note.
Para jugar con amigos fuera de tu red ya tenemos la guía de cómo implementar Relay en Unity, y para hablar mientras juegan, la de voice chat en Unity.
Preguntas frecuentes
¿Cómo se hace un juego multijugador en Unity?
Con un framework de red como Netcode for GameObjects: un NetworkManager que maneja la conexión, NetworkObject en todo lo que se sincroniza, NetworkBehaviour con IsOwner para que cada jugador controle solo el suyo, NetworkTransform para la posición y RPCs para acciones como disparar.
¿Qué es Netcode for GameObjects?
Es la librería oficial de Unity para multijugador con GameObjects. Se instala desde el Package Manager y se integra con Unity Gaming Services, como Relay y Lobby.
¿Por qué mi teclado mueve a los dos jugadores?
Porque el Update corre en todas las copias del jugador. Hay que heredar de NetworkBehaviour y cortar con if (!IsOwner) return; al principio del Update.
¿Qué diferencia hay entre StartHost y StartClient?
StartHost crea una sesión nueva donde esa computadora es servidor y jugador a la vez. StartClient se une a una sesión que ya existe.
¿Qué es un RPC en Unity?
Una función que se ejecuta en otra computadora. Un ServerRpc lo llama un cliente y corre en el servidor. Un ClientRpc lo llama el servidor y corre en todos los clientes.
Guías relacionadas
Hacé tu propio shooter online
En el curso Multijugador de Codearte armás un juego online completo con Netcode for GameObjects: sincronización, vida, kills, leaderboard, Relay, Lobby y optimización de red.
Ver el curso Multijugador¿Quieres crear tus propios juegos?
Aprende a programar videojuegos desde cero con nuestros cursos en Unity. Más de 3,000 estudiantes ya empezaron su camino.
Ver cursos gratuitos


