こんにちは、ちゃらいプログラマです。
Unity Lobby/Relayの最後はRPC送受信周りになります。
※前回の記事はこちら
Unity Lobby/Relay入門 (#1) - アヒルのある日
Unity Lobby/Relay入門 (#2) - アヒルのある日
実装としては、#1で用意していた
public class NetworkObjectBehaviour : NetworkBehaviour { }
を使用します。
ただ、このままだとNetworkObjectBehaviourを使用する手段がないので、#2で用意した「MultiGameManagerクラス」に「NetworkObjectBehaviour」のアクセサを定義します。
private NetworkObjectBehaviour m_networkObject = null; public NetworkObjectBehaviour GetNetworkObject() { // Relayネットワークから切断するとnullになります。 // エラー処理は別途必要です。 return m_networkObject ; } public void SetNetworkObject(NetworkObjectBehaviour networkObject) { m_networkObject = networkObject; }
では、RPC周りを実装していきます。
public class NetworkObjectBehaviour : NetworkBehaviour { // Startで処理しているのはNetworkManager(Unity用意)の生成処理を待つ必要があるためです public void Start() { // NetworkObjectBehaviourはRelayネットワークに接続された人数分生成されます // IsOwner()で自分自身かどうかを判定できるので、自身の場合に設定しておきます if(IsOwner()) { MultiGameManager.Instance.SetNetworkObject(this); } } // RelayネットワークでのRPCルールについて // ホスト管理方式を採用しているため、ホスト以外のプレイヤーはホスト経由で送受信する必要があります // 受信側の関数に以下の属性を付与します // [Unity.Netcode.ClientRpc] // クライアントで実行されるようになります // 関数の末尾に【Rpc】を付与しないとエラーになります // [Unity.Netcode.ServerRpc( RequireOwnership = false )] // ホストで実行されるようになります // RequireOwnershipはfalseにしていないと自身の所有権のみしか操作できないのでfalseにしておきましょう // 関数の末尾に【Rpc】を付与しないとエラーになります // ケース1:ホストから全員(ホスト含む)に送信する // [Unity.Netcode.ClientRpc]属性の関数を用意します // ホストもクライアント判定のため同関数が実行されます public void SendStart() { // ホストのみ実行するように判定します // IsHostは用意されていますので使用させてもらいます if(IsHost) { ReceiveStartClientRpc(); } } [Unity.Netcode.ClientRpc] private void ReceiveStartClientRpc() { // ホスト、クライアント共に実行されます } // ケース2:クライアントからホストに送信する // [Unity.Netcode.ServerRpc]属性の関数を用意します public void SendClientToHost() { // クライアントのみで実行できるようにします if(!IsHost) { ReceiveClientToHostServerRpc(); } } [Unity.Netcode.ServerRpc( RequireOwnership = false )] private void ReceiveClientToHostServerRpc() { // ホストのみで処理するようにします if(IsHost) { // 処理を記述 } } // ケース3:自分自身以外に送信する // [Unity.Netcode.ClientRpc][Unity.Netcode.ServerRpc]属性の関数を用意します public void SendOther() { // ホストの場合はクライアントへ反映する if(IsHost) { ReceiveOtherClientRpc(); } // クライアントの場合はホスト経由で他クライアントへ反映する else { ReceiveOtherServerRpc(); } } [Unity.Netcode.ClientRpc] private void ReceiveOtherClientRpc() { // 自身の情報を反映しないように判定を追加します // IsLocalPlayerは用意されているので使用させてもらいます if(!IsLocalPlayer) { // 他クライアントの情報を反映する処理 } } [Unity.Netcode.ServerRpc( RequireOwnership = false )] private void ReceiveOtherServerRpc() { // ホストはクライアント関数をそのまま呼び出せばOKです ReceiveOtherClientRpc(); } }
実際にMultiGameManager経由で実行する場合は
MultiGameManager.Instance.GetNetworkObject().SendStart()
のようになります。
いかがでしたでしょうか。
実際に使用するとなると、【ホスト移譲】を実装する必要がありますがかなりややこしいので機会があれば…
個人的にはPhotonEngineで提供されている
Fusion2 のトポロジー:ホストモード
と同じだと感じました。
ではまた次回!