Unity Mirror を使ってサーバーをDedicatedServerで動かした際の、サーバー側でClientRPCを実行する方法


この内容、Unityもマルチプレイヤーゲーム開発も不慣れな状態で書いたので一般常識レベルだったらすんません…
調べても見つからなかったので…(´・ω・`)

概要

  • Mirrorでマルチプレイヤーゲームを作る
  • サーバーはHost ServerではなくDedicated Serverで作る
  • このようなときに、サーバー側で ClientRPC を実行するにはどうするか?

サーバー側で ClientRPC を実行する際の問題点

  1. サーバー側では、 NetworkClient.connection.identity.GetComponent<T>(); という手法は使えない
    1. Deicated Serverとして動かしてるから、クライアントなんてあるわけがない…
    2. クライアントがないから、 ClientRPC を実行できる NetworkBehaviour コンポーネントも工夫しないととってこれない
  2. そもそも論として、 ClientRPC ってクライアント側じゃないと実行できない
    1. ここClientRpc calls are sent from objects on the server to objects on clients. とあるように、クライアント上で実行する前提の仕組みだし。

実行方法

実行方法の概要

任意の有効なクライアントのコネクションは、

サーバー側では NetworkConnectionToClient プロパティで、全クライアントのコネクションオブジェクトにアクセスできる

ということだから、

  • NetworkConnectionToClient から、任意の有効なクライアントのコネクションを使って NetworkBehaviour をとってくればいい

という考えで実行する方法です。

実行例

※疑似コードなのでこのままでは使えません

NetworkPlayer.cs

using Mirror;
using UnityEngine;
using System;

public class NetworkPlayer : NetworkBehaviour
{
    [ClientRpc]
    public void RpcSayHello()
    {
        Debug.Log("Hello!");
    }
}

GameMain.cs

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Mirror;

public class GameMain : MonoBehaviour
{
    private void Update()
    {
        // なんでもいいので有効なネットワーククライアントを手に入れる
        foreach (KeyValuePair<int, NetworkConnectionToClient> kvp in NetworkServer.connections)
        {
            NetworkPlayer networkPlayer = kvp.Value.identity.GetComponent<NetworkPlayer>();
            networkPlayer.RpcSayHello();
            break;
        }
    }
}

備考

このようなときに、サーバー側で ClientRPC を実行するにはどうするか?

「そもそも、そんな回りくどいことしないでメッセージングしろ」と言う場合は、 この辺 をどうぞ。