2017年04月11日

【Unity5】どのようにゲームデータを保存するか

ゲームの進捗状態や、オプション設定の情報、更にはステージを読み込むためのデータ等、
ゲームを作成する上では何かと読み込み保存の処理は必要となってくる。

インターネット上でUnityの保存処理はいくつか紹介されているが、あまり比較している記事は少ない。
なので今回はUnity環境における読み込み保存処理の選択肢を見ていきたい。
主な特徴を箇条書きし、それに対する所感を記載する形で列挙した。

スポンサードリンク

PlayerPrefs

[特徴]

  • KeyとValueの対となるデータを手軽に保存できる
  • とにかく実装がシンプル
  • string / int / floatの形式のみしかサポートしていない
  • JsonのStringデータなどを保存することも出来なくもない
  • BinaryFormatterなどでシリアライズしてBase64形式のString型で強引に保存することもできる。

[所感]

とにかくシンプルなデータを手軽に保存する処理を実装したいときに選択肢として上がるが、
登録したデータは一つのXMLデータで管理されてしまうため、
どれか一つのキーにでも巨大なデータを含めてしまうと、それ以外のキーを参照する際にも
全体のデータを読み込むコストがかかってしまうのでおススメできない。

またデータ解析も比較的容易にできてしまうのでゲームのフラグ管理にはチートされる危険性が残る。
PlayerPrefsはシステムの基本設定などの情報(オーディオボリューム値など)を入れておく程度の使用法がベターである。

シリアライゼーション

[特徴]

  • 基本不変のパラメータデータだが、開発中に変更する可能性のあるデータに向く
  • 専用の外部データに用意して読み書きのコストをかけるほどではないときに向く
  • 直感的に特定のCompornentに対してデータを管理可能
  • 入力処理をEditor実装することにより入力をツール化することも容易
  • metaデータが壊れたり、削除してしまった場合、設定していたデータが消失する危険がある。
  • 設定データをスマートに保存できるが、クラスの設計次第では正しくシリアライズできない。

[所感]

プレハブをAssetsとして保存した際にシリアライズされて任意のデータが保存される。
シーン上にセットしたプレハブも同様にSceneデータにシリアライズされて保存される。

シリアライズできるものは
  • publicまたは[SerializeField]属性を与えた変数
  • static/const/readonlyでない変数
  • [Serializable] 属性を持つ(抽象でない)クラス/構造体
  • UnityEngine.Objectを継承したオブジェクト参照
  • プリミティブ型(int/float/double/bool/string/...)
  • シリアライズ可能な変数の配列/リスト
になる。

使用する場合、変更しても致命的な影響が出ない程度のものが望ましい。
またこの方法でのデータ保存の欠点は、何か調整を行っているときに誤ってデータを変更してしまう可能性がある点。
metaデータを誤って削除してしまった場合などでデータが消失する可能性があるので注意する。
※バージョン管理していたデータが競合した場合に正しく解決しないと作業データが消失したり・・・

直感的に入れるデータ管理に向くが、大量のデータを入れるには流石にに非効率かと考える。
別途流し込むツールを作ってからレベルデザイナが微調整する方法も考えられるが、そこは開発現場次第で判断したい。

JsonまたはXml形式で読み書き

[特徴]

  • データの保存としては塊で管理するので信頼性がある
  • 書き出した後もテキストエディタでデータの確認がしやすい
  • 上記に付記してバージョン管理で競合した場合も、差分チェックやマージが行いやすい
  • 大容量データの保存に向く
  • 読み込み保存の処理を実装する際にひと手間が必要
  • テキストエディタで確認しやすいため生データではセキュリティの観点で脆弱性がある
  • リリース時に暗号化処理を仕込むことでセキュリティ面を担保できる

[所感]

Jsonも少し前のUnityでの導入は敷居が高かったと思われるが、
今はJsonUtilityクラスがUnityEngine内に追加されたため実装難度は大分下がったと思う。

自分もMonobehavior継承した「JsonData」クラスを実装して LoadJsonとSaveJsonのメソッドを用意している。
このクラスをJson管理したいクラスに継承させ、任意のパスに読み込み保存をするデータとして
メソッドを介してJson形式にコンバートできるようにしている。
これで上記のシリアライズを利用してJsonUtilityが動作するので、必要な変数をシリアライズしてあげれば
あとは勝手にJson化したりJsonデータを流し込んだりでき、非常に手軽なのでおススメしたい。
この辺りは後々に詳細をまとめておきたい。

XMLの変換処理はXmlDocumentを使うことで実現が可能である。

概ねUnityでの実データ形式の読み書き処理はこの二つが手軽な点で選択肢か。
JsonでもXMLでも外部データをExcelやGoogleSpreadSheetで管理し、出力用のツールを作ることで
Unity上でなくとも管理できフィルタやソートがしやすいのは大きな利点である。

スポンサードリンク

最後の選択は結局一般的なデータ保存処理を使用しており、単純にデータ形式をどう管理するかという点でしかない。

またチートや解析対策としてはシリアライズもJson書き出しも
最終データをアセットバンドル化して管理するのであれば、そちらでの暗号化が検討できる。

直接出力された文字列データをRijndaelなどで暗号化して保存してもよいが、
鍵の取り扱いは考えなければただの複雑なだけのセキュリティでしかない。

このあたりに関してはサーバーでデータを管理しているのであれば、
重要なプレイヤーデータは全部サーバーから与えたほうが良い。

今回紹介した手段はクライアントのみで完結する場合の保存処理だ。
各手法の細かい使用方法に関しては、どれも先達が記事にしているので調べてみるとよい。

スポンサードリンク



posted by しのゆい at 21:00 | Comment(0) | 開発メモ | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント: