Unity技術資料: ScriptableObjectとPlayerPrefsの組み合わせによるデータ管理

Unityにおけるデータ管理は、ゲームの進行状況やプレイヤーのステータスを保持するために不可欠です。本資料では、ScriptableObjectPlayerPrefsを組み合わせて効果的にデータを管理・保存・読み込みする方法を解説します。

ScriptableObjectは、データの構造を定義し、エディタ上で管理可能なアセットとして機能します。一方、PlayerPrefsは簡易的なデータ保存方法として広く利用されています。本資料では、この二つを組み合わせることで、効率的かつ柔軟なデータ管理システムを構築する方法を紹介します。

概要

本資料では以下の内容をカバーします:

  1. ScriptableObjectの作成: プレイヤーのデータ(例: レベル、経験値、ヘルス)を保持するScriptableObjectを作成。
  2. データの保存と読み込み: PlayerPrefsを使用してデータを保存および読み込みするスクリプトを実装。
  3. データの操作: ゲーム内でプレイヤーデータを操作するためのコントローラーを実装。
  4. 動作確認: 実装したシステムの動作を確認する手順。
  5. 注意点とベストプラクティス: 実装時の注意点と推奨されるベストプラクティスの紹介。

前提条件

  • Unity Hubおよび最新のUnityエディタがインストールされていること。
  • 基本的なUnityの操作方法およびC#スクリプトの知識があること。

ステップ1: ScriptableObjectの作成

1.1 PlayerDataクラスの定義

まず、プレイヤーのデータを保持するためのScriptableObjectクラスを作成します。

  1. スクリプトの作成:
    • Assetsフォルダ内で右クリックし、Create > C# Scriptを選択します。
    • スクリプト名を PlayerData とします。
  2. 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インスタンスの作成

  1. アセットの作成:
    • UnityエディタのProjectウィンドウで、Assetsフォルダ内を右クリックします。
    • Create > ScriptableObjects > PlayerDataを選択します。
    • 新しく作成されたPlayerDataアセットに適切な名前(例: PlayerDataAsset)を付けます。
  2. 初期値の設定:
    • 作成したPlayerDataアセットを選択し、インスペクターウィンドウでLevelExperienceHealthの初期値を設定します。

ステップ2: PlayerPrefsによるデータの保存と読み込み

2.1 PlayerDataManagerクラスの実装

PlayerDataを管理し、PlayerPrefsを使用してデータの保存と読み込みを行うマネージャークラスを作成します。

  1. スクリプトの作成:
    • Assetsフォルダ内で右クリックし、Create > C# Scriptを選択します。
    • スクリプト名を PlayerDataManager とします。
  2. 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エディタでの設定

  1. PlayerDataManagerの設定:
    • シーン内に新しい空のGameObjectを作成します(例: PlayerDataManagerObject)。
    • 作成したGameObjectにPlayerDataManagerスクリプトをアタッチします。
  2. PlayerDataアセットの割り当て:
    • PlayerDataManagerコンポーネントのPlayer Dataフィールドに、先ほど作成したPlayerDataアセット(例: PlayerDataAsset)をドラッグ&ドロップします。

ステップ3: データの操作

プレイヤーのデータをゲーム内で操作するためのコントローラスクリプトを作成します。

3.1 PlayerControllerクラスの実装

  1. スクリプトの作成:
    • Assetsフォルダ内で右クリックし、Create > C# Scriptを選択します。
    • スクリプト名を PlayerController とします。
  2. 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エディタでの設定

  1. PlayerControllerの設定:
    • シーン内に新しい空のGameObjectを作成します(例: PlayerControllerObject)。
    • 作成したGameObjectにPlayerControllerスクリプトをアタッチします。
  2. PlayerDataManagerの割り当て:
    • PlayerControllerコンポーネントのData Managerフィールドに、先ほど設定したPlayerDataManagerオブジェクトをドラッグ&ドロップします。

動作確認

以下の手順で実装したシステムの動作を確認します。

  1. ゲームの実行:
    • Unityエディタ上部の再生ボタンをクリックしてゲームを実行します。
  2. データの操作:
    • レベルアップ: Lキーを押すと、プレイヤーのレベルが1増加します。
    • 経験値獲得: Eキーを押すと、プレイヤーの経験値が10増加します。
    • ヘルス回復: Hキーを押すと、プレイヤーのヘルスが20回復します(最大値は100)。
    • データリセット: Rキーを押すと、プレイヤーデータが初期状態にリセットされ、保存されたデータが削除されます。
  3. データの保存と読み込み:
    • ゲームを終了(再生停止)すると、OnApplicationQuitによりデータが自動的に保存されます。
    • 再度ゲームを実行すると、保存されたデータが正しく読み込まれていることを確認します。

注意点とベストプラクティス

  • PlayerPrefsの適用範囲:
    • PlayerPrefsは主に小規模なデータ(設定値やスコアなど)の保存に適しています。大量のデータや複雑なデータ構造には向いていません。
    • より複雑なデータの保存には、JSONファイルやデータベースの利用を検討してください。
  • ScriptableObjectの扱い:
    • ScriptableObjectはエディタ時にデータを保持するため、実行時にデータを変更するとエディタのアセット自体が変更される可能性があります。
    • 実行時用のデータコピーを作成するなど、データの永続性を確保する工夫が必要です。
  • データの整合性:
    • データの保存・読み込み時には、必ずデータの整合性を確認してください。予期せぬデータ破損や不整合が発生しないように注意が必要です。
  • セキュリティ:
    • PlayerPrefsは暗号化されていないため、ユーザーが容易にデータを改ざん可能です。重要なデータの保存には適していません。

参考資料


本資料を基に、ScriptableObjectPlayerPrefsを効果的に組み合わせ、プロジェクトに適したデータ管理システムを構築してください。必要に応じて、さらに高度なデータ保存方法や管理手法を検討することを推奨します。

ScriptableObject,Unity

Posted by hidepon