プレイヤーオブジェクト
プレイヤーひとりひとりに属し、その人とともに保存されるオブジェクト。正しいコピーの見つけ方まで。
Save はラベルの付いた値の引き出しです。プレイヤーオブジェクトは、VRChat がプレイヤーごとに渡し、その人のために覚えておく GameObject まるごとです。
向いているものが違います。インベントリ、持ち歩く道具、設定パネル。構造のあるもの、大きいもの、頻繁に変わるもの。容量も別枠なので、保存した値と場所を取り合いません。
用意する
オブジェクトをシーンに置き、VRCPlayerObject コンポーネントを付けます。VRCEnablePersistence も付ければ、その同期変数は訪問のあいだ覚えられます。
ここで VRChat は、人がつまずきがちなことをします。あなたのオブジェクトはテンプレートになります。 それは無効化されてその場に残り、プレイヤーはそれぞれ自分のコピーを受け取ります。走るのはコピーのほうです。コピーは人が来るまで存在しないので、シーンの中の何もコピーを指すことはできません。
正しいコピーを見つける
ですからスクリプトは、欲しいインスタンスへの参照を持てません。持てるのはテンプレート、つまりインスペクターに入れられる唯一のものです。そのうえで、どのコピーが誰のものかを尋ねます。
public Inventory template; // テンプレートをここに入れる
public override void OnSaveReady()
{
Inventory mine = PlayerObjects.Mine(template);
mine.Add("hat");
}
他の人のものは次のように取れます。
Inventory theirs = PlayerObjects.Of(player, template);
引数なしの PlayerObjects.Mine() は、このクライアントのプレイヤーに属するオブジェクトをすべて返します。自分で探したいときはこちらを。
所有権
プレイヤーは自分のコピーを所有し、それは移せません。誰かが他人の持ち物を持ち去ることを防ぐ規則であり、同時に、プレイヤーオブジェクトを変更する前に所有権を要求する必要がないということでもあります。
タイミングの規則は同じ
プレイヤーオブジェクトが保存値を読み込むのは、保存値が届くのと同じ瞬間です。ですからここでも読む場所は OnSaveReady です。Start で読むと、データが届く前のオブジェクトの姿が返ります。
容量
保存値におよそ 100 KB、プレイヤーオブジェクトにもう 100 KB、いずれもプレイヤーごとです。超えてもワールドは止まりません。VRChat がエラーを記録して保存をやめるので、動き続けたまま、静かに覚えるのをやめます。
public override void OnPersistenceUsageUpdated()
{
int used = Storage.SaveUsed();
int limit = Storage.SaveLimit;
}
この数値はここで読んでください。ほかでは読まないでください。 常に維持されているのではなく時々計算し直されるもので、最初の計算より前はゼロを返します。それは「まだ数えていない」であって「空きがない」ではありません。OnPlayerDataStorageWarning を override しておけば、まだ手を打てるうちに、あるプレイヤーが上限に近づいたことを知れます。