ExtPlayerPrefs 技術資料

概要

ExtPlayerPrefs は Unity 環境でオブジェクトのデータを JSON 形式でファイルに保存・読み出しするための拡張クラスです。このクラスは暗号化機能をサポートし、オブジェクトを永続化するためのシンプルな API を提供します。また、非同期処理をサポートしており、パフォーマンスの向上も図れます。

主な機能

  • 任意のオブジェクトの保存・読み出し(同期版・非同期版)
  • ScriptableObject の保存・読み出し(同期版のみ)
  • プリミティブオブジェクトの保存・読み出し
  • ファイルの暗号化と復号化のサポート

メソッド解説

1. オブジェクトの保存と読み出し

1.1 オブジェクトの保存(同期版)

public static string Save<T>(T obj, string fileName, string pass = null, string customPath = null)
パラメータ
  • T obj: 保存するオブジェクト。null の場合は ArgumentNullException が発生します。
  • fileName: 保存するファイル名。拡張子は自動的に .json になります。
  • pass: 暗号化キー。指定しない場合は暗号化されません。
  • customPath: 保存先のカスタムパス。指定しない場合はデフォルトで Application.persistentDataPath に保存されます。
戻り値
  • 保存した JSON データ(暗号化前のもの)を返します。
使用例
var data = new PlayerData { name = "Player1", score = 100 };
ExtPlayerPrefs.Save(data, "playerData.json", "encryptionKey");

1.2 プリミティブオブジェクトの保存(同期版)

対応可能なプリミティブ型には、intfloatstringbooldoublelongshort などがあります。これらのプリミティブ型の保存も、他のオブジェクトと同様に Save メソッドを使用して実行できます。

使用例
int highScore = 500;
ExtPlayerPrefs.Save(highScore, "highScore.json");

1.3 オブジェクトの読み出し(同期版)

public static T Load<T>(string fileName, string pass = null, string customPath = null)
パラメータ
  • fileName: 読み出すファイル名。
  • pass: 暗号化キー。保存時と同じキーを使用します。
  • customPath: 読み出し元のカスタムパス。指定しない場合は Application.persistentDataPath から読み出します。
戻り値
  • 読み出したオブジェクトを返します。ファイルが見つからない場合は FileNotFoundException が発生します。
使用例
var playerData = ExtPlayerPrefs.Load<PlayerData>("playerData.json", "encryptionKey");

1.4 プリミティブオブジェクトの読み出し(同期版)

対応可能なプリミティブ型には、intfloatstringbooldoublelongshort などがあります。これらのプリミティブ型の読み出しも、他のオブジェクトと同様に Load メソッドを使用して実行できます。

使用例
int loadedHighScore = ExtPlayerPrefs.Load<int>("highScore.json");

2. オブジェクトの保存(非同期版)

public static async Task<string> SaveAsync<T>(T obj, string fileName, string pass = null, string customPath = null)

説明

このメソッドは、オブジェクトを非同期で保存します。非同期処理により、メインスレッドの負荷を軽減し、ゲームの動作をスムーズに保ちます。

使用例
await ExtPlayerPrefs.SaveAsync(data, "playerData.json", "encryptionKey");

3. ScriptableObject の保存と読み出し

3.1 ScriptableObject の保存(同期版)

public static string SaveScriptableObject<T>(T obj, string fileName, string pass = null, string customPath = null) where T : ScriptableObject
説明

ScriptableObject の保存に対応しています。Unity 特有のデータ管理用オブジェクトを永続化するために利用します。

使用例
ExtPlayerPrefs.SaveScriptableObject(myScriptableObject, "scriptableData.json");

3.2 ScriptableObject の読み出し(同期版)

public static void LoadScriptableObject<T>(T obj, string fileName, string pass = null, string customPath = null) where T : ScriptableObject
説明

ScriptableObject の読み出しに使用します。読み出したデータを指定した ScriptableObject インスタンスに上書きします。

使用例
ExtPlayerPrefs.LoadScriptableObject(myScriptableObject, "scriptableData.json");

技術的なポイント

1. 暗号化機能

  • オブジェクトのデータは暗号化して保存することが可能です。Encryption.EncryptString メソッドで暗号化を行い、同様に DecryptString で復号化します。
  • 暗号化キーが一致しない場合、データの読み出しに失敗します。

2. 非同期処理の活用

  • 保存や読み出しに時間がかかる場合でも、ゲームの処理に影響を与えないように async/await を用いた非同期メソッドを提供しています。
  • 非同期メソッドを使うことで、メインスレッドをブロックせずにファイル操作ができます。

3. 汎用的なラッパークラス

  • 任意のオブジェクトをシリアライズするために Wrapper<T> を使用し、プリミティブ型や ScriptableObject のような特殊なオブジェクトも扱えるように設計しています。
  • プリミティブ型のデータ(例えば、intfloatstringbooldoublelongshort など)についても、このラッパークラスを使うことで統一的に保存・読み出しが可能です。

標準の PlayerPrefs との比較

メリット

  1. 暗号化機能のサポート
    • ExtPlayerPrefs ではデータを暗号化して保存できるため、ユーザーのセーブデータや機密性の高い情報を安全に管理することができます。
    • PlayerPrefs は暗号化されておらず、外部から簡単にアクセス・改ざんされるリスクがあります。
  2. 任意のオブジェクトの保存
    • ExtPlayerPrefs は任意のオブジェクトを JSON 形式で保存でき、クラスのインスタンスや複雑なデータ構造を簡単に保存できます。
    • PlayerPrefs では intfloatstring のみサポートしており、複雑なデータを保存するにはシリアライズの手間がかかります。
  3. 保存パスのカスタマイズ
    • ExtPlayerPrefs は保存パスをカスタマイズでき、データ管理の柔軟性が向上します。
    • PlayerPrefs はプラットフォームごとに決まった場所にデータを保存し、カスタマイズができません。
  4. 非同期処理のサポート
    • ExtPlayerPrefs は非同期保存・読み出しをサポートし、大量のデータを扱う際のパフォーマンス低下を防ぎます。
    • PlayerPrefs は同期処理のみで、大量のデータ保存時にパフォーマンスが低下する可能性があります。
  5. ファイルのアクセス権と管理
    • ExtPlayerPrefs ではファイルの存在確認やエラーハンドリングを細かく制御可能です。
    • PlayerPrefs ではエラーハンドリングが限定的であり、ファイルアクセスエラーに対処しにくいです。

デメリット

  1. 実装の複雑さ
    • ExtPlayerPrefs は JSON シリアライズや暗号化処理を含むため、PlayerPrefs よりもコーディングが複雑になります。
    • PlayerPrefs はシンプルで使いやすく、迅速に実装できます。
  2. パフォーマンスの影響
    • ExtPlayerPrefs ではシリアライズ・デシリアライズや暗号化処理により、パフォーマンスに影響を与える可能性があります。
    • PlayerPrefs は軽量でパフォーマンスに優れています。
  3. 保存場所の制限
    • ExtPlayerPrefs で保存するファイルは、プラットフォームのファイルシステムの制約に影響を受けることがあります。
    • PlayerPrefs ではプラットフォームごとに最適化された保存場所が提供され、開発者が保存場所を気にする必要がありません。
  4. セキュリティリスクの管理
    • ExtPlayerPrefs では暗号化キーの管理が必要で、キーの管理が不適切だとセキュリティリスクが高まります。
    • PlayerPrefs では暗号化をサポートしていないため、セキュリティに関してシンプルですが、データはすべてプレーンテキストで保存されます。

注意点

  • JSON データの不正: 読み出した JSON が正しくない場合、例外が発生します。保存・読み出しの際にオブジェクトの構造が変更されていないことを確認してください。
  • ファイル操作の例外: ファイルの読み書きで発生する例外については、ログにエラーを出力し、ユーザーに通知することを推奨します。

実装例

プレイヤーデータを保存・読み出しする例を以下に示します。

[System.Serializable]
public class PlayerData
{
    public string name;
    public int score;
}

public class ExampleUsage : MonoBehaviour
{
    private async void Start()
    {
        PlayerData data = new PlayerData { name = "Player1", score = 200 };
        await ExtPlayerPrefs.SaveAsync(data, "playerData.json", "mySecretKey");

        PlayerData loadedData = await ExtPlayerPrefs.LoadAsync<PlayerData>("playerData.json", "mySecretKey");
        Debug.Log($"Loaded Player Name: {loadedData.name}, Score: {loadedData.score}");

        // プリミティブオブジェクトの保存・読み出し(暗号化なし)
        int highScore = 500;
        ExtPlayerPrefs.Save(highScore, "highScore.json");
        int loadedHighScore = ExtPlayerPrefs.Load<int>("highScore.json");
        Debug.Log($"Loaded High Score (without encryption): {loadedHighScore}");

        // プリミティブオブジェクトの保存・読み出し(暗号化あり)
        int highScoreEncrypted = 800;
        string encryptedJson = ExtPlayerPrefs.Save(highScoreEncrypted, "encryptedHighScore.json", "encryptionKey");
        Debug.Log($"Encrypted JSON: {encryptedJson}");
        ExtPlayerPrefs.Save(highScoreEncrypted, "encryptedHighScore.json", "encryptionKey");
        int loadedHighScoreEncrypted = ExtPlayerPrefs.Load<int>("encryptedHighScore.json", "encryptionKey");
        Debug.Log($"Loaded Encrypted High Score: {loadedHighScoreEncrypted}");
    }
}

結論

ExtPlayerPrefs クラスは、データの保存と読み出しを簡潔にし、暗号化や非同期処理の対応によってゲームの安全性やパフォーマンスを向上させることができます。Unity プロジェクトでのデータ管理に活用してください。

参考)データの保存先

UnityのApplication.persistentDataPathは、アプリケーションが永続的なデータを保存するために使用できるディレクトリのパスを提供します。このパスはプラットフォームによって異なります。以下は主要なプラットフォームごとのパスの場所です。


1. Windows

  • パス形式:
    C:\Users\<ユーザー名>\AppData\LocalLow\<会社名>\<プロジェクト名>
  • :
    C:\Users\JohnDoe\AppData\LocalLow\MyCompany\MyGame

2. macOS

  • パス形式:
    ~/Library/Application Support/<会社名>/<プロジェクト名>
  • :
    /Users/JohnDoe/Library/Application Support/MyCompany/MyGame

3. Linux

  • パス形式:
    ~/.config/unity3d/<会社名>/<プロジェクト名>
  • :
    /home/johndoe/.config/unity3d/MyCompany/MyGame

4. Android

  • パス形式:
    /data/data/<パッケージ名>/files
  • :
    /data/data/com.mycompany.mygame/files

5. iOS

  • パス形式:
    <アプリサンドボックス>/Documents
  • :
    /var/mobile/Containers/Data/Application/<ランダムなID>/Documents

6. WebGL

  • 備考:
    WebGLでは、Application.persistentDataPathはIndexedDBを使用してデータを保存しますが、具体的なパスはプラットフォームやブラウザに依存するため、直接確認することはできません。Unityでは内部的にブラウザのストレージを使用します。

7. PlayStation, Xbox, Nintendo Switch

  • パス形式:
    コンソールに応じてサンドボックス内の特定のストレージパスが割り当てられています。これらのプラットフォームは開発者が直接制御できない場所を使用します。

注意点

  • Application.persistentDataPathはプラットフォームごとに異なるため、コードを書くときはプラットフォーム非依存の方法で利用するべきです。
  • このパスはアプリがアンインストールされるとデータも削除される可能性があるため、重要なデータはクラウドなどにバックアップをとることを検討してください。

Unity

Posted by hidepon