RPCs - 使用例
RPCは、クライアント間で一時的なイベントをトリガーする仕組みです。ここで紹介するパターンはよく使用されるものです。このページは、RPC 基礎を理解していることを前提としています。
共有権限型でRPCが重要になる理由
クライアントごとに異なるオブジェクトを所有するため、オブジェクトの状態を横断的に変更するようなアクションは、所有者を必ず経由する必要があります。そのための手段がRPCで、主な対象は次の通りです:
TARGET_OWNER- 特定のネットワークオブジェクトの現在の所有者です。あるプレイヤーが別プレイヤー所有オブジェクトに影響を与える必要がある(ダメージを与える・バフを付与する・アイテムを渡す等)場合に使用してください。TARGET_MASTER- マスタークライアントです。マスタークライアントによって状態を同期したい(シーン変更リクエスト・ゲームモード変更など)場合に便利です。
所有者とマスタークライアントが同じクライアントとは限りません。マスタークライアントはルーム全体の調整を行いますが、各オブジェクトの所有権は複製ノードごとに設定されるため、どのクライアントにも属する可能性があります。所有権の割り当てや移行については、所有権モードをご覧ください。
例:相手にダメージを与える
シューティングゲームにおいて、射撃側は被弾側を所有していないため、被弾側のhealthに直接書き込むことはできません。そのかわりに、射撃側は被弾側の所有者にRPCを送信します。その所有者がローカルでダメージを適用すると、レプリケーションによって新しい値が他すべてのクライアントに伝搬されます。
GDScript
# 射撃側で弾の命中を検知した場合:
func _on_bullet_hit(target: Node):
# target.take_damageはCallableで、
# `target`は複製ノードを子に持ち、その複製ノード経由でルーティングされる
# TARGET_OWNERによって、`target`を現在所有しているクライアントに送信される
Fusion.rpc_to(Fusion.TARGET_OWNER, target.take_damage, 25)
GDScript
# 被弾側:
@rpc("any_peer", "call_local")
func take_damage(amount: int):
health -= amount
if health <= 0:
# 所有者上で死亡処理を行う(`health`の更新は自動的に複製される)
_die()
所有者が呼び出しを受信すると、healthプロパティの値の減少が複製され、次の同期時に新しい値が他すべてのクライアントに配信されます。
共通パターン
テキストチャット
チャットはブロードキャストRPCに最適です。あるクライアントが送信して全員が受信する仕組みで、途中参加者への対応は不要です。
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):
$ChatPanel.append_line("[%s]: %s" % [sender, text])
func send_chat(text: String):
Fusion.rpc(chat_message, local_player_name, text)
製品レベルのチャット機能をお探しの場合は、Photon Chatをご覧ください。これはPhotonの別製品で、互換性のあるサードパーティーサービスとの連携によって、AIモデレーションや単語フィルタリングなどの機能を備えています。
UIや単発エフェクト
一時的な効果(サウンド・爆発パーティクル・画面フラッシュ・トースト通知など)は、RPCに最適です。コード分岐せずに送信元でも効果を発生させたい場合は、@rpcアノテーション内で"call_local"を使用してください。
参考リンク
- RPC 基礎 - APIとルーティングのルール
- 所有権モード -
TARGET_OWNERの権限を割り当てる方法 - Photon Chat - マネージドチャットサービス