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

ネットワークコンポーネント

このドキュメントでは、Udonプログラムで使用できるネットワーキングコンポーネント、プロパティ、およびイベントについて解説します。

ネットワーキングプロパティ

Networkingから取得できる特別なプロパティです:

プロパティ名説明
LocalPlayerローカルプレイヤーのVRC Player APIオブジェクトを返します。
IsInstanceOwnerInvite、Invite+、Friends、Friends+インスタンスの作成者に対して true を返します。
グループインスタンス、パブリックインスタンス、およびSDKの「Build & Test」モードでは、常に false を返します。
InstanceOwnerインスタンスのオーナーであるプレイヤーのVRC Player APIオブジェクトを返します。オーナーが現在インスタンス内にいない場合、代わりに null を返します。オーナーが戻ると、再びインスタンスオーナーを返します。
インスタンスオーナーは特別なモデレーション権限を持っています。インスタンスのオーナー権限が変わることはありません。
IsMasterローカルプレイヤーがインスタンスマスターである場合に true を返します。マスターは、ネットワーク化されたゲームオブジェクトのデフォルトのオーナーとなります。
セキュリティやワールドへのアクセス制限のためにこれを使用しないでください。代わりに IsInstanceOwner を使用するか、モデレーションシステムを実装してください。
Master現在のインスタンスマスターであるプレイヤーの VRC Player API オブジェクトを返します。常に有効です。
IsNetworkSettledインスタンス内のすべてのデータがデシリアライズおよび適用され、使用可能な状態であれば true を返します。
IsClogged送信待ちのデータが多すぎる場合に true を返します。ネットワークの混雑が解消されるのを待つため、あるいはロジックを調整するために使用できます。
SimulationTimeネットワーキングコンポーネントを持つプレイヤーまたはオブジェクトの現在のシミュレーション時間を返します。詳細は以下を参照してください。

シミュレーション時間

SimulationTimeは、オブジェクトがどれだけ過去の時点でシミュレートされているかを示すタイムスタンプです。この値は、VRCObjectSyncplayersのために内部で使用されますが、Udonスクリプトで使用することも可能です。例えば、Time.realtimeSinceStartupが45で、オブジェクトのSimulationTimeが44.5である場合、VRChatはその瞬間にオブジェクトを滑らかに同期させるために500msの遅延が必要であると判断します。この数値を使用することで、VRCObjectSyncの動作に関する情報を把握したり、VRCObjectSyncと同様の独自のシステムを作成したりできます。例えば、Time.realTimeSinceStartup - SimulationTime(player)を実行すると、そのプレイヤーがその瞬間に抱えている正確なレイテンシを知ることができます。

シミュレーション時間は、レイテンシ、信頼性、パケット受信頻度など、ネットワークの状態に応じて頻繁に調整されます。この調整の目的は、レイテンシを減らすために可能な限りリアルタイムに近い状態を維持しつつ、カクつき(hitching)を防ぐための十分な余地を残すことです。カクつきの原因は多岐にわたりますが、その一例として、オーナーからのパケット受信が途切れることが挙げられます。

Networkingイベント

これらは、データの同期方法を制御するためにNetworkingシステムの一部として利用可能なイベントです。

OnPreSerialization

このイベントは、シリアル化されたデータが送信される直前に発生します。他のプレイヤーに向けて更新したい同期変数を設定するのに適した場所です。

OnDeserialization

このイベントは、同期データがバイト列から使用可能な変数へと変換された際に発生します。どのデータが更新されたかを個別に通知するわけではありませんが、同期変数を監視しているすべての要素を更新したり、新旧のデータを比較して特定の更新を行ったりするための起点として機能します。

OnDeserialization(DeserializationResult)

OnDeserializationと同様ですが、リクエストが送信および受信された時刻に関する追加情報が含まれます。

DeserializationResult

DeserializationResultには、3つのプロパティが含まれています。

  • sendTime: このメッセージが送信された時刻(秒)。
  • receiveTime: このメッセージが受信された時刻(秒)。
  • isFromStorage: trueの場合、含まれているデータは他のリアルタイムクライアントから受信したものではなく、ストレージから復元されたものであることを示します。

sendTimereceiveTimeはどちらも、あなたから見たVRChatの起動時からの経過時間(秒)に基づいています(Time.realtimeSinceStartupを参照)。つまり、特定のDeserializationが何秒前に送信されたかを知りたい場合は、Time.realtimeSinceStartup - sendTimeで計算できます。

各ユーザーの Time.realtimeSinceStartup は異なるため、あるプレイヤーの sendTime は他のプレイヤーの sendTime とは異なります。その結果、特定の sendTime を他のプレイヤーと同期させたい場合は、自身の Time.realtimeSinceStartup を差し引いてオフセットを計算する必要があります。その後、他のプレイヤーがそのオフセットを受け取れば、自身の Time.realtimeSinceStartup をオフセットに加算することで、それぞれの時計に基づいた絶対時間を算出できます。

sendTime は、VRChatを起動する前に他の誰かがメッセージを送信していた場合、負の数になる可能性があります。

OnPostSerialization

このイベントは、シリアル化されたデータの送信試行直後に発生します。'success'(bool型)と送信されたバイト数を示す 'byteCount'(int型)を含む SerializationResult 構造体を返します。

OnSpawn

このイベントは非推奨です。オブジェクトがプールから「スポーン」された際に何らかの処理を行いたい場合は、通常の OnEnabled イベントを使用してください。

OnOwnershipRequest

このイベントは、誰かがオーナー権の取得をリクエストした際に発生します。これには、リクエストしたプレイヤーとリクエストされたオーナーの PlayerObject が含まれます。変更を承認または拒否するには、「Set Return Value」ノードにブール値を設定してください。このロジックはリクエスターとオーナーの両方でローカルに実行されるため、両者のロジックに食い違いがあると非同期(desync)の原因となることに注意してください。これは、オーナー側で予期せず所有権の移行が拒否されるといった形で現れる可能性が最も高いです。

OnOwnershipTransferred

このイベントは、オブジェクトの所有権が変更された際、インスタンス内の全員に対して発生します。これには、新しいオーナーの PlayerObject が含まれます。

OnMasterTransferred

このイベントは、前のインスタンスマスターが退出したことでインスタンスマスターが変更された際、インスタンス内の全員に対して発生します。 このイベントには、マスターとなったプレイヤーの VRC Player API オブジェクトである newMaster というパラメーターが1つ含まれます。このパラメーターは常に有効です。 新しいインスタンスに参加した最初のユーザーの場合、このイベントは OnPlayerJoined の後に発生し、マスター状態が「なし」から移行したことを示します。

OnVariableChanged

これは、任意の変数に対して作成できる特殊なタイプのイベントです。Udon Graphでは、altキーを押しながら変数をグラフ内にドラッグ&ドロップすることで作成できます。このイベントは変数の変更を検知します。これには、他のプレイヤーから同期された変数を受信した場合も含まれます。

  • 配列の中身を変更しても変更イベントはトリガーされません。配列そのものは変わっていないためです。
  • OnVariableChangedは、変数そのものに書き込みが行われると即座にトリガーされます。これは、同期されたすべての変数の書き込みが完了した後にトリガーされるOnDeserialization(DeserializationResult)とは異なります。つまり、ある同期変数のOnVariableChangedを使用して別の同期変数の内容を取得しようとした場合、その変数が最新の同期データで更新されているとは限らないということです。

VRC Object Sync

このコンポーネントは、適用したオブジェクトのTransform(位置、回転、スケール)およびRigidbody(物理演算)を自動的に同期します。アクセス可能な特別なメソッドとプロパティがいくつかあります:

FlagDiscontinuity

オブジェクトをテレポートさせたいときにこれをトリガーします。このフレームで行った変更は、補間(スムージング)なしで適用されます。

Gravityの設定/取得

重力が有効な場合、このRigidbodyは重力の影響を受けて地面に落下します。通常、重力はRigidbodyのプロパティですが、VRCObjectSyncを使用している場合は、代わりにVRCObjectSyncコンポーネントでこのプロパティを制御する必要があります。これらの関数を使用することでそれが可能です。これは同期変数のように機能するため、オーナーのみが重力を設定できます。

Kinematicの設定/取得

Kinematicが有効な場合、このRigidbodyは力、衝突、ジョイントを無視します。通常、KinematicはRigidbodyのプロパティですが、VRCObjectSyncを使用している場合は、代わりにVRCObjectSyncコンポーネントでこのプロパティを制御する必要があります。これらの関数を使用することでそれが可能です。これは同期変数のように機能するため、オーナーのみがKinematicを設定できます。

Respawn(リスポーン)

このオブジェクトを開始時の位置(Position)と回転(Rotation)に戻し、速度(Velocity)を削除します。 具体的には、DiscontinuityHintをtrueに設定し、以下の変更を滑らかではなく即座に行われるようにします。その上で、以下の処理を行います:

  • transform.positionを初期位置に設定する
  • transform.rotationを初期回転に設定する

オブジェクトにRigidbodyがある場合:

  • rigidbody.velocityをVector3.zeroに設定する
  • rigidbody.angularVelocityをVector3.zeroに設定します
  • rigidbody.positionを初期位置に設定します
  • rigidbody.rotationを初期回転に設定します

VRC Object Pool

VRC Object Poolは、ゲームオブジェクトの配列を管理するための軽量な手法を提供します。このプールは、保持している各オブジェクトのアクティブ状態を管理および同期します。

オブジェクトをアクティブにするには、プールのオーナーが TryToSpawn ノードをトリガーします。これにより、アクティブ化されたオブジェクトが返されます。利用可能なオブジェクトがない場合は、nullオブジェクトが返されます。オブジェクトは、プールのオーナーによって Return ノード経由でプールに返却され、自動的に無効化されます。

途中参加者は、必要に応じてオブジェクトが自動的にアクティブまたは非アクティブになります。

最終更新: