はじめに

値を保存し、既定値つきで読み戻し、その答えが本物である唯一の瞬間に読む。ここまでの流れを一通り。

更新日 2026-09-08

インストール

まず、VCC(VRChat Creator Companion)で永続化パッケージを Unity プロジェクトに追加します。プロジェクトの vccproject.json を開いてパッケージを追加するか、VCC インターフェースを使って直接インストールしてください。

インストール後、パッケージはプロジェクトで利用可能になり、以下の永続化 API を使い始めることができます。

保存する

Save.Set("coins", 25);
Save.Set("name", "ada");
Save.Set("spawn", transform.position);

どの型でも動詞はひとつです。どれが使われるかは値が決めるので、SetInt を間違えようがありません。書き込みは常にこのクライアントのプレイヤーに対して行われます。クライアントが変更してよいのは自分のデータだけだからです。

読み戻す

int coins = Save.Get("coins", 100);
string name = Save.Get("name", "friend");
Vector3 spawn = Save.Get("spawn", Vector3.zero);

2 つめの引数は、何も保存されていなかったときに返る値で、省略できません。 それがこの設計の核心です。戻ってきたプレイヤーには 25 枚、初めての人には 100 枚が渡り、そのどちらであるかを TryGetif なしにコードが語ります。

キーが求めた型と違う型を持っていたときにも同じ値が返ります。ですから "level" という名前を選んでしまった 2 つのシステムは、意味の壊れた値ではなく既定値に落ちます。

正しい瞬間に読む

public class Shop : SaveBehaviour
{
    private int coins;

    public override void OnSaveReady()
    {
        coins = Save.Get("coins", 100);
    }
}

Start では読まないでください。 保存データはプレイヤーが参加した少しあとに届き、それより前に読んだものはすべて既定値です。これは一段落を割く価値のある間違いです。間違いに見えないからです。Editor ではそもそも保存されているものが無いことが多く、進行状況を持った本物のプレイヤーが入ってくるまで、ワールドは意図どおりに動いてしまいます。

SaveBehaviour を継承すると OnSaveReady が使えます。このクライアントのプレイヤーのデータが読める瞬間に、一度だけ走ります。

他の人のデータ

public override void OnPlayerSaveReady(VRCPlayerApi player)
{
    int theirs = Save.Get(player, "best", 0);
}

誰の保存値でも読めますが、その人のデータが読めるようになる瞬間は自分のときとは別です。その人が来たときで、それは 1 時間後かもしれません。だからメソッドが分かれています。知らない人が入ってくるたびに自分の状態を読み直す behaviour は、それまでの積み重ねを捨ててしまいます。

初回とそれ以外を見分ける

if (!Save.Has("visits"))
{
    // 歓迎のひと揃いを渡す。
}

Save.Has は、そのキーが一度でも書かれたかを答えます。たいていは既定値のほうが同じことをより直接に言えます。「無いこと」そのものが情報であるときに使ってください。

知っておく価値のある 2 つの制限

キーを削除する手段はありません。 VRChat は上書きはできますが削除はできません。ですからワールドが使うキーの集合は、増やしていくものではなく一度決めるものとして扱うのが賢明です。

キーはワールド全体で共有されます。 "level" を保存する 2 つのシステムは同じキーを使っています。接頭辞を付けてください。

問題が発生しました 再読み込み