UnityUnityメモ

【実践】UnityでJSONデータ管理!セーブ&ロードを最適化する方法

Unity

1. はじめに

ゲーム開発において、プレイヤーの進行状況や設定データを保存する仕組みはとても重要です。例えば、RPGなら「キャラクターのレベルやアイテムの所持状況」、アクションゲームなら「クリアしたステージ」など、データを保存・ロードできなければプレイヤーは毎回最初からやり直すことになってしまいます。

Unityでは、データを保存する方法はいくつかありますが、**JSON(JavaScript Object Notation)**を使うと、軽量で扱いやすく、可読性が高いというメリットがあります。JSONはテキスト形式でデータを保存するため、人間でも簡単に読み書きでき、デバッグしやすいのが特徴です。また、JSONはほとんどのプログラミング言語で利用できるため、他のプラットフォームやサーバーとデータをやり取りするのにも便利です。

本記事では、UnityでJSONを使ったセーブ&ロード処理を最適化する方法について解説します。JsonUtilityを活用し、ゲームのデータをスムーズに管理する方法を学んでいきましょう!




2. JSONとは?基礎知識

JSONの基本構造(キーと値のペア)

JSON(JavaScript Object Notation)は、データをシンプルなテキスト形式で表現するためのフォーマットです。
基本的な構造は「キー」と「値」のペアで構成されており、次のように書かれます。

{
"name": "勇者",
"level": 10,
"hp": 100,
"mp": 50,
"inventory": ["ポーション", "剣", "盾"]
}

この例では、

  • "name" の値は "勇者"(文字列)
  • "level" の値は 10(整数)
  • "hp" の値は 100(整数)
  • "mp" の値は 50(整数)
  • "inventory" の値は ["ポーション", "剣", "盾"](配列)

といった形で、ゲームのキャラクター情報を表しています。

UnityでのJSONの活用シーン

Unityでは、JSONを使ってさまざまなデータを管理できます。特に次のような場面で役立ちます。

セーブ&ロード機能

  • プレイヤーの進行状況をJSON形式で保存し、次回プレイ時に復元

設定データの管理

  • ゲームの設定(音量、解像度、操作方法など)をJSONで保存

レベルデザインデータの保存

  • ステージ情報や敵の配置データをJSONファイルにまとめ、ゲームで読み込む

オンラインとのデータ通信

  • サーバーとゲームの間でデータをやり取り(ランキングやアカウント情報の管理)

JSONはシンプルなテキスト形式なので、人間が直接編集しやすく、バージョン管理もしやすいのがポイントです。

JSONとXML・バイナリとの違い

データを保存・管理する方法はいくつかありますが、JSON以外にもXMLバイナリ形式が使われます。それぞれの違いを見てみましょう。

形式特徴メリットデメリット
JSONテキスト形式(キーと値のペア)軽量で可読性が高い、扱いやすい大きなデータになると処理が重くなる
XMLテキスト形式(タグで囲む)汎用性が高く、人間でも理解しやすいJSONより冗長でデータ量が増える
バイナリバイナリデータ(0と1のデータ)圧縮できて軽量、処理が速い人間が読めずデバッグしにくい

Unityでは、

  • 可読性と汎用性を重視するならJSON
  • 高速処理やセキュリティを優先するならバイナリ
  • XMLは外部ツールとの連携が必要な場合に選択

といった形で使い分けます。

JSONは特に初心者にも扱いやすく、Unityの標準機能(JsonUtility)で簡単に処理できるため、ゲーム開発において非常に便利なデータ管理方法です。




3. UnityでJSONを扱う方法

Unityでは、データをJSON形式で扱うために JsonUtility というクラスが標準で用意されています。このJsonUtilityを使えば、C#のオブジェクトを簡単にJSONへ変換したり、逆にJSONからオブジェクトへ復元することができます。


JsonUtilityの基本的な使い方

UnityのJsonUtilityを使うことで、ゲーム内のデータを簡単にJSONへ変換・保存し、後から復元することができます。

例えば、プレイヤーデータをJSONに変換する場合、以下のような流れになります。

  1. C#のクラスを作成(ゲームデータを表現)
  2. JsonUtility.ToJson() を使ってJSON形式のデータに変換
  3. JsonUtility.FromJson<T>() を使って元のオブジェクトに復元

これらの基本的な使い方を詳しく見ていきましょう。


JsonUtility.ToJson() と JsonUtility.FromJson<T>() の解説

C#のオブジェクトをJSONに変換する(ToJson)

Unityでは、JsonUtility.ToJson() を使うと、C#のオブジェクトをJSON形式の文字列に変換できます。

using UnityEngine;

[System.Serializable] // JSON化するにはSerializable属性が必要
public class PlayerData
{
public string playerName;
public int level;
public float health;
}

public class JsonExample : MonoBehaviour
{
void Start()
{
// プレイヤーデータを作成
PlayerData player = new PlayerData();
player.playerName = "勇者";
player.level = 5;
player.health = 98.5f;

// JSON形式に変換
string jsonData = JsonUtility.ToJson(player);
Debug.Log(jsonData);
}
}

出力されるJSONデータ(Debug.Log()で確認)

{"playerName":"勇者","level":5,"health":98.5}

このように、C#のオブジェクトをJSON形式に変換することができます。


JSONをC#のオブジェクトに復元する(FromJson)

JsonUtility.FromJson<T>() を使うと、JSONの文字列をC#のオブジェクトに変換できます。

using UnityEngine;

public class JsonLoadExample : MonoBehaviour
{
void Start()
{
// JSONデータ(例)
string jsonData = "{\"playerName\":\"勇者\",\"level\":5,\"health\":98.5}";

// JSONをC#のオブジェクトに変換
PlayerData loadedPlayer = JsonUtility.FromJson<PlayerData>(jsonData);

// 復元されたデータを表示
Debug.Log($"名前: {loadedPlayer.playerName}, レベル: {loadedPlayer.level}, 体力: {loadedPlayer.health}");
}
}

出力結果

名前: 勇者, レベル: 5, 体力: 98.5

これでJSONから元のオブジェクトに復元できました。




実際にJSONを使ってデータを保存・読み込む

ゲームで実際にデータをセーブ・ロードするには、JSONをファイルに保存し、後でファイルから読み込む仕組みが必要です。System.IO を使って、JSONデータをファイルに書き込んだり、読み込んだりすることができます。

using UnityEngine;
using System.IO;

public class SaveLoadManager : MonoBehaviour
{
private string filePath;

void Start()
{
// 保存するファイルのパスを設定(Application.persistentDataPathを使用)
filePath = Path.Combine(Application.persistentDataPath, "saveData.json");

// データを保存
SaveGame();

// データをロード
LoadGame();
}

void SaveGame()
{
PlayerData player = new PlayerData();
player.playerName = "勇者";
player.level = 10;
player.health = 120.5f;

// JSONに変換
string jsonData = JsonUtility.ToJson(player);

// ファイルに保存
File.WriteAllText(filePath, jsonData);
Debug.Log("データを保存しました: " + filePath);
}

void LoadGame()
{
// ファイルが存在するか確認
if (File.Exists(filePath))
{
// ファイルからJSONデータを読み込む
string jsonData = File.ReadAllText(filePath);

// JSONをC#のオブジェクトに変換
PlayerData loadedPlayer = JsonUtility.FromJson<PlayerData>(jsonData);

Debug.Log($"ロードしたデータ: 名前: {loadedPlayer.playerName}, レベル: {loadedPlayer.level}, 体力: {loadedPlayer.health}");
}
else
{
Debug.LogWarning("セーブデータが見つかりません");
}
}
}

まとめ

JsonUtility を使えば簡単にJSONデータの変換ができる
ToJson() でC#のオブジェクトをJSONに変換
FromJson<T>() でJSONからオブジェクトを復元
System.IO を使えばファイルに保存&読み込みが可能

この方法を活用すれば、プレイヤーデータやゲーム設定をJSON形式で管理し、簡単にセーブ・ロード処理を実装できます!




4. JSONを活用したセーブ・ロードシステムの実装

ゲームでプレイヤーデータや設定情報を保存・ロードする仕組みを作るには、JSONを活用すると便利です。ここでは、Unityで実際にセーブ&ロード機能を実装する方法を解説します。


ゲームデータを保存するC#スクリプトの作成

まずは、保存するデータの構造を定義します。C#のクラスを作成し、そのオブジェクトをJSONに変換することで、簡単にデータを管理できます。

プレイヤーデータのクラス

using System;
using UnityEngine;

[Serializable] // JSON化するにはこの属性が必要
public class PlayerData
{
public string playerName;
public int level;
public float health;
}

このクラスでは、以下の情報を保存できるようにしています。

  • playerName(プレイヤー名)
  • level(レベル)
  • health(体力)

このPlayerDataを使って、JSON形式でデータを保存・読み込む処理を実装します。


JSONファイルへの書き出し(System.IOを使ったファイル操作)

次に、System.IO を利用してJSONデータをファイルに保存するスクリプトを作成します。

データの保存処理

using UnityEngine;
using System.IO;

public class SaveLoadManager : MonoBehaviour
{
private string filePath;

void Start()
{
// 保存するファイルのパスを設定
filePath = Path.Combine(Application.persistentDataPath, "saveData.json");

// ゲームデータを保存
SaveGame();
}

public void SaveGame()
{
// 保存するプレイヤーデータを作成
PlayerData player = new PlayerData();
player.playerName = "勇者";
player.level = 10;
player.health = 95.5f;

// JSONに変換
string jsonData = JsonUtility.ToJson(player, true); // true で見やすいフォーマットにする

// ファイルに書き込み
File.WriteAllText(filePath, jsonData);

Debug.Log("データを保存しました: " + filePath);
}
}

コードの解説

JsonUtility.ToJson(player, true) でオブジェクトをJSON形式に変換
File.WriteAllText(filePath, jsonData) でJSONデータをファイルに保存
Application.persistentDataPath を使用することで、プラットフォームごとに適切な保存先を自動的に設定

🔹 Application.persistentDataPath の保存先例:

  • Windows: C:\Users\ユーザー名\AppData\LocalLow\会社名\ゲーム名\
  • Android: /data/data/パッケージ名/files/
  • iOS: Documents/

このスクリプトを実行すると、指定したフォルダ内にsaveData.jsonというファイルが作成され、JSON形式でデータが保存されます。

保存されるJSONデータの例(ファイルの中身)

{
"playerName": "勇者",
"level": 10,
"health": 95.5
}



JSONファイルからの読み込みと復元

保存したデータをゲーム内で復元するには、JSONファイルを読み込んで、C#のオブジェクトに変換する処理を追加します。

データのロード処理

public void LoadGame()
{
// セーブデータが存在するかチェック
if (File.Exists(filePath))
{
// JSONデータをファイルから読み込む
string jsonData = File.ReadAllText(filePath);

// JSONをC#のオブジェクトに変換
PlayerData loadedPlayer = JsonUtility.FromJson<PlayerData>(jsonData);

// ロードしたデータを表示
Debug.Log($"ロード成功! 名前: {loadedPlayer.playerName}, レベル: {loadedPlayer.level}, 体力: {loadedPlayer.health}");
}
else
{
Debug.LogWarning("セーブデータが見つかりません");
}
}

コードの解説

File.Exists(filePath) でセーブデータの存在を確認
File.ReadAllText(filePath) でJSONデータを取得
JsonUtility.FromJson<PlayerData>(jsonData) でC#のオブジェクトに変換

このスクリプトを実行すると、JSONデータが読み込まれ、ゲーム内で復元できるようになります。


完全版:ボタンでセーブ&ロード

ボタンを押したらセーブやロードができるように、UIと連携した完全版のスクリプトを作成しましょう。

using UnityEngine;
using UnityEngine.UI;
using System.IO;

public class SaveLoadSystem : MonoBehaviour
{
private string filePath;
public Text statusText; // UIに状態を表示するためのTextコンポーネント

void Start()
{
filePath = Path.Combine(Application.persistentDataPath, "saveData.json");
}

public void SaveGame()
{
PlayerData player = new PlayerData();
player.playerName = "勇者";
player.level = 15;
player.health = 120.0f;

string jsonData = JsonUtility.ToJson(player, true);
File.WriteAllText(filePath, jsonData);

Debug.Log("データを保存しました");
statusText.text = "データを保存しました!";
}

public void LoadGame()
{
if (File.Exists(filePath))
{
string jsonData = File.ReadAllText(filePath);
PlayerData loadedPlayer = JsonUtility.FromJson<PlayerData>(jsonData);

Debug.Log($"ロード成功! 名前: {loadedPlayer.playerName}, レベル: {loadedPlayer.level}, 体力: {loadedPlayer.health}");
statusText.text = $"ロード完了: {loadedPlayer.playerName}, Lv.{loadedPlayer.level}";
}
else
{
Debug.LogWarning("セーブデータがありません");
statusText.text = "セーブデータが見つかりません";
}
}
}

このスクリプトを使えば、UnityのUI(ボタン)からセーブ&ロードを実行できます!

  1. Canvasを作成
  2. Textコンポーネント(statusText)を追加
  3. ボタンを2つ作成(「セーブ」「ロード」)
  4. ボタンのOnClick()SaveGame()LoadGame() を紐付け

まとめ

JsonUtility を使うことで簡単にオブジェクトをJSONに変換できる
System.IO を活用してJSONデータをファイルに保存&読み込みができる
UIと連携すれば、ボタンでセーブ&ロードが簡単に実装可能!

「JSONを使ったセーブ・ロードは手軽に実装できますが、データの暗号化やクラウド保存、直感的なUIを活用して簡単にデータを管理したい場合は、Easy Saveのようなアセットを活用するのもおすすめです。
Easy Saveは、JSONやバイナリ形式でのデータ保存・読み込みを簡単にし、セキュリティ対策やクラウド対応もサポートしています。
Easy Saveの詳細はこちら

この方法を使えば、プレイヤーデータや設定情報をJSON形式で安全に管理し、どんなゲームにも応用できるセーブ&ロードシステムを作成できます!




5. データ管理を最適化するテクニック

ゲーム開発では、セーブデータが増えてくると、単純なJSONの保存・読み込みだけでは処理の最適化データの安全性が課題になります。このセクションでは、データ構造の整理、複雑なデータのJSON化、JSONの圧縮・暗号化といった、実践的な最適化テクニックを解説します。


データ構造を整理する方法(クラス設計のポイント)

データ管理を最適化するためには、適切なデータ構造を設計することが重要です。
クラス設計の際に気をつけるべきポイントは以下の3つです。

1. 1つのクラスに情報を詰め込みすぎない

悪い例(すべてのデータを1つのクラスで管理)

[System.Serializable]
public class GameData
{
public string playerName;
public int level;
public float health;
public int gold;
public int[] inventory; // アイテムのIDリスト
public int currentStage;
public bool[] unlockedStages;
}

➡ この設計の問題点

  • データが増えると、メンテナンスが大変
  • クラスが肥大化し、再利用しにくい

2. 関連するデータごとに分割する

良い例(データを分けて整理)

[System.Serializable]
public class PlayerData
{
public string playerName;
public int level;
public float health;
}

[System.Serializable]
public class InventoryData
{
public List<int> itemIDs; // アイテムのIDリスト
}

[System.Serializable]
public class GameProgress
{
public int currentStage;
public List<int> unlockedStages;
}

[System.Serializable]
public class GameData
{
public PlayerData player;
public InventoryData inventory;
public GameProgress progress;
}

➡ メリット

  • データの管理がシンプルになり、拡張しやすい
  • 各クラスを単独でテストできる
  • データの入れ替えが容易になる



複雑なデータ構造をJSONに変換する方法(リスト・ネスト構造)

ゲームデータが複雑になると、リストやネストされたデータ構造をJSONに変換する必要があります。
例えば、アイテムを持つプレイヤーデータをJSON化する場合を考えてみましょう。

リストを含むJSONデータ

[System.Serializable]
public class Item
{
public string itemName;
public int itemID;
}

[System.Serializable]
public class PlayerInventory
{
public List<Item> items;
}

JSONに変換する

void SaveInventory()
{
PlayerInventory inventory = new PlayerInventory();
inventory.items = new List<Item>()
{
new Item { itemName = "ポーション", itemID = 1 },
new Item { itemName = "エリクサー", itemID = 2 }
};

string jsonData = JsonUtility.ToJson(inventory, true);
Debug.Log(jsonData);
}

出力されるJSONデータ

{
"items": [
{
"itemName": "ポーション",
"itemID": 1
},
{
"itemName": "エリクサー",
"itemID": 2
}
]
}

JSONからデータを復元

void LoadInventory(string jsonData)
{
PlayerInventory loadedInventory = JsonUtility.FromJson<PlayerInventory>(jsonData);

foreach (var item in loadedInventory.items)
{
Debug.Log($"アイテム: {item.itemName}, ID: {item.itemID}");
}
}

➡ メリット

  • リストやオブジェクトの入れ子(ネスト)を使うことで、JSONをより柔軟に管理できる
  • ゲームのデータ構造を現実に即した形で表現できる



JSON圧縮・暗号化の方法(GZipStreamやAES暗号化)

セーブデータが増えると、ファイルサイズが大きくなったり、JSONの中身がそのまま見えてしまう問題があります。
そこで、データの圧縮と暗号化を行い、安全かつ効率的に保存する方法を紹介します。


1. JSONデータをGZipStreamで圧縮

GZipStream を使うと、JSONデータのサイズを圧縮できます。

圧縮処理
using System.IO;
using System.IO.Compression;
using System.Text;

public static byte[] CompressJson(string json)
{
byte[] jsonData = Encoding.UTF8.GetBytes(json);
using (MemoryStream memoryStream = new MemoryStream())
{
using (GZipStream gzipStream = new GZipStream(memoryStream, CompressionMode.Compress))
{
gzipStream.Write(jsonData, 0, jsonData.Length);
}
return memoryStream.ToArray();
}
}
解凍処理
public static string DecompressJson(byte[] compressedData)
{
using (MemoryStream memoryStream = new MemoryStream(compressedData))
{
using (GZipStream gzipStream = new GZipStream(memoryStream, CompressionMode.Decompress))
{
using (StreamReader reader = new StreamReader(gzipStream, Encoding.UTF8))
{
return reader.ReadToEnd();
}
}
}
}

➡ メリット

  • データサイズを削減できる(特に大きなJSONファイルに有効)
  • ゲームのロード速度を向上できる

2. AES暗号化でJSONを保護

プレイヤーのセーブデータがそのまま見えてしまうと改ざんのリスクがあります。AES暗号化を使えば、JSONデータを保護できます。

暗号化処理
using System.Security.Cryptography;

public static byte[] EncryptJson(string json, string key)
{
using (Aes aes = Aes.Create())
{
aes.Key = Encoding.UTF8.GetBytes(key);
aes.IV = new byte[16]; // IVはゼロ初期化(本番環境では適切なIVを使用)

using (MemoryStream memoryStream = new MemoryStream())
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, aes.CreateEncryptor(), CryptoStreamMode.Write))
{
byte[] jsonData = Encoding.UTF8.GetBytes(json);
cryptoStream.Write(jsonData, 0, jsonData.Length);
cryptoStream.FlushFinalBlock();
return memoryStream.ToArray();
}
}
}
復号化処理
public static string DecryptJson(byte[] encryptedData, string key)
{
using (Aes aes = Aes.Create())
{
aes.Key = Encoding.UTF8.GetBytes(key);
aes.IV = new byte[16];

using (MemoryStream memoryStream = new MemoryStream(encryptedData))
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, aes.CreateDecryptor(), CryptoStreamMode.Read))
using (StreamReader reader = new StreamReader(cryptoStream, Encoding.UTF8))
{
return reader.ReadToEnd();
}
}
}

➡ メリット

  • セーブデータを改ざんされにくくする
  • プレイヤーのプライバシーを守る

まとめ

データ構造を整理すると管理が楽になる
リストやネストを活用して複雑なデータをJSON化できる
GZipでJSONを圧縮するとデータサイズを削減できる
AES暗号化を使えばセーブデータを保護できる

この最適化テクニックを活用すれば、より安全で効率的なデータ管理が可能になります!




6. 実践!JSONを使ったセーブ・ロードのサンプルプロジェクト

ここでは、JSONを使って簡単なRPG風のセーブ&ロードシステムを作成します。
プレイヤーのHP、MP、経験値をJSONファイルに保存し、ボタンでセーブ&ロードできる仕組みを実装します。


1. プロジェクトの準備

🔹 必要なUI要素を作成

  1. Canvas を作成
  2. Text コンポーネントを3つ 作成(HP、MP、経験値の表示)
  3. Button コンポーネントを2つ 作成(「セーブ」「ロード」ボタン)
  4. ボタンのOnClick() にスクリプトの関数を設定(後で作成)

2. セーブ&ロードするデータ構造の作成

まずは、プレイヤーデータのクラスを作成します。

using System;
using UnityEngine;

[Serializable] // JSON化するために必要
public class PlayerData
{
public string playerName;
public int hp;
public int mp;
public int experience;
}

🔹 このクラスで管理するデータ

  • playerName(プレイヤー名)
  • hp(ヒットポイント)
  • mp(マジックポイント)
  • experience(経験値)

3. JSONを使ったセーブ&ロード機能を実装

次に、セーブ&ロード処理を行うスクリプトを作成します。

using UnityEngine;
using UnityEngine.UI;
using System.IO;

public class SaveLoadSystem : MonoBehaviour
{
private string filePath; // セーブデータの保存先

public Text hpText;
public Text mpText;
public Text expText;
public Text statusText;

private PlayerData player;

void Start()
{
// 保存先のファイルパスを設定
filePath = Path.Combine(Application.persistentDataPath, "playerData.json");

// 初期データを設定
player = new PlayerData
{
playerName = "勇者",
hp = 100,
mp = 50,
experience = 0
};

// UIに反映
UpdateUI();
}

// 🔹 セーブ処理
public void SaveGame()
{
string jsonData = JsonUtility.ToJson(player, true);
File.WriteAllText(filePath, jsonData);

Debug.Log("データを保存しました: " + filePath);
statusText.text = "データを保存しました!";
}

// 🔹 ロード処理
public void LoadGame()
{
if (File.Exists(filePath))
{
string jsonData = File.ReadAllText(filePath);
player = JsonUtility.FromJson<PlayerData>(jsonData);

Debug.Log("データをロードしました!");
statusText.text = "データをロードしました!";

// UIを更新
UpdateUI();
}
else
{
Debug.LogWarning("セーブデータが見つかりません");
statusText.text = "セーブデータが見つかりません";
}
}

// 🔹 UIを更新する
private void UpdateUI()
{
hpText.text = $"HP: {player.hp}";
mpText.text = $"MP: {player.mp}";
expText.text = $"経験値: {player.experience}";
}

// 🔹 プレイヤーのステータスを変更する(テスト用)
public void GainExperience()
{
player.experience += 10;
player.hp -= 5; // HPを少し減らす
player.mp -= 3; // MPを少し減らす
UpdateUI();
}
}



4. UnityのUIボタンとスクリプトを接続

🔹 ボタンの設定

  1. 「セーブ」ボタンOnClick()SaveGame() を設定
  2. 「ロード」ボタンOnClick()LoadGame() を設定
  3. 「経験値+10」ボタン(任意) を作成し GainExperience() を追加

5. 実行して確認

🔹 テスト手順

  1. Unityのエディターで「経験値+10」ボタンを押して、プレイヤーの経験値を増やす
  2. 「セーブ」ボタンを押して、JSONファイルにデータを保存
  3. Unityを再起動して「ロード」ボタンを押す
  4. 前回のプレイ時のデータが復元されていれば成功!

6. 実際に保存されるJSONデータ

保存されたJSONデータを開くと、以下のようなデータが確認できます。

{
"playerName": "勇者",
"hp": 95,
"mp": 47,
"experience": 10
}

このように、プレイヤーの状態が正しく記録されていることがわかります。


7. まとめ

JSONを使ってプレイヤーのデータをセーブ&ロードできるようになった
UIを使ってボタンで簡単に操作できるようにした
実際にJSONファイルが保存され、データの永続化ができることを確認した

この仕組みを応用すれば、RPGやアクションゲームでキャラクターの進行データやアイテム、クエスト進行状況などをJSON形式で管理することが可能になります!




7. まとめ

ここまで、UnityでJSONを活用したセーブ&ロードシステムの作り方を解説してきました。
JSONを使うことで、データの保存や管理が簡単になり、ゲームの進行データ、プレイヤーステータス、設定情報などを手軽に扱えるようになります。


JSONを活用することでデータ管理が簡単になる

可読性が高い → JSONはテキスト形式なので、人間が直接編集しやすく、デバッグしやすい
柔軟なデータ構造 → オブジェクトやリストをそのまま保存できるため、複雑なデータ管理に対応
汎用性が高い → 他のプログラムやサーバーとデータのやり取りが容易

特に、プレイヤーの進行状況やアイテムリスト、ステージ情報を簡単に保存・復元できるのがJSONの大きな利点です。


さらに発展させるには(クラウド保存・オンライン同期など)

JSONを活用したセーブ&ロードの仕組みを発展させることで、より便利なデータ管理が可能になります。

1. クラウド保存

ローカルのJSONファイルに保存するのではなく、Google FirebasePlayFab などのクラウドサービスを利用すると、オンラインでデータを管理できます。

  • メリット
    • 複数のデバイス間でデータを同期できる
    • オンラインランキングやユーザープロフィールの管理が可能
    • クラウドバックアップによりデータ消失のリスクを減らせる
  • 方法
    • FirebaseのRealtime DatabaseFirestore を使用
    • PlayFabを使ってJSON形式でプレイヤーデータをクラウドに保存

2. オンライン同期(サーバーとのデータやり取り)

JSONはサーバーとデータをやり取りするのにも適しています。例えば、REST API を利用して、JSON形式でデータを送受信することができます。

  • 例: UnityでAPI経由でデータを送る
using UnityEngine;
using UnityEngine.Networking;
using System.Collections;

public class DataUploader : MonoBehaviour
{
private string url = "https://example.com/upload";

public void UploadData(string jsonData)
{
StartCoroutine(PostRequest(url, jsonData));
}

IEnumerator PostRequest(string uri, string json)
{
UnityWebRequest request = new UnityWebRequest(uri, "POST");
byte[] bodyRaw = System.Text.Encoding.UTF8.GetBytes(json);
request.uploadHandler = new UploadHandlerRaw(bodyRaw);
request.downloadHandler = new DownloadHandlerBuffer();
request.SetRequestHeader("Content-Type", "application/json");

yield return request.SendWebRequest();

if (request.result == UnityWebRequest.Result.Success)
{
Debug.Log("データ送信成功: " + request.downloadHandler.text);
}
else
{
Debug.LogError("データ送信失敗: " + request.error);
}
}
}

このように、JSONデータをサーバーに送信することで、ゲームのクラウド同期が実現できます。




次に学ぶべき関連技術

JSONを使ったデータ管理に慣れてきたら、次の技術も学んでみましょう。

1. ScriptableObject

JSONよりも高速で、エディターで管理しやすいデータ保存方法

  • 設定データやキャラクターのパラメータなどを保存するのに便利
  • JSONのように外部ファイルを使わず、Unityエディター上で直感的に管理できる
  • ただし、データの永続化(セーブ&ロード)には向いていないので、JSONと併用するのがベスト

🔹 ScriptableObjectの基本

using UnityEngine;

[CreateAssetMenu(fileName = "NewPlayerData", menuName = "Game Data/Player")]
public class PlayerData : ScriptableObject
{
public string playerName;
public int level;
public float health;
}

2. PlayerPrefs

小さな設定データを保存するならJSONよりも簡単な方法

  • 音量設定やグラフィック設定など、単純なデータを保存するのに便利
  • しかし、ゲームの進行データなど大きなデータの保存には向いていない

🔹 PlayerPrefsの基本

PlayerPrefs.SetInt("HighScore", 100);
int highScore = PlayerPrefs.GetInt("HighScore", 0);

JSONと使い分けるべきポイント

保存方法メリットデメリット向いている用途
JSONファイルデータ構造が柔軟、大量のデータを扱えるファイル操作が必要プレイヤーデータ、アイテムリスト
ScriptableObject高速でエディター管理しやすい永続的な保存ができないゲームのバランス調整データ
PlayerPrefs手軽に設定を保存できる大量のデータには向かないサウンド設定、言語設定

まとめ

JSONを使うことで、簡単にデータを保存&ロードできるようになった
クラウド保存やAPI通信を活用すれば、オンライン同期も可能
ScriptableObjectやPlayerPrefsと使い分けることで、最適なデータ管理ができる

「JSONを使ったデータ管理は便利ですが、実装コストを抑えて、より直感的に管理したいならEasy Saveを活用するのもおすすめです。
手間をかけずにゲームのセーブ・ロード機能を強化したい方は、ぜひチェックしてみてください!
Easy Saveの詳細はこちら

これで、UnityでJSONを活用したデータ管理の基礎から応用までを学ぶことができました!
次のステップとして、クラウド保存やデータの暗号化など、さらに高度なテクニックを取り入れてみましょう! 🚀




よくある質問(FAQ)

Q
PlayerPrefsとJsonUtilityはどちらが良い?
A

▶ どちらを使うべきかは、保存するデータの種類によります。

PlayerPrefsJsonUtility
データ形式int, float, string のみオブジェクト、リスト、ネスト構造のデータもOK
データ量少量(設定データなど)多量(ゲーム進行データなど)
保存場所レジストリ(Windows)やPlayerPrefsファイル(Mac, iOS, Android)Application.persistentDataPath にJSONファイルとして保存
用途音量設定、画面解像度、キー設定などプレイヤーデータ、アイテムリスト、クエスト進行状況など

PlayerPrefsが向いているケース

  • 音量、言語設定、グラフィック設定などの小さなデータ
  • SetInt()SetFloat()SetString() だけで簡単に保存できる

JsonUtilityが向いているケース

  • プレイヤーのステータス、アイテムリスト、ストーリー進行などのデータを保存したい場合
  • データの構造が複雑で、リストやオブジェクトを扱う必要がある場合

結論:
小さな設定データ → PlayerPrefs
ゲーム進行データ → JsonUtility(JSONファイル)



Q
JSONファイルを暗号化する方法は?
A

▶ JSONデータを暗号化するには、AES暗号化を使うのが一般的です。
JSONデータはテキスト形式のため、そのままではプレイヤーに改ざんされるリスクがあります。
AES暗号化を施すことで、データを安全に保護できます。

🔹 AES暗号化を使ったJSONデータの保護

🔐 JSONを暗号化して保存
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using UnityEngine;

public class Encryptor
{
private static readonly string key = "1234567890123456"; // 16文字の秘密鍵(実際は安全に管理する)

public static byte[] Encrypt(string json)
{
using (Aes aes = Aes.Create())
{
aes.Key = Encoding.UTF8.GetBytes(key);
aes.IV = new byte[16]; // 固定のIV(本番環境ではランダム化する)

using (MemoryStream memoryStream = new MemoryStream())
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, aes.CreateEncryptor(), CryptoStreamMode.Write))
{
byte[] jsonData = Encoding.UTF8.GetBytes(json);
cryptoStream.Write(jsonData, 0, jsonData.Length);
cryptoStream.FlushFinalBlock();
return memoryStream.ToArray();
}
}
}
}
🔓 JSONを復号してロード
public static string Decrypt(byte[] encryptedData)
{
using (Aes aes = Aes.Create())
{
aes.Key = Encoding.UTF8.GetBytes(key);
aes.IV = new byte[16];

using (MemoryStream memoryStream = new MemoryStream(encryptedData))
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, aes.CreateDecryptor(), CryptoStreamMode.Read))
using (StreamReader reader = new StreamReader(cryptoStream, Encoding.UTF8))
{
return reader.ReadToEnd();
}
}
}

🔹 メリット ✔ セーブデータを改ざんされにくくなる
✔ プレイヤーのプライバシーを守れる

🔹 デメリット ❌ 暗号化&復号化の処理が増えるため、若干処理が重くなる
❌ 秘密鍵(key)を安全に管理する必要がある

➡ ゲームのチート対策やセキュリティが必要な場合におすすめ!



Q
JsonUtilityとNewtonsoft.Jsonの違いは?
A

▶ JsonUtilityとNewtonsoft.JsonはどちらもC#でJSONを扱うためのツールですが、特徴が異なります。

JsonUtility(Unity標準)Newtonsoft.Json(外部ライブラリ)
パフォーマンス高速(Unityに最適化)比較的遅い(機能が豊富な分オーバーヘッドがある)
機能シンプル(基本的なJSON変換のみ)リストやDictionaryのサポート、データフォーマット制御が可能
リストのサポート直接はサポートしていない(ラップする必要あり)ネスト構造、配列、リスト、Dictionaryも直接変換可能
外部ライブラリの必要性不要(Unity標準機能)必要(NuGetやUnity Asset Storeからインストール)
用途基本的なJSONのセーブ&ロード複雑なデータ構造やAPI通信でのデータ処理

1. JsonUtilityを使った場合

using UnityEngine;

[System.Serializable]
public class Player
{
public string name;
public int level;
}

void Save()
{
Player player = new Player() { name = "勇者", level = 10 };
string json = JsonUtility.ToJson(player);
Debug.Log(json);
}

出力

{"name":"勇者","level":10}

🔹 メリット ✔ Unityに標準搭載されており、軽量&高速
✔ 使い方がシンプルで、パフォーマンスが良い

🔹 デメリットリストやDictionaryのサポートが不十分
❌ JSONのキー名を変更できない(C#の変数名がそのまま使われる)


2. Newtonsoft.Jsonを使った場合
using Newtonsoft.Json;
using System.Collections.Generic;
using UnityEngine;

public class Player
{
public string name;
public int level;
public List<string> items;
}

void Save()
{
Player player = new Player() { name = "勇者", level = 10, items = new List<string> { "剣", "盾" } };
string json = JsonConvert.SerializeObject(player, Formatting.Indented);
Debug.Log(json);
}

出力

jsonコピーする編集する{
    "name": "勇者",
    "level": 10,
    "items": ["剣", "盾"]
}

🔹 メリットリストやDictionaryをそのままJSON化できる
カスタムフォーマット、キー名の変更、JSONの制御が可能
REST APIやクラウドデータの処理に最適

🔹 デメリット ❌ 外部ライブラリ(Newtonsoft.Json.dll)のインストールが必要
❌ JsonUtilityより少し処理が遅い

**➡ Unityの基本的なセーブ&ロードなら JsonUtility
**➡ 複雑なデータ構造を扱うなら Newtonsoft.Json

タイトルとURLをコピーしました