Unity技術資料: ScriptableObjectとPlayerPrefsの組み合わせによるデータ管理
Unityにおけるデータ管理は、ゲームの進行状況やプレイヤーのステータスを保持するために不可欠です。本資料では、ScriptableObjectとPlayerPrefsを組み合わせて効果的にデータを管理・保存・読み込みする方法を解説します。
ScriptableObjectは、データの構造を定義し、エディタ上で管理可能なアセットとして機能します。一方、PlayerPrefsは簡易的なデータ保存方法として広く利用されています。本資料では、この二つを組み合わせることで、効率的かつ柔軟なデータ管理システムを構築する方法を紹介します。
概要
本資料では以下の内容をカバーします:
- ScriptableObjectの作成: プレイヤーのデータ(例: レベル、経験値、ヘルス)を保持する
ScriptableObjectを作成。 - データの保存と読み込み: 
PlayerPrefsを使用してデータを保存および読み込みするスクリプトを実装。 - データの操作: ゲーム内でプレイヤーデータを操作するためのコントローラーを実装。
 - 動作確認: 実装したシステムの動作を確認する手順。
 - 注意点とベストプラクティス: 実装時の注意点と推奨されるベストプラクティスの紹介。
 
前提条件
- Unity Hubおよび最新のUnityエディタがインストールされていること。
 - 基本的なUnityの操作方法およびC#スクリプトの知識があること。
 
ステップ1: ScriptableObjectの作成
1.1 PlayerDataクラスの定義
まず、プレイヤーのデータを保持するためのScriptableObjectクラスを作成します。
- スクリプトの作成:
Assetsフォルダ内で右クリックし、Create > C# Scriptを選択します。- スクリプト名を 
PlayerDataとします。 
 - PlayerData.csの編集:
- ポイント:
[CreateAssetMenu]属性により、Unityエディタのメニューから簡単にPlayerDataアセットを作成できます。level,experience,healthはプレイヤーの基本的なステータスを表します。ResetDataメソッドは、データを初期状態にリセットするために使用します。
 
 - ポイント:
 
// PlayerData.cs
using UnityEngine;
[CreateAssetMenu(fileName = "PlayerData", menuName = "ScriptableObjects/PlayerData", order = 1)]
public class PlayerData : ScriptableObject
{
    public int level = 1;
    public float experience = 0f;
    public float health = 100f;
    /// <summary>
    /// データを初期状態にリセットします。
    /// </summary>
    public void ResetData()
    {
        level = 1;
        experience = 0f;
        health = 100f;
    }
}
1.2 PlayerDataインスタンスの作成
- アセットの作成:
- Unityエディタの
Projectウィンドウで、Assetsフォルダ内を右クリックします。 Create > ScriptableObjects > PlayerDataを選択します。- 新しく作成された
PlayerDataアセットに適切な名前(例:PlayerDataAsset)を付けます。 
 - Unityエディタの
 - 初期値の設定:
- 作成した
PlayerDataアセットを選択し、インスペクターウィンドウでLevel、Experience、Healthの初期値を設定します。 
 - 作成した
 
ステップ2: PlayerPrefsによるデータの保存と読み込み
2.1 PlayerDataManagerクラスの実装
PlayerDataを管理し、PlayerPrefsを使用してデータの保存と読み込みを行うマネージャークラスを作成します。
- スクリプトの作成:
Assetsフォルダ内で右クリックし、Create > C# Scriptを選択します。- スクリプト名を 
PlayerDataManagerとします。 
 - PlayerDataManager.csの編集:
- ポイント:
PlayerDataアセットへの参照を保持し、データの保存・読み込みを担当します。SavePlayerDataメソッドは、PlayerDataの各フィールドをPlayerPrefsに保存します。LoadPlayerDataメソッドは、PlayerPrefsからデータを読み込み、PlayerDataに適用します。データが存在しない場合は初期化します。ResetPlayerDataメソッドは、データを初期状態にリセットし、PlayerPrefsをクリアします。OnApplicationQuitメソッドは、アプリケーション終了時に自動的にデータを保存します。
 
 - ポイント:
 
// PlayerDataManager.cs
using UnityEngine;
public class PlayerDataManager : MonoBehaviour
{
    [Header("Player Data")]
    public PlayerData playerData;
    private void Start()
    {
        LoadPlayerData();
    }
    /// <summary>
    /// PlayerPrefsにプレイヤーデータを保存します。
    /// </summary>
    public void SavePlayerData()
    {
        PlayerPrefs.SetInt("PlayerLevel", playerData.level);
        PlayerPrefs.SetFloat("PlayerExperience", playerData.experience);
        PlayerPrefs.SetFloat("PlayerHealth", playerData.health);
        PlayerPrefs.Save();
        Debug.Log("Player data saved.");
    }
    /// <summary>
    /// PlayerPrefsからプレイヤーデータを読み込みます。
    /// </summary>
    public void LoadPlayerData()
    {
        if (PlayerPrefs.HasKey("PlayerLevel"))
        {
            playerData.level = PlayerPrefs.GetInt("PlayerLevel");
            playerData.experience = PlayerPrefs.GetFloat("PlayerExperience");
            playerData.health = PlayerPrefs.GetFloat("PlayerHealth");
            Debug.Log("Player data loaded.");
        }
        else
        {
            // 初回起動時のデータ初期化
            playerData.ResetData();
            Debug.Log("Player data initialized.");
        }
    }
    /// <summary>
    /// プレイヤーデータをリセットし、PlayerPrefsをクリアします。
    /// </summary>
    public void ResetPlayerData()
    {
        playerData.ResetData();
        PlayerPrefs.DeleteAll();
        Debug.Log("Player data reset.");
    }
    private void OnApplicationQuit()
    {
        SavePlayerData();
    }
}
2.2 Unityエディタでの設定
- PlayerDataManagerの設定:
- シーン内に新しい空のGameObjectを作成します(例: 
PlayerDataManagerObject)。 - 作成したGameObjectに
PlayerDataManagerスクリプトをアタッチします。 
 - シーン内に新しい空のGameObjectを作成します(例: 
 - PlayerDataアセットの割り当て:
PlayerDataManagerコンポーネントのPlayer Dataフィールドに、先ほど作成したPlayerDataアセット(例:PlayerDataAsset)をドラッグ&ドロップします。
 
ステップ3: データの操作
プレイヤーのデータをゲーム内で操作するためのコントローラスクリプトを作成します。
3.1 PlayerControllerクラスの実装
- スクリプトの作成:
Assetsフォルダ内で右クリックし、Create > C# Scriptを選択します。- スクリプト名を 
PlayerControllerとします。 
 - PlayerController.csの編集:
- ポイント:
- ユーザーのキー入力に応じて、
PlayerDataの各フィールドを操作します。 Lキーでレベルアップ、Eキーで経験値獲得、Hキーでヘルス回復、Rキーでデータリセットを行います。
 - ユーザーのキー入力に応じて、
 
 - ポイント:
 
// PlayerController.cs
using UnityEngine;
public class PlayerController : MonoBehaviour
{
    [Header("Data Manager")]
    public PlayerDataManager dataManager;
    private void Update()
    {
        // レベルアップ (Lキー)
        if (Input.GetKeyDown(KeyCode.L))
        {
            dataManager.playerData.level += 1;
            Debug.Log($"Level Up! Current Level: {dataManager.playerData.level}");
        }
        // 経験値獲得 (Eキー)
        if (Input.GetKeyDown(KeyCode.E))
        {
            dataManager.playerData.experience += 10f;
            Debug.Log($"Gained Experience! Current Experience: {dataManager.playerData.experience}");
        }
        // ヘルス回復 (Hキー)
        if (Input.GetKeyDown(KeyCode.H))
        {
            dataManager.playerData.health = Mathf.Min(dataManager.playerData.health + 20f, 100f);
            Debug.Log($"Health Recovered! Current Health: {dataManager.playerData.health}");
        }
        // データリセット (Rキー)
        if (Input.GetKeyDown(KeyCode.R))
        {
            dataManager.ResetPlayerData();
            Debug.Log("Player data has been reset.");
        }
    }
}
3.2 Unityエディタでの設定
- PlayerControllerの設定:
- シーン内に新しい空のGameObjectを作成します(例: 
PlayerControllerObject)。 - 作成したGameObjectに
PlayerControllerスクリプトをアタッチします。 
 - シーン内に新しい空のGameObjectを作成します(例: 
 - PlayerDataManagerの割り当て:
PlayerControllerコンポーネントのData Managerフィールドに、先ほど設定したPlayerDataManagerオブジェクトをドラッグ&ドロップします。
 
動作確認
以下の手順で実装したシステムの動作を確認します。
- ゲームの実行:
- Unityエディタ上部の再生ボタンをクリックしてゲームを実行します。
 
 - データの操作:
- レベルアップ: 
Lキーを押すと、プレイヤーのレベルが1増加します。 - 経験値獲得: 
Eキーを押すと、プレイヤーの経験値が10増加します。 - ヘルス回復: 
Hキーを押すと、プレイヤーのヘルスが20回復します(最大値は100)。 - データリセット: 
Rキーを押すと、プレイヤーデータが初期状態にリセットされ、保存されたデータが削除されます。 
 - レベルアップ: 
 - データの保存と読み込み:
- ゲームを終了(再生停止)すると、
OnApplicationQuitによりデータが自動的に保存されます。 - 再度ゲームを実行すると、保存されたデータが正しく読み込まれていることを確認します。
 
 - ゲームを終了(再生停止)すると、
 
注意点とベストプラクティス
- PlayerPrefsの適用範囲:
PlayerPrefsは主に小規模なデータ(設定値やスコアなど)の保存に適しています。大量のデータや複雑なデータ構造には向いていません。- より複雑なデータの保存には、JSONファイルやデータベースの利用を検討してください。
 
 - ScriptableObjectの扱い:
ScriptableObjectはエディタ時にデータを保持するため、実行時にデータを変更するとエディタのアセット自体が変更される可能性があります。- 実行時用のデータコピーを作成するなど、データの永続性を確保する工夫が必要です。
 
 - データの整合性:
- データの保存・読み込み時には、必ずデータの整合性を確認してください。予期せぬデータ破損や不整合が発生しないように注意が必要です。
 
 - セキュリティ:
PlayerPrefsは暗号化されていないため、ユーザーが容易にデータを改ざん可能です。重要なデータの保存には適していません。
 
参考資料
本資料を基に、ScriptableObjectとPlayerPrefsを効果的に組み合わせ、プロジェクトに適したデータ管理システムを構築してください。必要に応じて、さらに高度なデータ保存方法や管理手法を検討することを推奨します。





ディスカッション
コメント一覧
まだ、コメントがありません