Skip to content

Latest commit

 

History

History
196 lines (161 loc) · 6.28 KB

unity-mirror-cheatsheet.md

File metadata and controls

196 lines (161 loc) · 6.28 KB

back to overwiev

Unity Mirror CheatSheet

Table of Contents

NetworkManager

Example:

public class MyNetworkManager : NetworkManager
{
    public override void OnClientConnect(NetworkConnection conn) // called on the client when it's connected to the server
    {
        base.OnClientConnect(conn);
        Debug.Log("I have connected to a server!");
    }

    public override void OnServerAddPlayer(NetworkConnection conn) // called on the server whenever a player object is added after a client connected
    {
        base.OnServerAddPlayer(conn);
        MyNetworkPlayer player = conn.identity.GetComponent<MyNetworkPlayer>(); // conn.identity is a reference to the player object that was created
        player.SetDisplayName($"Player {this.numPlayers}"); // i.e. run a script on the player in
        Debug.Log($"Connected: {this.numPlayers} Players"); // numPlayers holds a count of the amount of players
    }
}

NetworkBehaviour

Example:

public class MyNetworkPlayer : NetworkBehaviour
{
    public override void OnStartAuthority() // called only on the client that owns the object as soon as authority was given by the server
    {
        base.OnStartAuthority();
    }
    
    [ClientCallback] // makes sure that it's not run on the server
    private void Update()
    {
        if(!this.hasAuthority) return; // checks if the current client is the owner of the object
    }
}

SyncVars

Example:

public class MyNetworkPlayer : NetworkBehaviour
{
    [SyncVar] // syncs a variable from the server accross all clients
    [SerializeField] // show the variable in the editor
    private string displayName = "Missing Name";

    [Server] // only runs code on the server
    public void SetDisplayName(string newDisplayName)
    {
        Debug.Log(newDisplayName);
        displayName = newDisplayName;
    }
}

With hooks

    [SyncVar(hook=nameof(HandleDisplayNameUpdated))] // hook will call the specified method on the client every time the var is updated
    private string displayName = "Missing Name";

    private void HandleDisplayNameUpdated(string oldDisplayName, string newDisplayName)
    {
        Debug.Log(newDisplayName);
    }

Actions

Commands (clients calling a method on the server):

    [Command]
    private void CmdSetDisplayName(string newDisplayName) // this will only be executed on the server
    {
        SetDisplayName(newDisplayName);
    }
    
    [ContextMenu("SetMyName")] // this is not nescessary, it's to make the method available in the unity editor
    private void SetMyName()
    {
        CmdSetDisplayName("My New Name"); // this is executed on the client, it will tell the server to execute the command method on the server
    }
    

CleintRpc (server calling a method on all clients):

    [Command]
    private void CmdSetDisplayName(string newDisplayName) // executed on the server
    {
        SetDisplayName(newDisplayName);
        RpcLogName(newDisplayName); // method call
    }

    [ClientRpc]
    private void RpcLogName(string name) // this method will be called on all clients
    {
        Debug.Log($"The new name is: {name}");
    }

TargetRpc (server calling a method on a specific client (only owner if nothing is specified)):

[Command]
private void CmdSetDisplayName(string newDisplayName) // executed on the server
{
    SetDisplayName(newDisplayName);
    TargetRpcLogName(newDisplayName); // method call, implicitly passes in the connection that made the CMD call
}

[TargetRpc]
private void TargetRpcLogName(string name) // this method will be called on a specific client (since none is specified, it will implicitly be called on the client that initiated the CMD call)
{
    Debug.Log($"The new name is: {name}"); // will only be logged on the client that called the command
}

Server Authority

  • SyncVars have authority by default, only the server can change them and have them synced
  • Spawned player also has ownership authority by default. When spawning other objects it's important to tell Mirror who owns what.
  • The server should check the validity of each client command:
    [Command]
    private void CmdSetDisplayName(string newDisplayName) // executed on the server
    {
        if(newDisplayName.Length < 2) return;
        SetDisplayName(newDisplayName);
        RpcLogName(newDisplayName); // method call
    }

Network Transform

  • Use a component called NetworkTransform if you want to sync the transform attributes of that object across all clients.
  • It will automatically transpolate smoothly between the positions.

Spawning

// IPointerClickHandler is an interface. You can use it to have something happening when the user clicks the object it is attached to
// This is usually used for UI but we can also use it for game objects. You'll need to add an EventSystem to your Game and add a PhysicsRaycaster to your camera
public class UnitSpawner : NetworkBehaviour, IPointerClickHandler
{
    [SerializeField] private GameObject unitPrefab = null;
    [SerializeField] private Transform unitSpawnPoint = null;


    #region Server

    [Command]
    private void CmdSpawnUnit()
    {
        GameObject unitInstance = Instantiate(unitPrefab, unitSpawnPoint.position, unitSpawnPoint.rotation);
        // Spawn takes 2 arguments: 1st: the object instance, 2nd: the owner of the object (if empty, the server will be the owner)
        // connectionToClient is the connection that owns the object that called the command
        NetworkServer.Spawn(unitInstance, connectionToClient);
    }

    #endregion

    #region Client

    // this comes from IPointerClickHandler Interface
    public void OnPointerClick(PointerEventData eventData)
    {
        if(eventData.button != PointerEventData.InputButton.Left || !hasAuthority) return;
        CmdSpawnUnit();
    }

    #endregion
}

Useful

  • You can create sections in a class by using #region RegionName and #endregion
  • You can have a method being call-able from the unity editor by adding the [ContextMenu("Name")] decorator
  • Template strings in c# are $"Something {variable}"