この記事について
この記事では JsonUtility を使ってデータを保存・読み込みする方法について解説します。
クラスを JSON 形式に変換して保存できるため、セーブデータやアイテム管理などに便利です。
さらに、データの存在確認、パスワードチェック、暗号化(Base64 / AES) についても紹介します。

この記事でわかること
- JsonUtility とは何か
- ToJson / FromJson でデータを保存・読み込みできる
- データの存在確認(File.Exists(filePath))
- JSON文字列の暗号化(Base64 / AES)
JsonUtilityとは?
JsonUtilityは Unityが提供するJSONシリアライズ機能 です。
クラスや構造体を JSON 文字列に変換(保存)、または JSON 文字列をクラスに変換(読み込み)できます。
※勘違いしやすいですがJsonUtilityがデータの保存・読み込みをするのではなく、「保存するための構造体」みたいなものです。
特徴
- 軽量で高速(Unity 内部に最適化された仕組み)
- public フィールドのみ対象(プロパティや private は保存されない)
- [Serializable] 属性が必要
JsonUtilityの準備
まずはヒエラルキーで右クリックをして空のGameObjectを1つ用意します。
・「右クリック」→「Create Empty」
次にスクリプトを作成して先ほどのCreate Emptyにアタッチしてください。

JsonUtilityの保存・存在確認・読み込み
クラスを定義する
JsonUtilityを使用する場合はデータの構造を「クラス+[System.Serializable]」で書いておく必要があります。
[System.Serializable]
public class PlayerData
{
public string Name;
public int Level;
public float Score;
public string password; // パスワード(後でチェック用)
}
JsonUtility.ToJson()でデータを保存する
データの保存にはPlayerPrefsやクラウド保存もできますが今回はFileを使用します。
また、保存前にJSONに変換するために「JsonUtility.ToJson(クラス名,prettyPrint)」で変換します。
※prettyPrintはtrueで一行にまとめる、falseで改行をしてくれます。
using System.IO;
using UnityEngine;
[System.Serializable]
public class PlayerData
{
public string Name;
public int Level;
public float Score;
public string password; // パスワード(後でチェック用)
}
public class Data_JsonUtility : MonoBehaviour
{
private string filePath;
void Start()
{
filePath = Application.persistentDataPath + "/playerData.json";
PlayerData data = new PlayerData();
data.Name = "No Name";
data.Level = 100;
data.Score = 12.3f;
data.password = "MySecret";
// JSONに変換
string json = JsonUtility.ToJson(data, true);
// ファイルに保存
File.WriteAllText(filePath, json);
Debug.Log("保存完了: " + filePath);
}
}
実行してみると、構造通りにデータが保存されていることがわかりますね。
※Application.persistentDataPathを使うと、スマホでもPCでもアプリごとに専用の保存場所を取得できます。


JsonUtility.FromJson()でデータを読み込む
データの読み込みにもPlayerPrefsやクラウド保存もできますが今回はFileを使用します。
また、読み込み時にデータの存在確認「File.Exists(filePath)」とJSONから変換するために「JsonUtility.FromJson()<クラス名>」で変換します。
using System.IO;
using UnityEngine;
[System.Serializable]
public class PlayerData
{
public string Name;
public int Level;
public float Score;
public string password; // パスワード(後でチェック用)
}
public class Data_JsonUtility : MonoBehaviour
{
private string filePath;
private string Dummy_filePath; //ダミーパス
void Start()
{
filePath = Application.persistentDataPath + "/playerData.json";
Dummy_filePath = Application.persistentDataPath + "/player.json";
//データが存在しない場合
if (!File.Exists(Dummy_filePath))
{
Debug.Log("データが存在しません");
}
//データが存在する場合
if (File.Exists(filePath))
{
string json = File.ReadAllText(filePath);
PlayerData loadedData = JsonUtility.FromJson<PlayerData>(json);
Debug.Log("名前: " + loadedData.Name);
Debug.Log("レベル: " + loadedData.Level);
Debug.Log("スコア: " + loadedData.Score);
Debug.Log("パスワード: " + loadedData.password);
}
}
}
実行してみると、Jsonで保存していたデータが読み込みできましたね。今回は実装しませんでしたが、Jsonの中にパスワードを入れているので、簡易的なパスワードチェックは実装できますね。

JSON文字列の暗号化
※暗号化の知識はないので実装方法のみ今回は記載しています。
Base64(簡易)で暗号化をする
Base64でデータの保存
直接読まれたくない場合はBase64で隠すだけでも効果があります。
using System;
using System.IO;
using UnityEditor.Overlays;
using UnityEngine;
[System.Serializable]
public class PlayerData
{
public string Name;
public int Level;
public float Score;
public string password; // パスワード(後でチェック用)
}
public class Data_JsonUtility : MonoBehaviour
{
private string filePath;
void Start()
{
filePath = Application.persistentDataPath + "/playerData.json";
PlayerData data = new PlayerData();
data.Name = "No Name";
data.Level = 100;
data.Score = 12.3f;
data.password = "MySecret";
Save(data);
}
// 保存
public void Save(PlayerData data)
{
string json = JsonUtility.ToJson(data);
string enc = Base64Helper.Encrypt(json);
File.WriteAllText(filePath, enc);
Debug.Log("保存完了");
}
}
//Base64に暗号化
public static class Base64Helper
{
public static string Encrypt(string plainText)
{
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(plainText);
return Convert.ToBase64String(bytes);
}
}
実行してみると、暗号化されていて難読化し何を書いているのかさっぱりですね。

Base64でデータの読み込み
次はこの暗号化されたファイルで読み込みを行っていきます。
using System;
using System.IO;
using UnityEditor.Overlays;
using UnityEngine;
[System.Serializable]
public class PlayerData
{
public string Name;
public int Level;
public float Score;
public string password; // パスワード(後でチェック用)
}
public class Data_JsonUtility : MonoBehaviour
{
private string filePath;
void Start()
{
filePath = Application.persistentDataPath + "/playerData.json";
PlayerData data = new PlayerData();
data = Load();
Debug.Log("名前: " + data.Name);
Debug.Log("レベル: " + data.Level);
Debug.Log("スコア: " + data.Score);
Debug.Log("パスワード: " + data.password);
}
// 読み込み
public PlayerData Load()
{
if (!File.Exists(filePath))
{
Debug.LogWarning("セーブデータがありません");
return null;
}
string enc = File.ReadAllText(filePath);
string json = Base64Helper.Decrypt(enc);
return JsonUtility.FromJson<PlayerData>(json);
}
}
//Base64の暗号化を解読
public static class Base64Helper
{
public static string Decrypt(string encodedText)
{
byte[] bytes = Convert.FromBase64String(encodedText);
return System.Text.Encoding.UTF8.GetString(bytes);
}
}
実行してみると暗号化はそのままで読み込めました。

AES(本格的)で暗号化する
AESでデータの保存
セーブデータを改ざんされにくくしたいなら AES暗号化 を使う方法もあります。
※暗号化は必ずしも解読されないというものではありません。(絶対に侵入されない暗号化は投稿者も見つけられておりません。)
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using UnityEditor.Overlays;
using UnityEngine;
using UnityEngine.InputSystem;
[System.Serializable]
public class PlayerData
{
public string Name;
public int Level;
public float Score;
public string password; // パスワード(後でチェック用)
}
public class Data_JsonUtility : MonoBehaviour
{
private string filePath;
void Start()
{
filePath = Application.persistentDataPath + "/playerData.json";
PlayerData data = new PlayerData();
data.Name = "No Name";
data.Level = 100;
data.Score = 12.3f;
data.password = "MySecret";
Save(data);
}
public void Save(PlayerData data)
{
string json = JsonUtility.ToJson(data);
string enc = AESHelper.Encrypt(json);
File.WriteAllText(filePath, enc);
Debug.Log("AES保存完了");
}
public PlayerData Load()
{
if (!File.Exists(filePath))
{
Debug.LogWarning("AESセーブデータがありません");
return null;
}
string enc = File.ReadAllText(filePath);
string json = AESHelper.Decrypt(enc);
return JsonUtility.FromJson<PlayerData>(json);
}
}
//AESで暗号化
public static class AESHelper
{
private static readonly string Key = "12345678901234567890123456789012"; // 32文字(256bit)
private static readonly string IV = "1234567890123456"; // 16文字(128bit)
public static string Encrypt(string plainText)
{
using (Aes aes = Aes.Create())
{
aes.Key = Encoding.UTF8.GetBytes(Key);
aes.IV = Encoding.UTF8.GetBytes(IV);
ICryptoTransform encryptor = aes.CreateEncryptor();
using (MemoryStream ms = new MemoryStream())
using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
using (StreamWriter sw = new StreamWriter(cs))
{
sw.Write(plainText);
sw.Close();
return Convert.ToBase64String(ms.ToArray());
}
}
}
}
実行してみると、暗号化されていますね。
AESなら「鍵(Key, IV)」を知らないと復号できないので、単なるBase64より安全です。

AESでデータの読み込み
次はこの暗号化されたファイルで読み込みを行っていきます。
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using UnityEditor.Overlays;
using UnityEngine;
using UnityEngine.InputSystem;
[System.Serializable]
public class PlayerData
{
public string Name;
public int Level;
public float Score;
public string password; // パスワード(後でチェック用)
}
public class Data_JsonUtility : MonoBehaviour
{
private string filePath;
void Start()
{
filePath = Application.persistentDataPath + "/playerData.json";
PlayerData data = new PlayerData();
data = Load();
Debug.Log("名前: " + data.Name);
Debug.Log("レベル: " + data.Level);
Debug.Log("スコア: " + data.Score);
Debug.Log("パスワード: " + data.password);
}
public PlayerData Load()
{
if (!File.Exists(filePath))
{
Debug.LogWarning("AESセーブデータがありません");
return null;
}
string enc = File.ReadAllText(filePath);
string json = AESHelper.Decrypt(enc);
return JsonUtility.FromJson<PlayerData>(json);
}
}
//AESの暗号化を解読
public static class AESHelper
{
private static readonly string Key = "12345678901234567890123456789012"; // 32文字(256bit)
private static readonly string IV = "1234567890123456"; // 16文字(128bit)
public static string Decrypt(string cipherText)
{
using (Aes aes = Aes.Create())
{
aes.Key = Encoding.UTF8.GetBytes(Key);
aes.IV = Encoding.UTF8.GetBytes(IV);
ICryptoTransform decryptor = aes.CreateDecryptor();
byte[] buffer = Convert.FromBase64String(cipherText);
using (MemoryStream ms = new MemoryStream(buffer))
using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
using (StreamReader sr = new StreamReader(cs))
{
return sr.ReadToEnd();
}
}
}
}
実行してみると暗号化はそのままで読み込めました。

注意点
- [Serializable] を忘れると保存されない
- 保存できるのは public フィールドのみ
- Base64 はあくまで「難読化」、セキュリティにはならない
- AES は強力だが「Key, IV」をソースコード内に書くとバレる可能性あり
→ 本格的なセキュリティが必要なら サーバー管理 がベスト
補足
Base64とは?
- 正式名称:Base64 Encoding
- 意味:
- データを 64種類の文字(A–Z, a–z, 0–9, +, /)で表現するエンコード方式
- もともとバイナリデータ(画像やファイルなど)を文字列として扱えるようにするために考案された方式
- 用途:
- メール(MIMEエンコード)
- JSONやXMLにバイナリを埋め込みたいとき
- 簡易的な難読化(暗号化ではない)
- 「Base64」は “基数64の変換方式” という意味です。
AESとは?
- 正式名称:Advanced Encryption Standard(高度暗号化標準)
- 意味:
- 2001年に米国標準技術研究所(NIST)が採用した 共通鍵暗号方式 の標準規格
- Rijndael(ラインダール)という暗号方式が採用され、現在もっとも広く使われている暗号化規格
- 用途:
- HTTPS 通信
- Wi-Fi (WPA2, WPA3)
- ファイル暗号化、銀行・政府機関のセキュリティ
- 「AES」は “高度暗号化規格” という意味で、世界標準の暗号方式です。
まとめ
- JsonUtility → データを JSON 化して保存・読み込み
- File.Exists(filePath) → 存在確認できる
- Base64 → 簡易暗号化(改ざん防止には不十分)
- AES → 本格的にデータを守りたいときに有効