Late Joiners & Sync Issues(途中参加と同期の問題)
プレイヤーが同期変数が変更された後にVRChatインスタンスに参加する場合、ワールドの最新の状態に追いつく必要があります。このガイドでは、途中参加したプレイヤーに対して一貫性があり同期されたワールド体験を保証する方法を解説します。
VRChatにおける途中参加者の処理方法
新しいプレイヤーがインスタンスに参加すると、VRChatは以下の処理を行います。
OnDeserializationイベントを通じて、最新の synced variable 値を送信します。- オブジェクトのオーナーを適切なプレイヤーに設定します。
- イベントの再実行(リプレイ)は行われません。
後から参加したプレイヤーに正しい状態を表示させる
1. 状態の管理にはイベントではなく同期変数を使用する
イベントは一度実行されると保持されないため、後から参加したプレイヤーはイベントベースの変更を見逃してしまいます。代わりの方法として以下を行ってください。
- 重要なデータは
UdonSynced変数に格納します。 - 手動同期(Manually-synced)の
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));
}
これにより、変数を設定するためだけにドアのオーナー権限を操作(Interactしたプレイヤーに変更)する必要がなくなります。
最終更新: