永続化
プレイヤーの進行状況の保存を、16 種類のメソッドではなく 2 つの動詞で。タイミングの落とし穴も引き受けます。
VRChat は、プレイヤーについての情報を訪問のあいだ覚えておくことができます。そのために用意されている API は型ごとにメソッドが分かれたキーと値のストアで、SetInt、GetInt、TryGetInt があり、同じ 3 つが 16 の型それぞれに用意されています。
そこには静かに壊れるものが 3 つあります。
どのメソッドがそのキーを書いたかを覚えておく必要があります。 SetInt で書いた "level" を GetString で読んでも何も言われません。空の文字列が返り、そのまま進みます。
誰も書いていないキーに対して GetInt はゼロを返します。 これは保存されたゼロと見分けがつきません。新規プレイヤーに所持金を配る店は、初めての人と使い切った人を区別できないことになります。
Start の時点では保存データはまだ届いていません。 プレイヤーが入ってきた少しあとに届きます。早く読んでもエラーにはならず既定値が返るので、復元するものが何もない Editor では完璧に動き、進行状況を持った本物のプレイヤーを初めての人として迎えます。
このパッケージは 2 つの動詞と 1 つの基底クラスです。
public class Shop : SaveBehaviour
{
private int coins;
public override void OnSaveReady()
{
coins = Save.Get("coins", 100);
}
public void Buy(int price)
{
coins = coins - price;
Save.Set("coins", coins);
}
}
あとは値が決めてくれます。Save.Set("name", "ada") は文字列を、Save.Set("coins", 5) は整数を保存します。どちらの型かをあなたが名指しする必要はありません。読み取りには「何も保存されていなかったときの値」を渡します。これは TryGet の下の if に書いたはずの値そのもので、それを必ず書かせることが「一度も保存されていない」と「ゼロとして保存された」を分けています。
OnSaveReady は、読むことに意味がある唯一の瞬間に走ります。読み込みを Start ではなくそこに置けば、順序を覚えておく必要はなくなります。
入っているもの
Save |
Set と Get。VRChat が保存できるすべての型に |
SaveBehaviour |
データが本物になった瞬間に走る OnSaveReady |
PlayerObjects |
あるプレイヤーのものであるコピーを見つける |
Storage |
そのプレイヤーの容量をワールドがどれだけ使ったか |