RPC - 基礎
レプリケーションが処理するのは、時間と共に変化する「継続的な状態」(位置・体力・スコアなど)です。しかし、ゲームには「一度きりのイベント」(武器の射撃・チャットメッセージの送信・スキルの発動など)も必要です。リモートプロシージャコール(RPC)を使用して、他のクライアント上で関数を呼び出すと、これらのイベントをトリガーできます。
RPCは一度だけ配信され、サーバーには保存されません。そのため、RPCが送信された後に参加したプレイヤーにはRPCは届きません。一時的なアクションには最適ですが、途中参加者にも影響を与えるものには不向きなので、そういった場合はプロパティを複製してください。
概要
すべてのRPCはFusionから送信できます。受信関数はGodot標準の@rpcアノテーションを使用します。
Fusionは呼び出される関数を所有するノードに基づいて、配信方式を自動的に選択します:
- 子ノードに複製ノード(
FusionsharedReplicator/FusionServerReplicator)が存在する場合、リモートクライアント上の対応するネットワークオブジェクトに対して呼び出しが配信されます。これはオブジェクト対象(Object-Targeted)RPCです。 - そうでない場合、呼び出しはブロードキャストレシーバーとして登録済みのノードに送信されます。これはブロードキャスト(Broadcast)RPCです。
標準的なパターンや実用的な例については、RPCの使用例をご覧ください。
3つの呼び出し形式
呼び出しを受信する対象に合わせて、適切な形式を選択してください。全員にはrpc()、特定ロールや特別な対象にはrpc_to()、特定プレイヤー1人にはrpc_to_player()を使用します。
rpc() - 全員に送信
GDScript
Fusion.rpc(my_method, arg1, arg2)
すべてのピアに送信します(rpc_to(FusionClient.TARGET_ALL, ...)と同等です)。
rpc_to() - 列挙型の指定対象に送信
GDScript
Fusion.rpc_to(Fusion.TARGET_MASTER, my_method, arg1)
Fusion.rpc_to(Fusion.TARGET_OWNER, my_method, arg1) # オブジェクト対象RPCのみ
第一引数はFusion.RpcTarget列挙型の値(後述)です。
rpc_to_player() - 特定プレイヤーに送信
GDScript
Fusion.rpc_to_player(player_id, my_method, arg1, arg2)
数値のID(0より大きい値が必須)を指定して、特定プレイヤーを対象にします。
RpcTarget列挙型
すべてFusionの定数です:
| 定数 | 説明 |
|---|---|
TARGET_ALL |
すべてのピア(デフォルト) |
TARGET_MASTER |
マスタークライアントのみ - Photonからルームホストとして指定されたプレイヤー |
TARGET_OWNER |
オブジェクト所有者のみ - オブジェクト対象RPCのみ(ブロードキャストRPCは所有者がいないため拒否される) |
カスタムPhotonプラグインでの高度なサーバーサイドスクリプティング用にTARGET_PLUGINも用意されていますが、ほとんどのゲームで必要になることはありません。
オブジェクト対象RPC
オブジェクト対象RPCは、クライアント間で特定のネットワークオブジェクトのメソッドを呼び出します。メソッドは、複製ノードを子ノードに持つノードに属している必要があります。Fusionはその複製ノードを使用して、他すべてのクライアント上の対応するオブジェクトでの呼び出しをルーティングします。
GDScript
@rpc("any_peer", "call_local") # any_peer:どのクライアントも送信可能、call_local:送信元のローカルでも実行
func take_damage(amount: int):
health -= amount
func attack():
# take_damegeがこのノードのメソッドにあり、このノードの子ノードに複製ノードがあるため、
# Fusionはリモートクライアント上の複製ノードを経由して呼び出しをルーティングする
Fusion.rpc(take_damage, 10)
# ルーティングは同様だが、オブジェクト所有者のみに配信される
Fusion.rpc_to(Fusion.TARGET_OWNER, take_damage, 10)
ブロードキャストRPC
ブロードキャストRPCは、特定のネットワークオブジェクトを対象にせずに、すべてのクライアントにメッセージを配信します。まずブロードキャストレシーバー(受信したブロードキャスト呼び出しを処理する任意のノード)を登録した後にFusionから送信します。
GDScript
func _ready():
Fusion.register_broadcast_receiver(self)
func _exit_tree():
if Fusion:
Fusion.unregister_broadcast_receiver(self)
@rpc("any_peer", "call_local")
func chat_message(sender: String, text: String):
print("[%s]: %s" % [sender, text])
func send_chat(text: String):
Fusion.rpc(chat_message, local_player_name, text)
必ず_exit_tree()でブロードキャストレシーバーの登録を解除してください。登録したノードを登録解除せずに解放すると、Fusionは参照を保持したままになり、次のブロードキャストRPCが到着した際にクラッシュします。
@rpcアノテーション
Godotの@rpcアノテーションによって、送信を許可する対象・呼び出す関数が送信元のローカルで実行されるかどうかを設定できます。
GDScript
@rpc("any_peer", "call_local") # どのピアでも送信可能、ローカルで実行される
@rpc("authority") # 権限者のみ送信可能(デフォルト)
@rpc("any_peer", "call_remote") # どのピアでも送信可能、リモートでのみ実行される
- Mode:
"authority"は送信前にhas_authority()をチェックします(送信元に権限がない場合は黙って破棄されます)。"any_peer"は誰でも送信が許可されます。 - Sync:
"call_remote"(デフォルト)はリモートにのみ送信されます。"call_local"は送信直後に送信元でも実行されます。コード分岐せずに、即座にローカルでフィードバックを得たい場合に便利です。
共有権限型において、オブジェクトの「権限」は、オブジェクトを所有するクライアントが持ちます。所有者の割り当てや移行については、所有権モードをご覧ください。
サポートする引数の型
FusionのRPCは、ほとんどのGodot組み込み型に加え、ネットワークオブジェクトのノード参照をサポートしています:
bool,int,float,StringVector2,Vector3,Vector4,Quaternion,ColorPackedByteArray,Array,Dictionary- ネットワーク
Node参照(ネットワーク伝送用に自動的にエンコードされる)
RPCが到着する前にオブジェクトがデスポーンした場合、受信時にNode参照がnullになることがあります。Node参照を使用する前は、常にnullチェックを行ってください。
次のステップ
標準的なパターンや実用的な例については、RPCの使用例をご覧ください。
Back to top