Openbracket / a tj gillis braindump

Mirror-Networking Character Creator

2023-11-13

I am working on a little multiplayer Unity game and decided to use Mirror Networking for handling the server and communication. In this post I’m going to outline how I use Mirror to build a simple Character Builder and syncing that between clients.

Mirror Concept Breakdown

We’re going to leverage the NetworkRoomManger for our game. The NetworkRoomManager handles the flow of a player connecting or becoming the host, create a room, ensure players are ready, transitioning to the game scene, creating your character prefab and along the way offering hooks for customing the different steps.

As you can see, NetworkRoomManager does a lot for us and only asks for a few objects to be configured in return; An offline scene, an online, your transport, a player prefab, a room player prefab, a room scene and a game scene.

Example:

NetworkRoomManagerExt Config

Let’s break these requirements down

Planning

Now that we understand that Mirror is looking for let’s at what we need to accomplish our character builder

Set Up

With that all thunk through, the actual implementation is pretty straightforward

Create Game Scene

Nothing special needs to happen in this scene

Create Lobby Scene

The lobby scene is also our Online, Character Builder and Room scene.

LobbyController.cs

// We fire off this trio of Commands (Commands are messages from client to server) 
// when we click our ready button
roomPlayer.CmdUpdateCharacterModelIndex(modelIndex);
roomPlayer.CmdUpdateWeaponModelIndex(weaponIndex);
roomPlayer.CmdChangeReadyState(true);
                

Create Player Controller

Aattach to your Player Prefab.

PlayerController.cs

// Within Start function we get a reference to our PlayerSyncVO which at this point has
// been filled with the data from RoomPlayer
PlayerSyncVO roomPlayer = GetComponent<PlayerSyncVO>();
characerModelController.LoadCharacterModel(roomPlayer.CharacterModelIndex);
hammerHead = await characerModelController.LoadWeaponModel(roomPlayer.WeaponModelIndex);

Create Player Sync VO

Attach to Player Prefab.

PlayerSyncVO

using Mirror;

public class PlayerSyncVO : NetworkBehaviour
{
    [SyncVar]
    public int CharacterModelIndex;
    [SyncVar]
    public int WeaponModelIndex;
    [SyncVar]
    public bool IsWhacker;
}

Create Characrter Model Controller

This is what does the heavy lifting of conveting the synced indexes to prefabs. It’s outside of the scope of this post as it don’t include any networking code but personally I just use addressables to store my prefabs and in this class convert the indexes to paths names to load the proper prefab.

Create MainMenu Scene

Create NetworkRoomManagerExt, add to an object in scene and accosicate all the above elements to it.

NetworkRoomManagerExt.cs

using UnityEngine;
using Mirror;

public class NetworkRoomManagerExt : NetworkRoomManager
{
    public override bool OnRoomServerSceneLoadedForPlayer(NetworkConnectionToClient conn, GameObject roomPlayer, GameObject gamePlayer)
    {
        NetworkRoomPlayerExt serverRoomPlayer = roomPlayer.GetComponent<NetworkRoomPlayerExt>();
        PlayerSyncVO roomPlayerVO = gamePlayer.GetComponent<PlayerSyncVO>();
        if (serverRoomPlayer.isServer && serverRoomPlayer.isLocalPlayer)
        {
            roomPlayerVO.IsWhacker = true;
        }

        roomPlayerVO.CharacterModelIndex = serverRoomPlayer.CharacterModelIndex;
        roomPlayerVO.WeaponModelIndex = serverRoomPlayer.WeaponModelIndex;
        return base.OnRoomServerSceneLoadedForPlayer(conn, roomPlayer, gamePlayer);
    }
}

Create UI

This is just two input field and a button and is connected to MainMenuController.

public void CreateHost()
{
    NetworkManager.singleton.StartHost();
}

public void JoinHost()
{
    NetworkManager.singleton.networkAddress = hostURL.text;
    NetworkManager.singleton.StartClient();
}

Conclusion

With only a little code we were able to pretty easily setup a sync multiplayer character builder. This is just a simple example but could easily be scaled up to handle more complex character creations.