PlayerObject
PlayerObjectを使用すると、ワールドに参加した各プレイヤーに対して、懐中電灯や体力バー、剣といったGameObjectのコピーを自動的に割り当てることができます。
- プレイヤーがワールドに参加すると、VRChatは各プレイヤー用にGameObjectのコピーを自動的にスポーンします。
- このコピーには、すべてのコンポーネントと子GameObjectが含まれます。
- コピーは、元のPlayerObjectテンプレートと同じ位置、回転、スケール、親オブジェクトでスポーンされます。
セットアップ
以下の手順に従って、シンプルなPlayerObjectを作成してください。プレイヤーがインスタンスに参加すると、VRChatはそのプレイヤーのためにPlayerObjectをスポーンします。
- シーンのヒエラルキー内にGameObjectを作成します。
VRCPlayerObjectコンポーネントを追加します。- これにより、GameObjectがPlayerObjectテンプレートになります。
- (オプション) GameObject(またはその子オブジェクトのいずれか)に
UdonBehaviourコンポーネントを追加します。 - (オプション) 同期された変数を保持したい場合は、
UdonBehaviourと同じGameObjectにVRCEnablePersistenceを追加します。
永続的なユーザーデータの読み込み
VRChatは、以下の条件を満たすPlayerObject上のPersistent User Dataを自動的に読み込みます。
- PlayerObject(またはその子GameObject)に
UdonBehaviourコンポーネントがあること。 UdonBehaviourに変数が同期されていること。UdonBehaviourを持つGameObjectにVRCEnablePersistenceコンポーネントがあること。
PlayerObjectのユーザーデータの読み込み完了を検知するには、OnPlayerRestoredを使用してください。このイベントは、PlayerObjectのオーナーを含む、インスタンス内のすべてのプレイヤーに対して1回ずつ実行されます。
OnPlayerRestoredには、データが復元されたプレイヤーへの参照が含まれます。これを使用して、GameObjectのオーナーに変数を初期化させたり、イベントを実行させたりしてください。
StartイベントやOnDeserializationイベントでは、所有権が正しく保証されています。ただし、OnPlayerRestoredイベントが発生する前にPlayerObjectのユーザーデータを読み書きすることは避けてください。古いユーザーデータを誤って読み書きしてしまう可能性があり、VRChatのサーバーからユーザーデータを受信した際に変更が上書きされてしまう恐れがあります。
Ownership
プレイヤーがPlayerObjectを所有している場合、そのプレイヤーは自身のPlayerObject内にある、同期されたUdonBehavioursを持つすべてのGameObjectも所有することになります。これらを他のプレイヤーに譲渡することはできません。
これは、他のプレイヤーに「盗まれる」ことのないツールやピックアップをプレイヤーに提供する際に便利です。プレイヤーが常に自身のPlayerObjectを所有していることを保証できます。
PlayerObject Templates
PlayerObjectテンプレートとは、エディタ上でVRCPlayerObjectを追加して作成するオリジナルのGameObjectのことです。VRChatはテンプレートをコピーしてPlayerObjectをスポーンします。
テンプレートやPlayerObject上のコンポーネントには、他のコンポーネントへの参照を含めることができます:
- テンプレートは、自身のコンポーネントや子コンポーネントを参照できます。
- テンプレートは、シーン内の他のコンポーネントを参照できます。
- シーン内のコンポーネントからテンプレートを参照することはできません。
- その代わり、シーン内のオブジェクトは、スポーンされたPlayerObjectへの直接参照を使用する必要があります。
- テンプレートはVRChatによって自動的に無効化されますが、シーン内には存在し続けます。
- テンプレートが無効化された後、それを変更、破棄、編集しないでください!エラーや予期しない動作を引き起こす可能性があります。
スクリプト内でPlayerObjectとそのコンポーネントへの参照を見つけるには、以下のメソッドを使用してください:
Networking.GetPlayerObjectsを使用して、プレイヤーに関連付けられたすべてのPlayerObjectを取得し、その配列を調べて目的のものを探してください。Networking.FindComponentInPlayerObjectsを使用して、PlayerObjectテンプレートから特定のプレイヤーのPlayerObjectへの参照を変換してください。- 以下の例を参照してください。
Events
以下のイベントはPlayerObjectに関連しています:
| Event | Output | Notes |
|---|---|---|
| OnPlayerRestored | VRCPlayerApi player | VRChatプレイヤーの永続データがすべて読み込まれた後にトリガーされます。 |
| OnPersistenceUsageUpdated | VRCPlayerApi player | VRChatプレイヤーの永続データ使用状況が更新されたときにトリガーされます。 |
| OnPlayerObjectStorageExceeded | VRCPlayerApi player | VRChatプレイヤーのプレイヤーオブジェクトの使用量が許容ストレージ制限を超えたときにトリガーされます。 |
| OnPlayerObjectStorageWarning | VRCPlayerApi player | VRChatプレイヤーのプレイヤーオブジェクトの使用量が許容ストレージ制限に近づいたときにトリガーされます。 |
Methods
PlayerObjectのメソッドは VRC.SDKBase.Networking 名前空間にあります。
| Function | Input | Output | Notes |
|---|---|---|---|
GetPlayerObjects | VRCPlayerApi target | GameObject[] objects | 指定されたプレイヤーに関連付けられているすべてのPlayerObjectの配列を返します。 |
FindComponentInPlayerObjects | VRCPlayerApi player, Component referenceComponent | Component | PlayerObjectテンプレートの子である必要がある referenceComponent を使用して、指定されたプレイヤーに関連付けられている対応するコンポーネントを返します。 |
GetPlayerObjectStorageLimit | int | PlayerObjectのストレージ制限をバイト単位で返します。 | |
GetPlayerObjectStorageUsage | VRCPlayerApi target | int | 対象プレイヤーの最後に計算されたPlayer Object Storage使用量を返します。 |
RequestStorageUsageUpdate | void | ローカルプレイヤーのPlayerDataおよびPlayerObjectのストレージ使用量の計算をリクエストします。結果はOnPersistenceUsageUpdatedを介して取得されます。 |
ストレージ情報は時間の経過とともに古くなる可能性があり、更新が必要になる場合がある点に注意してください。RequestStorageUsageUpdateを頻繁に呼び出すことは避けてください。
これらのメソッドのユーティリティラッパーは、VRCPlayerApiクラスに用意されています。
| Function | Input | Output | Notes |
|---|---|---|---|
GetPlayerObjects | GameObject[] objects | 指定されたプレイヤーに関連付けられているすべてのPlayerObjectの配列を返します。 |
例
PlayerObject上のカスタムスクリプトを見つける
この例では、すべてのPlayerObjectを自動的に走査し、目的のコンポーネントを探します。CustomPlayerObjectScriptを、探したいコンポーネントの型に置き換えてください。
public CustomPlayerObjectScript Find(VRCPlayerApi player)
{
var objects = Networking.GetPlayerObjects(player);
for (int i = 0; i < objects.Length; i++)
{
if (!Utilities.IsValid(objects[i])) continue;
CustomPlayerObjectScript foundScript = objects[i].GetComponentInChildren<CustomPlayerObjectScript>();
if (Utilities.IsValid(foundScript)) return foundScript;
}
return null;
}
PlayerObject上のコンポーネントを見つける
この例では、FindComponentInPlayerObjects関数を使用して、PlayerObjectテンプレートの参照を、特定のプレイヤーのPlayerObjectの参照に変換します。
public Transform referenceChildTransform; // A reference to a Transform on a PlayerObject or a child of a PlayerObject
public void Find(VRCPlayerApi targetPlayer)
{
Component foundComponent = Networking.FindComponentInPlayerObjects(targetPlayer, referenceChildTransform);
// foundComponent will be of type Transform and will correspond to the targetPlayer's PlayerObject that matches the reference.
}
最終更新: