事の発端
きゅぶんずさんがいい感じの記事を書いてるのを見て、Airtableに興味を持ち、いろいろ調べていたらMasterMemoryなるものが出たので、全部一緒に料理してやんよ見たいな感じでUnityでいい感じに使おうと思った記録です。
とりあえず参考までに
きゅぶんずさんの記事
https://qiita.com/kyubuns/items/dc47cf7c9af38f13c9ee
Airtable
https://airtable.com/
Airtableの.NETクライアント
https://github.com/ngocnicholas/airtable.net
↑がJson.NET使ってたので、Utf8Json用に私が作ったもの
https://github.com/yKimisaki/AirtableClient
Utf8Json
https://github.com/neuecc/Utf8Json
起動のたびにAirtableにアクセスすると遅いので、手元にそのデータをバイナリでキャッシュしておく。
そのキャッシュを作ったり、バイナリからテーブルにしてくれる良い物がMasterTable。
https://github.com/Cysharp/MasterMemory
作戦
↑のようなテーブルを
var appleMaster = MasterCache.TestMaster.FindByID(1);
みたいな形でUnity上から使えるようにする。
TestMasterクラスの作成
自動生成したいけど、いろいろ面倒くさい経験しかないので頑張って書きます。
[MessagePackObject(true)]
[MemoryTable(nameof(MainGameMaster))]
public class TestMaster
{
[PrimaryKey]
public int ID { get; set; }
public string Name { get; set; }
public int Price { get; set; }
}
注意点としては、PrimaryKey属性がフィールドじゃなくプロパティにしか付けられないので{ get; set; }なりが必須、またUnity用のmpc.exe(MessagePackのリゾルバ生成)はTestMasterのリゾルバは生成してもTestMaster[]、つまりカスタムクラスの配列は自動で生成してくれないので、作っておかないと怒られます。以下で生成されるMasterMemoryResolverを登録しましょう!!!
UnityEditorで必要なものをいい感じに生成する
みたいなのを作ってメニューからMessagePackのリゾルバやらAssetBundleやらをそれっぽく生成できるようにしておきます。
できたらMasterMemoryのTablesを生成します。
普通にMasterMemory.Generator.exe自分でたたいてくれてもいいです。
AirTableやバイナリからMasterMemoryに読み込む
みたいな感じで、複数の経路、具体的にはキャッシュのバイナリか、Airtableから直接MasterCacheみたいなメモリ上に展開するクラスに登録できる状態を作っておきましょう。
Airtableからバイナリを作成
あとは、だいぶ前のBuilder.csあたりに
[MenuItem("Build/MasterMemory/Binaries")]
public static void BuildBinaries()
{
var binary = ScriptableObject.CreateInstance<BinaryObject>();
Task.Run(async () =>
{
binary.Value = await new AirtableMasterLoader().LoadAsync();
}).Wait();
AssetDatabase.CreateAsset(binary, ClientMasterLoader.BinaryAssetPath);
AssetDatabase.Refresh();
Debug.Log($"Build completed. Binary is created on {ClientMasterLoader.BinaryAssetPath}");
}
を追加して実行すると、指定の場所にバイナリを内包したScriptableObjectが生成されます。
仕上げ
あとはそのバイナリをAssetBundleにしておきましょう。
await MasterCache.RegisterAsync(new ClientMasterLoader());
で、読み込んであげれば、
var appleMaster = MasterCache.TestMaster.FindByID(1);
これが達成できます。
まとめ
雑くてスミマセンが、アプリの起動時間=ログインのしやすさ関わってくる部分だと思っているので、できるだけマスタなどはクライアントにキャッシュしておくことをお勧めします。
で、更新があれば都度AssetBundleなどを経由してDLしてもらうのが、いいと思います。