原カバンは鞄のお店ではありません。

Unityを使ったゲーム制作のあれこれを綴っていきます。

【Unity】マスタデータの管理にはMasterMemoryが便利(導入と仕組みについて)

次の連休

五月のGWを過ぎると次の連休まで二ヶ月以上空いている事に軽い絶望を覚える五月病予備軍の皆さんこんにちは。ここから五連勤の週が10週続きます、なんだそれ。税金を増やす減らすとか賃金が上がる上がらないとか以前に休みを増やすことを考えても罰は当たらないと思う。

 

近況

制作中のリズムゲーム「Under A Groove」ですが、GW中はバグ修正とステージ選択画面の作成に勤しんでました。このゲームは特に発売日を決めず、Tokyo Inide Games Summit等の展示会イベントに合わせて新しいステージを披露していく開発スケジュールを取っており、展示会イベントで披露・試遊してもらうのはその新ステージのみ(既存のステージは見せない)という形にしていますが、今後のことも考えて既存のステージも遊んでもらえるようにステージ選択の画面(シーン)を作成しました。

作成したステージ選択画面

 

現状では上の動画でも分かるように未だ3ステージしか作ってませんが、今後ステージ数が増えていくことを考えると選択画面に表示するデータはソースに埋め込むのではなくマスタデータとして管理していきたい、それも出来ればロードが高速で検索も簡単にできる形で・・・といわけで、そういった用途には一番適しているデータ保存形式であろうMasterMemoryを導入することにしました。

 

MasterMemoryの導入

MasterMemoryはCysharp社が開発したアセットですがライセンスの範囲内であれば誰で無料で使用することができます。特徴としては高速かつ軽量なデータ管理ライブラリで、読み取り専用のデータ管理を得意とします。

github.com

このMasterMemoryの導入にはMasterMemoryが依存するMessagePack for C#の導入が先だって必要でそれに伴う設定変更も行うことになりますが、NuGetForUnityを使えばそういった事を省いて比較的簡単にUnityプロジェクト内に導入することができます

 

よって先にPackageManagerからNuGetForUnityを導入します。PackageManagerウィンドウ左上の + ボタンを押下し、「Add package from git URL...」を選択して以下のURLを入力、Addボタンを押します。

https://github.com/GlitchEnzo/NuGetForUnity.git?path=/src/NuGetForUnity

 

NuGetForUnityを導入するとUnity上部のMenu内にNuGetForUnityの項目が増えるので、そこからManage NuGet Packages を選択します。



パッケージ検索ウィンドウが開くので、「MasterMemory」を検索してインストールします。

 

MasterMemoryの仕組み

MasterMemoryは、静的なバイナリ形式でデータを保存します。つまり、CSVやJsonなどに保存している原本データは一度そのデータをバイナリ形式に変換して保存しておく必要があります。そしてこのバイナリ形式に変換する際にインデックスを付加することで検索性能を最適化しています。

例えば以下のようなデータ構造のクラスをゲーム内でマスタデータとして取り扱い場合は

// クラスにMemoryTableアトリビュートをつける
// クラスにMessagePackObjectアトリビュートをつける
[MemoryTable("Music"), MessagePackObject(true)]
public sealed class MusicData
{
	// プライマリキーにはPrimaryKeyアトリビュートをつける
	[PrimaryKey]
	public string Id { get; set; }

	public string MusicName { get; set; }

	public int MusicBPM { get; set; }

	public string PlayTime { get; set; }
}

 

マスタデータを格納したデータクラス(配列)を作成してDatabaseBuilderを使ってバイナリデータに変換してファイルに保存

var musicMasters = new MusicData[]
{
    new("001", "Music1", 88, "02:35"),
    new("002", "Music2", 117, "01:30"),
    new("003", "Music3", 88, "02:30")
};

// DatabaseBuilderを使ってバイナリデータを生成する
var databaseBuilder = new DatabaseBuilder();
databaseBuilder.Append(musicMasters);
var binary = databaseBuilder.Build();

// できたバイナリは永続化しておく
var path = "Assets/Resources/Binary/MusicData.bytes";
var directory = Path.GetDirectoryName(path);
if (!Directory.Exists(directory))
    Directory.CreateDirectory(directory);
File.WriteAllBytes(path, binary);

 

そして参照側ではMemoryDatabaseに変換したバイナリデータを読み込み、そこから検索キーを指定した検索を行って目的のデータを取得

var path = "Assets/Resources/Binary/MusicData.bytes";
var asset = AssetDatabase.LoadAssetAtPath<TextAsset>(path);
var binary = asset.bytes;

var memoryDatabase = new MemoryDatabase(binary);
var data = memoryDatabase.MusicDataTable.FindById("001");

という手順になります。

ちょっとややい越しいのでMasterMemoryを使ったデータの流れを図で表してみます。

 

ここまでのまとめ

MasterMemoryは高速な検索と任意のデータ構造に対応したマスタデータを管理するには大変便利なアセットです。
データはバイナリ形式で保持され、効率的にメモリを使用するためメモリ消費は少ないですし、インデックスが作られる為に大量データでも短時間でクエリ処理が可能となっています。

しかしデータには変換工程が必要で、準備に時間がかかるのがデメリットと言えます。
今回は例としてのマスタデータをソース内に定義して、それ以後の変換工程と取得手順を紹介しましたが、次回は実際にゲームで使用することを想定してマスタデータをJson形式で定義し、それをDatabaseBuilderを使ってバイナリデータに変換する手順を紹介したいと思います。

 

◇プライバシーポリシー

●個人情報の利用目的

当ブログでは、メールでのお問い合わせ、メールマガジンへの登録などの際に、名前(ハンドルネーム)、メールアドレス等の個人情報をご登録いただく場合がございます。

これらの個人情報は質問に対する回答や必要な情報を電子メールなどをでご連絡する場合に利用させていただくものであり、個人情報をご提供いただく際の目的以外では利用いたしません。

●個人情報の第三者への開示

当サイトでは、個人情報は適切に管理し、以下に該当する場合を除いて第三者に開示することはありません。

・本人のご了解がある場合
・法令等への協力のため、開示が必要となる場合

個人情報の開示、訂正、追加、削除、利用停止
ご本人からの個人データの開示、訂正、追加、削除、利用停止のご希望の場合には、ご本人であることを確認させていただいた上、速やかに対応させていただきます。

アクセス解析ツールについて

当サイトでは、Googleによるアクセス解析ツール「Googleアナリティクス」を利用しています。

このGoogleアナリティクスはトラフィックデータの収集のためにCookieを使用しています。このトラフィックデータは匿名で収集されており、個人を特定するものではありません。
この機能はCookieを無効にすることで収集を拒否することが出来ますので、お使いのブラウザの設定をご確認ください。

●免責事項

当サイトからリンクやバナーなどによって他のサイトに移動された場合、移動先サイトで提供される情報、サービス等について一切の責任を負いません。

当サイトのコンテンツ・情報につきまして、可能な限り正確な情報を掲載するよう努めておりますが、誤情報が入り込んだり、情報が古くなっていることもございます。

当サイトに掲載された内容によって生じた損害等の一切の責任を負いかねますのでご了承ください。

●プライバシーポリシーの変更について

当サイトは、個人情報に関して適用される日本の法令を遵守するとともに、本ポリシーの内容を適宜見直しその改善に努めます。

修正された最新のプライバシーポリシーは常に本ページにて開示されます。