VRCSDK3 同期周りを調べてみた

概要

VRCSDK3とU#を使用した同期関係をまとめた記事です。

主に以下の内容について、本記事では記述しています。 - 同期のタイミング - UdonBehaviorのSynchronizationMethodの設定によるそれぞれの影響 - 設定による[UdonSync]の変数の挙動 - 違う設定のGameObject間での同期の影響について - Joinなどの挙動

確認環境

  • Unity2019.4.31f1

  • VRCSDK 2022.04.20.16.26

  • U# v0.20.3

必要な知識

  • 関数がわかる人
  • 同期の仕組みが、基本的にはOwner基準で同期されるという事がわかっている事。

同期とは?

同期とは?そもそもなんなのでしょうか? 同期は、簡単にいうと、他の人と同じ状況にする事です。

VRC内であるのはPickUpのObjectは、同期されているものため、みなさんと同じ位置に持っている物が見えている状態になっています。

そして、同期を行う際に、基本的にはGameObject単位で保持されているOwnerの環境下での状態が同期されます。 そのため、対象のGameObjectのOwnerがどの人なのかを把握しておく事が重要です。

同期されるタイミング

同期の形式は大きく分けて2種類の同期があります。 - 変数の同期 - [UdonSync]の同期 - UdonBehavior側のSynchronizationMethod設定に依存 - Continous - オーナーの値を常に同期して他の人とほぼ同じ値を共有する - Manual - RequestSerializeを呼び出した際に値が共有する。 - 関数の同期 - SendCustomNetworkEventによる「動作」が同期

[変数の同期]

変数の同期は、状態を他の人と同様にする際使用します。 たとえば、スコアや、ミラーのOnOffなどの状態です。

同期のしたい変数は[UdonSync]をつける事で同期され、インスタンスに途中から入ってきた人に対して同様の値を通知します。

同期されるタイミングは、基本的には、UdonBehavior側のSynchronizationMethodの設定によって変化します。

Continuousは、[UdonSync] がついた変数が常に同期されます。 正しい値がほぼ確実に入る一方で、常に通信を行っている事になります。

通信が多くなるため、それによる不具合などが発生した際に大幅な改修が要求されます。

Manualは、RequestSerializeを呼び出した任意のタイミングに同期を行います。

常に送るわけではないので、同期頻度によっては、通信を減らす事ができます。

一方で、同期を行うタイミングの管理を行わなければいけないため、工夫が必要です。

[関数の同期]

関数の同期は、全ての人が一緒のタイミングで始める場合に使用します。

SendNetworkCustomEvent(対象、メソッド名)で実行をします。

変数の同期と違って、その場、その時にいる人に対してのみ行われるものです。

なので、これを使ってゲームがスタートしていて、途中から入られたくない場合は、変数の同期と合わせておく必要があります。


同期のパターン

今回調べたパターンと結果はは以下の通りです。 - SynchronizationMethodの設定がContinuousの場合 - 値が常に更新される - SynchronizationMethodの設定がManualの場合 - 呼び出されたタイミングのみ更新される - ContinuousのUdonBehaviorからManualのUdonBehaviorに定義されている関数を直接呼び出す。 - 値が更新されない - ManualのUdonBehaviorから、ContinuousのUdonBehaviorに定義されている関数を直接呼び出す。 - 値が更新される。

  • ContinuousのUdonBehaviorからManualのUdonBehaviorに定義されている関数をSendCustomEventで呼び出す

    • 値が更新されない
  • ManualのUdonBehaviorから、ContinuousのUdonBehaviorに定義されている関数をSendCustomEventで呼び出す。

    • 値が更新される。
  • ContinuousのUdonBehaviorからManualのUdonBehaviorに定義されている関数をSendCustomNetWorkEventで呼び出す

    • 値が更新される
  • ManualのUdonBehaviorから、ContinuousのUdonBehaviorに定義されている関数をSendCustomEventで呼び出す。

    • 値が更新される

- ContinuousのUdonBehaviorDesirializeの挙動

  • Manual時のRequestSerializeからどれくらいの遅延が起きるものなのか?

まとめ

基本的には、[UdonSync]属性のついている変数が同期対象です。

同期タイミングが、UdonBehaviorのSynchronizationMethodの設定が

Continueの時は常に同期されます。

Manualの時は、RequestSerializeが呼ばれた時に同期されます。

またPlayerJoin時はどちらの設定にも関わらず、[UdonSync]属性がついている変数が同期されます。