ハツェの真時代傾向璋

興味を持ったことを書いていく鱗片的な場所から先の未来の場

Persistence入門 - 基礎知識編

こんばんは。ハツェです。
久しぶりに面白い機能が追加されるので、紹介しようかなと思います。
動作環境は、Unity : 2022.3.22f1、VRCSDK : 3.7.2-persistence-beta.1です。

目次


Persistenceとは

Persistenceとは、VRChatでデータを保存してそれを復元することが出来る機能です。
データはローカルに保存されずにVRChat上のサーバーにアップロードされる形で保存されるため、同一アカウントであれば別クライアントでも同じワールドにJoinすることでデータを引き継ぐことが出来ます。
しかし、現状はワールドインスタンス間でのデータ共有機能はないみたいです。今後実装されるといいですね。
また、公式ドキュメントではアップロードするデータのことを「User Data」と呼んでいるため、本記事でもこれに倣っていこうと思います。
vrc-persistence-docs.netlify.app

Persistenceの必要性

後述するデータ強制削除不可の性質上、本当にPersistenceが必要かどうかは考えてから導入することをおすすめします。
もし、一度Persistenceを導入した場合、以降の開発ではセーブデータの互換性が取れるようにしていかなければなりません。ある程度の品質を求める場合に限りますが...
ですので、Persistemceを使わなくても大丈夫そうな場合には、その方法を用いた方が良いかもしれません。

User Dataの消去

Udon側からUser Dataを消去する方法はありませんが、ユーザー自身がUser Dataを消す方法は幾つか存在しています。

全User Dataを消去する場合

クライアントからは、メインメニューの設定タブを開き、デバッグ情報ページにある「Reset All User Data」を押すことで全てのワールドのUser Dataを消去することが出来ます。

Webからは、画面上部の歯車アイコンを押し、User Data欄の「Reset All User Data」を押すことで全てのワールドのUser Dataを消去することが出来ます。

特定のワールドのUser Dataだけ消去する場合

クライアントからは、そのワールドにJoinしていない状態でワールドページを開き、「Reset User Data」を押すことでそのワールドのUser Dataを消去出来ます。

Webからは、そのワールドのページを開き、「Reset User Data」を押すことでそのワールドのUser Dataを消去出来ます。

Persistenceの種類

Persistenceには、二種類のAPIが存在します。
以下、それぞれについて紹介しますが、なるべくPlayer Objectを使用することを推奨します。

  • Player Data
  • Player Object

Player Data

Player Dataとは、キーバリュー型でUser Dataを構築し、それをVRChatのサーバーに保存するような仕組みのAPIです。
Player Data自体は、Udon Behaviourからは独立しているため、どのUdonからも利用可能ですが、データが送られてくるタイミングは RequestSerialization になっています。
また、Player Dataに保存出来るデータの型は、下記公式ドキュメントに記載されているものになります。
vrc-persistence-docs.netlify.app

キーとそのデータを追加するだけで保存出来るため、簡単に保存データを追加出来るというのがメリットです。
しかし、キーが重複した場合にデータが意図せず上書きされてしまったり、キーが削除出来ないという性質上、使用しなくなったキーが大量発生してしまったりするデメリットもあるため、アップデートを逐一行う規模の大きいワールド制作や頒布物、販売物への利用には適していません。
とりあえず、自分のワールドで保存ギミックを軽く扱うぐらいの場合にのみ使用することをお勧めします。

Player Object

Player Objectとは、GameObjectの状態そのものをVRChatのサーバーに保存するような仕組みのAPIです。
そのため、GameObjectにアタッチしているUdonの同期変数はもちろん、VRCObjectSync のようなコンポーネントの同期状態も保存出来るようです。
Player Objectは、NetworkIDをキーにしているようなので、別のGameObjectにしたりNetworkIDを意図的に別の値にしない限り、データは保存され続けることになります。
そのため、Player Dataで問題になる「キーの重複」が頒布物のインポート等で起こることがなく、ワールドをアップデートしていく過程においても比較的保全性があるため、基本的にはこちらを使用することを推奨します。

データのアップロード制限

現状は、Player Dataで100KB、Player Objectで100KBまでそれぞれアップロードすることが出来ます。
これを超えた容量をアップロードしようとした場合、アップロードだけは失敗するため、次回以降のJoin時にデータが復元出来なくなります。
また、容量を超えたアップロードをした際、現状は特にエラー等が吐き出されたりしないため、自前で容量チェックする必要がありそうです。
容量系のイベントを追加してほしいというCannyは上がっているので、投票しておくといいかも...?
feedback.vrchat.com

データの復元と保存タイミング

データが復元するタイミングは、ユーザーがインスタンスにJoinした後の OnPlayerRestored イベント発生時です。
復元させるデータ量によっては、StartOnPlayerJoined よりも後に OnPlayerRestored が発生する可能性もあるため、保存データを扱う際は OnPlayerRestored 以降で扱うようにする必要があります。

また、データが保存されるタイミングは、Player DataはキーにデータをSetした時、Player Objectでは同期変数の値を更新して再同期させた時になります。
ワールドJoin時は自動でデータを復元してくれますが、Left時には自動でデータを保存してくれないため、注意が必要です。

次回

基礎知識としては以上になります。
次回は、Player Objectを使った例を紹介していきます。
hatuxes.hatenablog.jp