UnityでJSONを扱う方法と実践例

ゲーム開発

はじめに

Unityを使ってゲーム開発を行うとき、キャラクターのステータスやゲーム内アイテムのデータを保存したいと思う場面は多いのではないでしょうか。 そういったデータを管理するときに便利なのがJSONです。 JSONとは、JavaScript Object Notationの略称で、さまざまな環境や言語で取り扱えるデータフォーマットです。 UnityでもC#のコードからJSONの読み書きを行うことができます。

さらにUnity 2022 LTSのような新しいバージョンでは、JsonUtilityをはじめとする仕組みが改良されており、扱いやすくなっています。 そこで、本記事では、UnityでJSONを扱うメリットや基本的な利用方法、そして実務と結びつけた具体的な活用事例について順を追って解説します。 初めてJSONを扱う方にも分かりやすいように説明していきますので、皆さんのゲーム開発の参考にしてみてください。

Unityで扱うJSONのメリット

JSONを使う理由は、人間にもコンピュータにも読みやすいという点です。 Unityのプロジェクトでゲームデータをテキスト形式のファイルとして管理する場合、XMLやCSVなどの方法も考えられますが、JSONは構造が単純であり、キーと値がはっきり分かるため視覚的にも理解しやすいでしょう。

また、UnityではC#のクラスとの相性が良いというメリットがあります。 スクリプト上で定義したクラスをそのままJSONに書き出したり、逆にJSONからクラスオブジェクトに変換したりすることが可能です。 複雑なデータ構造を扱うときにも、階層化したクラスを用意すればスムーズに管理できるのが魅力です。

現場ではゲームアイテムの設定リストや、各ステージの設定値をまとめて外部ファイルとして運用することが多いです。 もしバランス調整や翻訳テキストなどを更新したい場合、JSON形式ならエンジニアでなくても編集しやすいかもしれません。 JSONをサーバーと連携させれば、オンラインゲームのデータ通信にも活用できます。

このようにJSONは柔軟性が高いフォーマットであり、バージョン管理システムとの相性が良いのもメリットだと感じます。 データがどのように変更されたかも見やすいですし、コミットログから変化を確認するときにも役立ちます。

JSONデータはプラットフォームに依存しづらく、将来的に別の環境で再利用しやすいという特徴もあります。

UnityのJsonUtilityの基本

Unity公式が提供するJsonUtilityクラスは、シンプルにJSONを扱える機能を持っています。 たとえばゲーム内の設定データをクラスで定義しておけば、JsonUtility.ToJsonメソッドで文字列(JSON)へ変換し、JsonUtility.FromJsonメソッドで文字列からクラスのインスタンスを生成することができます。

JsonUtilityを使うための基本的なクラス定義

クラス定義はC#スクリプトで行います。 以下の例は、キャラクターの名前やHP、攻撃力などを管理するクラスを定義したものです。

using UnityEngine;

[System.Serializable]
public class CharacterData
{
    public string characterName;
    public int hp;
    public int attack;
}

JsonUtilityを使う場合、クラスに**[System.Serializable]**属性をつけることが大切です。 こうすることで、フィールドがシリアライズされ、JsonUtilityに対応しやすくなります。

ToJsonとFromJsonの基本

先ほど定義したCharacterDataクラスをJSONに変換したり、逆にJSONから変換したりするコード例を見てみましょう。

using UnityEngine;

public class JsonUtilityExample : MonoBehaviour
{
    void Start()
    {
        // CharacterDataを用意
        CharacterData character = new CharacterData();
        character.characterName = "勇者";
        character.hp = 100;
        character.attack = 20;

        // CharacterDataからJSON文字列へ変換
        string jsonData = JsonUtility.ToJson(character);
        Debug.Log("ToJson: " + jsonData);

        // JSON文字列をCharacterDataに変換
        CharacterData loadedCharacter = JsonUtility.FromJson<CharacterData>(jsonData);
        Debug.Log("FromJson: " + loadedCharacter.characterName +
                  ", HP: " + loadedCharacter.hp +
                  ", Attack: " + loadedCharacter.attack);
    }
}

JsonUtility.ToJson(character)は、characterオブジェクトの内容をJSONの形式で文字列に変換します。

このように、ToJsonFromJsonを使うことで、クラスのオブジェクトとJSONデータを簡単に行き来できるようになります。

ただし、JsonUtilityには配列やリストを扱う場合に少し制限があります。 そのため複雑なオブジェクト構造を扱うときは、後述するNewtonsoft.Jsonの利用が検討されることが多いです。

UnityでNewtonsoft.Jsonを使う方法

JsonUtilityだけでまかなえるケースもありますが、配列やリスト、そして入れ子になったオブジェクトを多用する複雑なJSONを扱う場合にはNewtonsoft.Jsonライブラリがよく使われます。 もともとはC#の世界で広く使われているライブラリであり、Unityにも対応したバージョンがあります。

Newtonsoft.Jsonを利用するメリット

  • 複雑なデータ構造のシリアライズとデシリアライズ
  • リストや辞書型の扱いが容易
  • JSONに変換するときの細かいカスタマイズが可能

JsonUtilityでも配列に対応する方法はありますが、入れ子の多い構造や辞書型(Dictionaryなど)をスムーズに扱うには、Newtonsoft.Jsonが向いていると感じます。 実務では、外部APIと連携しながらJSONを扱うケースが増えており、そのときもNewtonsoft.Jsonが便利です。

インストールの手順

UnityのPackage Managerから「Newtonsoft.Json」を導入するか、ライブラリを直接プロジェクトに加えるだけで使えるようになります。 一度導入してしまえば、あとはC#スクリプトでusing Newtonsoft.Jsonを記述するだけなのでスムーズです。

Newtonsoft.Jsonのサンプルコード

以下は、Newtonsoft.Jsonを使ってキャラクターのリストをJSON化したり、逆にJSONから読み込む例です。

using UnityEngine;
using Newtonsoft.Json;
using System.Collections.Generic;

[System.Serializable]
public class CharacterList
{
    public List<CharacterData> characters;
}

public class NewtonsoftJsonExample : MonoBehaviour
{
    void Start()
    {
        // キャラクターリストを作る
        CharacterList characterList = new CharacterList();
        characterList.characters = new List<CharacterData>();

        CharacterData c1 = new CharacterData { characterName = "勇者", hp = 100, attack = 20 };
        CharacterData c2 = new CharacterData { characterName = "魔法使い", hp = 80, attack = 10 };
        characterList.characters.Add(c1);
        characterList.characters.Add(c2);

        // JSON文字列にシリアライズ
        string jsonData = JsonConvert.SerializeObject(characterList);
        Debug.Log("Newtonsoft ToJson: " + jsonData);

        // JSON文字列からオブジェクトにデシリアライズ
        CharacterList loadedList = JsonConvert.DeserializeObject<CharacterList>(jsonData);
        foreach (var ch in loadedList.characters)
        {
            Debug.Log("FromJson Character: " + ch.characterName);
        }
    }
}

この例では、リスト構造をスムーズに管理できます。 また、オプションを使えば、日付のフォーマットやプロパティ名のマッピングなどを細かく調整できるのもNewtonsoft.Jsonの魅力です。

JSONを活用する実務例

実際の開発ではどのようにJSONを活用するか、いくつか例を挙げて解説します。

ゲーム内のアイテムリストを管理

たとえばRPGなどで複数のアイテムが存在する場合、それらをひとまとめにしてJSONファイルで管理すると便利です。 アイテムIDや名前、レアリティなどをJSONに書き出しておけば、アイテムの追加や修正が必要になったときも一括で管理できます。

さらに、アイテムの説明文を異なる言語に切り替えるといった多言語対応にも、JSON形式のファイルなら柔軟に対応しやすいです。 外部翻訳チームにファイルを渡す場合にも、構造が分かりやすくミスを減らしやすいと考えられます。

ステージ設定やパラメーターの一括管理

プラットフォーマーやアクションゲームで、ステージごとに難易度や配置オブジェクトを変えたいケースもあるでしょう。 そういった情報をステージIDをキーにしてまとめ、JSON形式にしてプロジェクト内で読み込みます。 Unityエディタではテキストファイルとしてプロジェクトに格納し、必要に応じてデシリアライズしてステージを生成するといった形です。

JSONは同じキー名を持つオブジェクトをいくつも並べて書くのが得意です。 大量のパラメーターがある場合でも、構造をきちんと決めておけばすぐに拡張できるのも便利なポイントでしょう。

セーブデータとしての利用

プレイヤーの進行状況やスコアなどをセーブデータとして扱うときにも、JSONは有力な選択肢です。 シリアライズした文字列をローカルストレージやPlayerPrefsに保存し、ゲーム起動時に読み込むことで、プレイヤーのデータを簡単に復元できます。

ゲームがマルチプラットフォームに展開している場合でも、JSONでデータを保持していれば共通化しやすいです。 JSONファイルをクラウドやサーバーに送信すれば、オンライン同期も行いやすいかもしれません。

JSON活用時の注意点

JSONを使うときには、いくつか気を付けたい点も存在します。

ファイルサイズと読み込みタイミング

JSONファイルが大きくなりすぎると、ゲーム起動時のロードに時間がかかることがあります。 大量のデータを一度に扱うより、必要な部分だけを読み込む仕組みを用意したほうが良い場合もあります。 また、アセットバンドルやAddressablesを使うといった方法で、データを分割管理することも検討してみるといいでしょう。

文字コードや改行コード

Unityで扱うときには大きな問題になりにくいですが、外部ツールとのやりとりで文字化けが発生するケースもゼロではありません。 JSON自体はUnicodeでエンコードできるため、ほとんどの場合は問題ありませんが、念のためUTF-8で保存するなどの設定を確認しておくと安心です。

デバッグとバージョン管理

JSONファイルが増えてくると、いつ誰がどこを変更したのか分からなくなることがあります。 Gitなどでバージョン管理しておけば、ファイルの差分を簡単に追跡できますが、コメントを残す仕組みがないためJSONファイル内でコメントを入れることはできません。 代わりにドキュメントやコメント用の別ファイルを用意して管理すると良いでしょう。

メモリ管理とパフォーマンスへの影響

JSONはテキスト形式なので可読性が高い一方、バイナリ形式のファイルに比べてサイズが大きくなることがあります。 モバイル機器や低スペックの端末をターゲットにする場合、ある程度のチューニングが必要になるかもしれません。

ただし、ゲームデータ程度であればJSONのサイズが原因で極端にパフォーマンスが落ちることはあまりないと考えられます。 むしろ開発効率や保守性とのバランスを考慮し、JSONの可読性を重視する現場が多いように感じます。

一方でリアルタイム通信を行うゲームでは、データ量を削減するためにJSONではなくバイナリプロトコルを使う場合もあります。 実際のところ、JSONはオブジェクト数がそこまで多くないゲームでは取り回しの良い方法と言えるでしょう。

拡張やカスタマイズのアイデア

JSONを扱う中で、データ変換や独自フォーマットが必要になることがあるかもしれません。 そのような場合は、Newtonsoft.Jsonでカスタムコンバーターを作成したり、独自のシリアライズメソッドを用意する手段があります。

たとえば、Vector3やColorといったUnity特有の構造体をJSON化するとき、標準のJsonUtilityだけでは思った通りに変換できないケースがあります。 そんなときにNewtonsoft.Jsonのカスタマイズ機能を使うと、x, y, zをまとめたオブジェクト構造を自由に変換できるので、実用性が高いと考えられます。

また、バージョン管理の観点から、JSONファイルに細かい設定を追記していくと構造が複雑化しやすい点には注意が必要です。 不要な情報を入れすぎないように設計することも安定した開発には欠かせません。

まとめ

本記事では、UnityでJSONを扱うメリットや基本的な利用方法について解説しました。 JsonUtilityはシンプルで取り回しがしやすく、Newtonsoft.Jsonは複雑なデータ構造にも対応できるなど、それぞれに特徴があります。

ゲームのステータスデータやアイテム設定、ステージ情報、セーブデータなど、活用できる場所はたくさんありそうです。 可読性が高く、人間にも編集しやすいJSONは、開発チーム内での連携や将来的な拡張にも相性が良いと考えられます。

皆さんがゲーム開発を進めるうえで、JSONをうまく使いこなし、データ管理を快適にしてみてはいかがでしょうか。 以上がUnityにおけるJSONの基本と実務的な活用例です。

Unityをマスターしよう

この記事で学んだUnityの知識をさらに伸ばしませんか?
Udemyには、現場ですぐ使えるスキルを身につけられる実践的な講座が揃っています。