VRChat 非公式日本語ドキュメント

途中参加者と同期の問題

プレイヤーがVRChatのインスタンスに途中参加し、いくつかの同期変数が変更された後、そのプレイヤーはワールドの最新の状態に追いつく必要があります。このガイドでは、途中参加者にも一貫した同期されたワールド体験を提供する方法を解説します。

VRChatにおける途中参加者の処理方法

新しいプレイヤーがインスタンスに参加すると、VRChatは以下の処理を行います:

  • OnDeserializationイベントを通じて、最新のSynced Variableの値を送信します。
  • オブジェクトのオーナーを適切なプレイヤーに設定します。
  • イベントはreplayedされません

途中参加者に正しい状態を表示させるには

1. 状態の管理にはイベントではなくSynced Variableを使用する

イベントは一度しかトリガーされず永続しないため、途中参加者はイベントベースの変更を見逃してしまいます。代わりに以下の方法をとってください:

  • 重要なデータはUdonSynced変数に保存します。
  • 手動同期(Manually)のUdonBehaviourを使用している場合は、同期データを変更した後に必ずオーナーがRequestSerialization()を呼び出すようにします。

例:ドアを開けるためにイベントを送信するのではなく、変数を同期させます:

[SerializeField, UdonSynced] private bool isDoorClosed;

public void OpenDoor()
{
isDoorClosed = false;
RequestSerialization();
}

途中参加者が加わった際、正しくisDoorClosedの状態を受け取ることができます。

2. 途中参加者のためにオブジェクトの状態を補完する

プレイヤーが参加した際に変更を適用します。これは、読み込みが完了した時点で発生する OnDeserialization イベントで行うことができます:

private GameObject lockedDoor;

public override void OnDeserialization()
{
// show or hide the door depending on its synced state
lockedDoor.SetActive(isDoorClosed);
}

3. イベントと同期変数を必要に応じて組み合わせる

必要であれば、イベントから同期変数を変更することも可能です。例えば、誰かがドアを開けるたびにドアの同期状態を更新したい場合は、オブジェクトのオーナーに対してイベントを送信できます:

public override void Interact()
{
SendCustomNetworkEvent(NetworkEventTarget.Owner, nameof(OpenDoor));
}

これにより、変数を設定するためだけに、ドアのオーナーをインタラクトしたプレイヤーに変更する必要がなくなります。

最終更新: