聞いてない
東京五輪の時もそうでしたがSNS等で「私は万博には行きません」とわざわざ表明する進歩的文化人の方々の意図が良く分からない一般庶民の皆さんこんにちは。誰も別に聞いてないんですが。日本で大きなイベントが開催されると必ずと言っていいほど自己顕示欲を抑えきれないのか何なのか、そういった方々が雨後の公園のミミズのように這い出てきますが必要とされてないので静かにしておいてほしいものです。まぁ、私も行く気はないけど。
MasterMemory
前回の記事でUnityでのマスタデータを利用する手法として「MasterMemory」を紹介しました。
MasterMemoryはマスタデータのような静的な大量データを扱うのに長けていて、省メモリで高速な検索を可能にします。このアセットはCysharp社が開発したアセットですがライセンスの範囲内であれば誰でも自由に使う事ができます。
MasterMemoryを使用してデータを管理するにはデータが保存されたデータクラス(配列等)をバイナリデータへの変換が必要で、MasterMemoryはこの変換されたバイナリデータを使ったデータの検索や取得の処理を行います。
この為、MasterMemoryの導入にはバイナリデータに変換する処理とバイナリデータからデータを読み込む処理を実装したスクリプトが必要で、前回の記事ではその辺りの実例を紹介させてもらいました。
【Unity】マスタデータの管理にはMasterMemoryが便利(導入と仕組みについて)
前回からの続き
今回も以下のようなデータ構造のクラスを使用するとします。
// クラスに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; } }
前回の記事ではこのデータクラスを使ったマスタデータをスクリプト内部で定義していましたが、実際にゲーム内で使用する場合は別のファイルに外出して定義する方が便利なので、今回はJSON形式のデータを用意し、それを読み込んでデータクラスを定義したいと思います。
[ { "Id": "00", "MusicName": "カラフルな生活", "MusicBPM": 110, "PlayTime": "01:35" }, { "Id": "01", "MusicName": "散々なんだよ、この空は", "MusicBPM": 88, "PlayTime": "02:16" }, { "Id": "02", "MusicName": "君はレトロ", "MusicBPM": 83, "PlayTime": "02:35" } ]
用意したJSON形式のデータファイル
ファイルの読み込みとビルド
JSON形式のファイルを読み込んでデータクラスへ設定するにはMessagePackのAPIを使用します。MessagePackは外部のアセットですがMasterMemoryを導入する際に併せてインストールされていると思うので特に設定を追加することなく使う事が出来ます。
using System; using UnityEngine; using MessagePack; /// <summary> /// Jsonファイル読み込みクラス /// </summary> public class JsonFileLoad { //////////////////////////////////// /// Jsonファイル読み込み /// //////////////////////////////////// /// <summary> /// Jsonロード /// </summary> /// <typeparam name="T">取得するデータモデル</typeparam> /// <typeparam name="K">ファイル読み込み名</typeparam> /// <returns></returns> public static T[] JsonLoad<T>() { try { string downloadPath = $"Data/{typeof(T).Name}"; string json = Resources.Load<TextAsset>(downloadPath).text; var bytes = MessagePackSerializer.ConvertFromJson(json); return MessagePackSerializer.Deserialize<T[]>(bytes); } catch (Exception) { throw; } } }
上記のJsonファイル読み込みクラスを経由してDatabaseBuilderを使ってバイナリデータに変換してファイルに保存します。
using System.IO; using MasterMemory; using MessagePack; using MessagePack.Resolvers; using UnityEditor; public static class BinaryGenerator { [MenuItem("Tools/Master/Generate Binary")] private static void Run() { // MessagePackの初期化(ボイラープレート) var messagePackResolvers = CompositeResolver.Create( MasterMemoryResolver.Instance, // 自動生成されたResolver StandardResolver.Instance // MessagePackの標準Resolver ); var options = MessagePackSerializerOptions.Standard.WithResolver(messagePackResolvers); MessagePackSerializer.DefaultOptions = options; // DatabaseBuilderを使ってバイナリデータを生成する var databaseBuilder = new DatabaseBuilder(); databaseBuilder.Append(JsonFileLoad.JsonLoad<MusicData>()); 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); AssetDatabase.Refresh(); } }
このBinaryGeneratorがコンパイルされるとメニューのTool配下に「Master>Generate Binary」の項目が追加されるので、その項目を選択すると
Resources/BinaryディレクトリにMasterMemoryで使用するバイナリデータファイルが生成されます。
参照側は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("01");
最後に
データをJson形式で定義する事でデータを変更してもプロジェクトのコンパイルをする必要がなく、メニューから選ぶだけでバイナリデータの生成が行えるのでかなり使いやすくなったと思います。
ただ、上のBinaryGeneratorのクラスはエディタ拡張となるので、ゲームを実行形式にビルドする際には「#if UNITY_EDITOR」を定義するなどしてビルド対象から外す必要がある事に注意してください。