PlayerData
PlayerDataは、ゲームのスコアやワールド内の設定など、プレイヤーに関する永続的なデータを保存するためのキー・バリュー型データベースです。
セットアップ
UdonBehaviourで PlayerData を使用するには、以下に説明する各種 PlayerData 関数を使用するだけです。どの UdonBehaviour からも、ほぼいつでもどこからでもこれらの関数にアクセスできます。
ベストプラクティス
OnPlayerDataUpdatedを使用する際は、そのスクリプトをローカルプレイヤーの変更時のみトリガーするように制限できるか、それともリモートプレイヤー全員に対してもトリガーする必要があるかを検討してください。- 例:ビデオプレイヤーの音量設定といったユーザー設定はローカルプレイヤーのみ更新すれば十分ですが、インスタンス内で「なでた犬の総数」を集計する協力型ペットゲームのような場合は、プレイヤーのスコアが増加したことに反応してグローバルスコアを増やす必要があります。
- Player Data を使用する前に
OnPlayerRestoredイベントを待機してください。OnPlayerRestoredは、プレイヤーのセーブデータが読み込まれ、Udon で安全にアクセスできる状態であることを示します。このイベントはセーブデータがない場合でも実行されます。 - 多数の Player Keys がある場合、すべてを反復処理すると低速になる可能性があります。一般的なガイドラインとして、特定のキーを直接確認したい場合、あるいはチェック対象が少数である場合、またはチェック対象が10個を超える場合など、必要に応じて
TryGetメソッドを使用してください。
ネットワーキング
PlayerData は、特定の UdonBehaviour に結びつけられているわけではないため、UdonBehaviour の synchronization 設定には依存しません。スクリプトの設定を "Manual" や "Continuous" ではなく "None" に設定しても、そのスクリプトが PlayerData にアクセスしたり変更したりすることは妨げられませんし、PlayerData 全体の動作に悪影響を与えることもありません。
UdonBehaviour が PlayerData 内の値を設定すると、PlayerData はその値を自動的に同期します。内部的には、PlayerData は RequestSerialization イベントを使用した手動同期と同様の方法で値を送信します。つまり、UdonBehaviour は複数の PlayerData キーを同時に設定し、それらをまとめて送信できるということです。UdonBehaviour が各キーを個別に送信する必要はありません。同様に、UdonBehaviour があるキーをひとつの値に設定し、直後に別の値へ変更した場合、リモートユーザーはその中間の値を受け取りません。データが短時間に連続して変更された場合、リモートユーザーには最終的な状態のみが届きます。
PlayerData の bandwidth cost は、synchronization を "Manual" に設定した UdonBehaviour 1つ分と同等です。
ワールド内のすべての UdonBehaviour は、ワールドの PlayerData へのアクセスを共有します。PlayerData キーを設定すると、ワールド内のどの UdonBehaviour からもアクセス可能になります。PlayerData は UdonBehaviour ごとに「分離」されることはありません。
ローカルプレイヤーのデータを何らか変更すると、変更されていないデータを含め、そのプレイヤーの PlayerData すべてが送信されます。少量のデータを非常に高頻度で更新する場合や、大量のデータをゆっくり更新する場合であれば、Udon's bandwidth limits に達することはまずありません。しかし、PlayerData を使用して大量のデータと高頻度なデータの両方を同期する場合、その一方を player object に移行することを検討してください。player object を使用して永続的な変数を同期することもできますが、各オブジェクトは個別に同期されます。これにより、高速なデータと大きなデータを分離でき、ワールドのネットワーク帯域幅を削減できます。
イベント
| イベント | Output | 備考 |
|---|---|---|
| OnPlayerDataUpdated | VRCPlayerApi player, PlayerData.Info[] infos | プレイヤーのPlayerDataが変更された、または受信された場合に、フレームの最後に発生します。 そのデータに関連付けられたプレイヤーのVRCPlayerApiと、データ内の全キーに関する情報が含まれた配列を提供します。この配列内の情報には、データに使用されたキーのほか、そのデータが変更・追加・未変更であるかといった状態が含まれます。 |
| OnPlayerRestored | VRCPlayerApi player | VRChatプレイヤーの永続データが読み込まれた後に発生します。 |
| OnPersistenceUsageUpdated | VRCPlayerApi player | VRChatプレイヤーの永続化データ使用状況が更新された場合に発生します。 |
| OnPlayerDataStorageExceeded | VRCPlayerApi player | VRChatプレイヤーのPlayerData使用量が、許可されたストレージ制限を超えた場合に発生します。 |
| OnPlayerDataStorageWarning | VRCPlayerApi player | VRChatプレイヤーのPlayerData使用量が、許可されたストレージ制限に近づいた場合に発生します。 |
PlayerDataを読み書きする前に、必ず OnPlayerRestored イベントを待機してください。
プレイヤーが参加すると OnPlayerJoined イベントが呼び出されますが、そのPlayerDataが受信されるまでには時間がかかる場合があります。PlayerDataをあまりに早いタイミングで設定してしまうと、永続データが受信された際に上書きされてしまう可能性があります。
PlayerData Info
OnPlayerDataUpdated イベントは PlayerData.Info 配列を提供します。この配列には、そのプレイヤーに関連付けられた現在のすべての PlayerData キーが含まれています。各要素には以下の情報が含まれます。
| Property | Type | Notes |
|---|---|---|
| Key | String | PlayerData キーに関連付けられた文字列。クエリやミューテーターで使用できます。 |
| State | Enum | この OnPlayerDataUpdated が発生した時点での PlayerData Key の最新の状態。 |
State 列挙型は、以下の可能な状態を示します。
| State | Index | Notes |
|---|---|---|
| Unchanged | 0 | 前回の更新以降、このキーのデータに変更がないことを示します。 |
| Added | 1 | 前回の更新以降、このキーが追加されたことを示します。 |
| Removed | 2 | 前回の更新以降、このキーが削除されたことを示します。削除されたキーはこの状態としてこの配列に一度だけ表示され、次回以降は表示されなくなります。 注: 現在、キーの削除はできません。 |
| Changed | 3 | 前回の更新以降、このキーのデータが変更されたことを示します。 |
| Restored | 4 | このキーが永続的なレコードから復元されたことを示します。これは、以前そのインスタンスにいたことがあるプレイヤーが再び参加した際にのみ発生します。 |
ベストプラクティス
OnPlayerDataUpdatedを使用する際は、そのスクリプトのトリガーをローカルプレイヤーの変更のみに限定できるか、あるいはすべてのリモートプレイヤーに対してもトリガーする必要があるかを検討してください。- 例えば、ビデオプレイヤーの音量に関するユーザー設定はローカルプレイヤーのみで更新すれば十分ですが、インスタンス内で「なでた犬の合計数」を集計する協力型ペットゲームの場合、プレイヤーのスコアが増加するたびに反応してグローバルスコアを増やす必要があります。
- PlayerData を使用する前に
OnPlayerDataRestoredイベントを待機してください。OnPlayerDataRestoredは、プレイヤーの保存データが読み込まれ、Udon で安全にアクセスできる状態であることを示します。 - 多数の Player Key を持っている場合、それらをすべて反復処理すると低速になる可能性があります。一般的なガイドラインとして、確認するキーが少数である場合や、キーの数が多い場合は、特定のキーの値を直接確認する
TryGetメソッドを使用してください。
メソッド
ストレージ情報
Player Data Storage 情報のメソッドは、Player Object Storage 情報のメソッドと併せて VRC.SDKBase.Networking 名前空間に含まれています。
| Function | Input | Output | Notes |
|---|---|---|---|
| GetPlayerDataStorageLimit | int | Player Data のストレージ制限をバイト単位で返します。 | |
| GetPlayerDataStorageUsage | VRCPlayerApi target | int | 指定したプレイヤーの最後に計算された Player Data Storage 使用量を返します。 |
| RequestStorageUsageUpdate | void | ローカルプレイヤーの PlayerData および PlayerObject ストレージ使用量の計算を要求します。結果は OnPersistenceUsageUpdated を通じて通知されます。 | |
| ストレージ情報は時間が経過すると古くなる可能性があり、更新が必要な場合があります。%%RequestStorageUsageUpdate%% を頻繁に呼び出すことは避けてください。 | |||
| ### クエリ | |||
| キーに関連付けられた値について詳細な情報を取得するには、これらのメソッドを使用します。キーに対して何らかの操作を行う前に、そのキーに何が存在するかを確認するのに役立ちます。 |
| Function | Input | Output | Notes |
|---|---|---|---|
| HasKey | VRCPlayerApi player, string key | bool value | 指定したキーの PlayerData に値が存在する場合、true を返します。 |
| GetType | VRCPlayerApi player, string key | Type | 指定したキーの PlayerData に格納されている値の型を取得します。 |
| TryGetType | VRCPlayerApi player, string key | out Type t, bool success | 指定したキーの PlayerData に格納されている値の型を取得します。キーが存在しない場合は false を返します。 |
| ### ミューテーター | |||
| ローカルプレイヤーの PlayerData を保存するには、これらのメソッドを使用します。リモートプレイヤーのデータを設定することはできません。 | |||
| 値は、以前に別の型であったとしても上書き可能です。一度書き込まれたキーを削除することはできません。 |
| Function | Input |
|---|---|
| SetString | string key, string value |
| SetBool | string key, bool value |
| SetSByte | string key, sbyte value |
| SetByte | string key, byte value |
| SetBytes | string key, byte[] value |
| SetShort | string key, short value |
| SetUShort | string key, ushort value |
| SetInt | string key, int value |
| SetUInt | string key, uint value |
| SetLong | string key, long value |
| SetULong | string key, ulong value |
| SetFloat | string key, float value |
| SetDouble | string key, double value |
| SetQuaternion | string key, Quaternion value |
| SetVector4 | string key, Vector4 value |
| SetVector3 | string key, Vector3 value |
| SetVector2 | string key, Vector2 value |
| SetColor | string key, Color32 value |
| SetColor32 | string key, Color32 value |
| ### アクセサ | |
| インスタンス内の任意のプレイヤーの PlayerData を取得するには、これらのメソッドを使用します。 | |
キーが存在しない場合は、その型のデフォルト値が返されます。例えば、PlayerData.GetInt() を呼び出すと 0 が返されます。 |
|
また、string が格納されているキーに対して GetInt を使用するなど、誤ったアクセサ型を使用した際もデフォルト値が返されます。 |
|
デフォルト値が望ましくない場合は、TryGet またはクエリを使用して、デフォルト値と存在しないキーを区別してください。 |
| Function | Input | Output |
|---|---|---|
| GetString | VRCPlayerApi player, string key | string value |
| TryGetString | VRCPlayerApi player, string key | string value, bool success |
| GetBool | VRCPlayerApi player, string key | bool value |
| TryGetBool | VRCPlayerApi player, string key | bool value, bool success |
| GetSByte | VRCPlayerApi player, string key | sbyte value |
| TryGetSByte | VRCPlayerApi player, string key | sbyte value, bool success |
| GetByte | VRCPlayerApi player, string key | byte value |
| TryGetByte | VRCPlayerApi player, string key | byte value, bool success |
| GetBytes | VRCPlayerApi player, string key | byte[] value |
| TryGetBytes | VRCPlayerApi player, string key | byte[] value, bool success |
| GetShort | VRCPlayerApi player, string key | short value |
| TryGetShort | VRCPlayerApi player, string key | short value, bool success |
| GetUShort | VRCPlayerApi player, string key | ushort value |
| TryGetUShort | VRCPlayerApi player, string key | ushort value, bool success |
| GetInt | VRCPlayerApi player, string key | int value |
| TryGetInt | VRCPlayerApi player, string key | int value, bool success |
| GetUInt | VRCPlayerApi player, string key | uint value |
| TryGetUInt | VRCPlayerApi player, string key | uint value, bool success |
| GetLong | VRCPlayerApi player, string key | long |
| TryGetLong | VRCPlayerApi player, string key | long value, bool success |
| GetULong | VRCPlayerApi player, string key | ulong |
| TryGetULong | VRCPlayerApi player, string key | ulong value, bool success |
| GetFloat | VRCPlayerApi player, string key | float |
| TryGetFloat | VRCPlayerApi player, string key | float value, bool success |
| GetDouble | VRCPlayerApi player, string key | double |
| TryGetDouble | VRCPlayerApi player, string key | double value, bool success |
| GetQuaternion | VRCPlayerApi player, string key | Quaternion |
| TryGetQuaternion | VRCPlayerApi player, string key | Quaternion value, bool success |
| GetVector4 | VRCPlayerApi player, string key | Vector4 |
| TryGetVector4 | VRCPlayerApi player, string key | Vector4 value, bool success |
| GetVector3 | VRCPlayerApi player, string key | Vector3 |
| TryGetVector3 | VRCPlayerApi player, string key | Vector3 value, bool success |
| GetVector2 | VRCPlayerApi player, string key | Vector2 |
| TryGetVector2 | VRCPlayerApi player, string key | Vector2 value, bool success |
| GetColor | VRCPlayerApi player, string key | Color |
| TryGetColor | VRCPlayerApi player, string key | Color value, bool success |
| GetColor32 | VRCPlayerApi player, string key | Color32 |
| TryGetColor32 | VRCPlayerApi player, string key | Color32 value, bool success |
例
永続的なジャンプカウンター

using TMPro;
using UdonSharp;
using VRC.SDK3.Persistence;
using VRC.SDKBase;
using VRC.Udon.Common;
public class JumpCounter : UdonSharpBehaviour
{
public TextMeshProUGUI jumpText;
private const string JumpsKey = "jumps";
public override void InputJump(bool value, UdonInputEventArgs args)
{
if (value)
{
AddJump();
}
}
public override void OnPlayerDataUpdated(VRCPlayerApi player, PlayerData.Info[] infos)
{
if (player.isLocal)
{
UpdateTextComponent();
}
}
private void AddJump()
{
var currentJumps = PlayerData.GetInt(Networking.LocalPlayer, JumpsKey);
PlayerData.SetInt(JumpsKey, currentJumps + 1);
}
private void UpdateTextComponent()
{
jumpText.text = $"Jumps: {PlayerData.GetInt(Networking.LocalPlayer, JumpsKey)}";
}
}
最終更新: