オブジェクトのオーナーシップ
はじめに
VRChatでは、すべてのネットワーク化されたGameObjectにオーナーが存在します。オーナーシップは、どのプレイヤーがそのネットワークオブジェクトを変更・更新できるかを決定します。インスタンス内の全プレイヤー間でオブジェクトを適切に同期するには、オーナーシップの理解と管理が不可欠です。
オーナーシップの仕組み
- インスタンスに最初に参加したプレイヤーが、デフォルトですべてのネットワークオブジェクトのオーナーになります。
- オーナーシップは、プレイヤー間で動的に転送できます。
- ネットワークオブジェクトのオーナーのみが、同期されたUdon変数を変更できます。
- オーナーがインスタンスから退出した場合、VRChatは自動的に新しいオーナーを割り当てます。
オーナーシップの転送
Udonを使用してオブジェクトのオーナーシップを転送できます。
Networking.SetOwner(VRCPlayerApi player, GameObject obj);
例:オブジェクトのオーナーシップを変更する
プレイヤーがオブジェクトを操作した際に、そのプレイヤーにオーナーシップを取得させたい場合は以下のようにします。
public override void Interact()
{
Networking.SetOwner(Networking.LocalPlayer, gameObject);
}
この関数が実行されると、ローカルプレイヤーがそのオブジェクトの新しいオーナーになります。
オーナーシップに関するイベント
VRChatには、オーナーシップに関連する2つの主要なイベントがあります。
OnOwnershipRequest
このイベントはオーナーシップが転送される前に呼び出され、リクエストを承認または拒否することができます。
public override bool OnOwnershipRequest(VRCPlayerApi requestingPlayer, VRCPlayerApi newOwner)
{
return true; // Approve transfer
}
OnOwnershipTransferred
オブジェクトの所有権が変更されたときに発生します。これを使用して、所有権が移行した際のUI要素やその他の動作を更新できます。
public override void OnOwnershipTransferred(VRCPlayerApi newOwner)
{
Debug.Log($"New owner: {newOwner.displayName}");
}
Transfer Eventsのダイアグラム
この画像はイベントの順序を示しており、オブジェクトの所有権を正常に転送する手順を理解するのに役立ちます。
Instance Master
Instance Masterとは、手動で所有権が設定または転送されていないすべてのオブジェクトを所有するプレイヤーのことです。あるプレイヤーがMasterであるかどうかは、VRCPlayerApi.isMasterで確認できます。
プレイヤーがInstance Masterであるかどうかを、ワールドの特定の機能へのアクセスを制限する方法として使用してはいけません。そのためには、代わりに「instance owner」の使用を検討してください。
Masterプレイヤーの選出には以下のルールが適用されます:
- インスタンス内には必ず有効なMasterプレイヤーが存在します。
- 誰もいないインスタンスに最初に入室したプレイヤーが、最初のMasterとなります。
- 現在のMasterがインスタンスから退出すると、Masterプレイヤーが変更されます。
- Android版VRChatを使用しており、バックグラウンド状態が長時間続いた場合も、Masterプレイヤーが変更される可能性があります。
- 現在のMasterが退出した際、
OnPlayerLeftが呼び出される前に、インスタンス内の他のプレイヤーから新しいMasterが選出されます。 - 特定のプレイヤーがMasterになることを前提にしてはいけません。新しいMasterプレイヤーは、サーバー側でさまざまな基準(プラットフォーム、ネットワーク状況など)に基づいて選出されます。
これらが、VRChatが現在保証しているネットワークMasterの挙動のすべてです。これ以外の挙動が観測されたとしても、将来的に変更される可能性があります。
可能な限り、インスタンスのMasterを確認するのではなく、所有権の確認をネットワーキングのロジックに使用することを推奨します。 Masterプレイヤーが一時的に応答しなくなるシナリオがあり、その間はイベントが実行されない可能性があります。
ベストプラクティス
- プレイヤーにオブジェクトの変数を変更させたい場合は、最初に所有権を確認するか、要求するようにしてください。
- 所有権に関連するロジックが、player disconnects(プレイヤーの切断)や late joiners(途中参加者)を考慮していることを確認してください。
- 可能であれば Instance Master に依存することは避け、代わりに適切な所有権の取り扱いを使用してください。
次のステップ
詳細については、以下のネットワーク関連トピックを確認してください:
最終更新: