概要
ゲームを終了しても、次に起動したときに前回の設定が復元されていると便利です。例えば、音量の設定、グラフィック品質、キーコンフィグ、あるいはハイスコアなど、プレイヤーの環境設定や簡単な進捗データを保存する機能は多くのゲームで必要とされます。
Unityには、このような比較的単純なデータを簡単にデバイスに保存・読み込みするための仕組みとして PlayerPrefs クラスが用意されています。PlayerPrefsは、レジストリ(Windows)、plistファイル(macOS/iOS)、またはXMLファイ ル(Android)といったプラットフォーム標準の場所に、キーと値のペアでデータを保存します。
この記事では、PlayerPrefsを使ったデータの保存と読み込みの基本的な方法と、その利便性の裏に潜む注意点や限界について解説します。
PlayerPrefsの基本的な使い方
PlayerPrefsは、3種類のデータ型(int, float, string)のみをサポートしています。それぞれのデータ型に対応したSetメソッド(保存)とGetメソッド(読み込み)が用意されています。
データの保存: Setメソッド
データを保存するには、SetInt(), SetFloat(), SetString()メソッドを使います。第一引数にデータを識別するためのキー(文字列)、第二引数に保存したい値を指定します。
using UnityEngine;
public class GameSettings : MonoBehaviour
{
public void SaveVolume(float volumeLevel)
{
// "MasterVolume"というキーで、float型の音量データを保存
PlayerPrefs.SetFloat("MasterVolume", volumeLevel);
}
public void SaveHighScore(int score)
{
// "HighScore"というキーで、int型のハイスコアを保存
PlayerPrefs.SetInt("HighScore", score);
}
}
重要: Setメソッドを呼び出しただけでは、データはまだメモリ上にあり、ディスクには書き込まれていません。ゲームがクラ ッシュした場合などにデータが失われるのを防ぐため、重要なデータを保存した直後にはPlayerPrefs.Save()を呼び出して、明示的にディスクへの書き込みを指示するのが安全です。
public void SaveAllSettings()
{
PlayerPrefs.SetInt("QualityLevel", 2);
PlayerPrefs.SetFloat("MusicVolume", 0.8f);
// メモリ上の変更をディスクに即座に書き込む
PlayerPrefs.Save();
}
データの読み込み: Getメソッド
保存したデータを読み込むには、GetInt(), GetFloat(), GetString()メソッドを使います。第一引数に、保存時に使ったキーを指定します。
このとき、第二引数としてデフォルト値を指定することが非常に重要です。指定したキーのデータが存在しない場合(例: ゲームの初回起動時)、このデフォルト値が返されます。デフォルト値を指定しないと、キーが存在しない場合に0や空文字が返され、意図しない挙動の原因となります。
using UnityEngine;
using UnityEngine.UI;
public class LoadSettings : MonoBehaviour
{
public Slider volumeSlider;
public Text highScoreText;
void Start()
{
// "MasterVolume"キーのデータを読み込む。存在しない場合はデフォルト値1.0fを使う。
float savedVolume = PlayerPrefs.GetFloat("MasterVolume", 1.0f);
volumeSlider.value = savedVolume;
// "HighScore"キーのデータを読み込む。存在 しない場合はデフォルト値0を使う。
int highScore = PlayerPrefs.GetInt("HighScore", 0);
highScoreText.text = "High Score: " + highScore;
}
}
その他の便利なメソッド
PlayerPrefs.HasKey(string key): 指定したキーのデータが存在するかどうかをbool値で返します。初回起動時の処理を分岐させたい場合などに便利です。PlayerPrefs.DeleteKey(string key): 指定したキーのデータを削除します。PlayerPrefs.DeleteAll(): すべてのPlayerPrefsデータを削除します。ゲームのリセット機能などで使いますが、非常に強力なため取り扱いには注意が必要です。
PlayerPrefsの注意点と限界
PlayerPrefsは非常に手軽で便利ですが、万能ではありません。使うべきでないケースを理解しておくことが重要です。
1. セキュリティの問題
PlayerPrefsで保存されるデータは、暗号化されていません。少し知識のあるユーザーであれば、保存されたファイルを簡単に見つけ出し、内容を書き換えることができてしまいます。ハイスコアや所持金といった、改ざんされると困るような重要なデータをPlayerPrefsでそのまま保存するのは非常に危険です。
対策:
- 重要なデータを保存する場合は、
PlayerPrefsを使う前に必ず独自の暗号化処理を施す必要があります。 - あるいは、
PlayerPrefsは使わずに、JSONやバイナリ形式でファイルに書き出し、そのファイル自体を暗号化する、より本格的なセーブシステムの導入を検討します。
2. 複雑なデー タの保存
PlayerPrefsが扱えるのはint, float, stringの3種類のみです。プレイヤーのインベントリ(アイテムのリスト)、キャラクターのステータス、クエストの進捗といった複雑な構造を持つデータを保存するには不向きです。
対策:
JsonUtilityやJson.NETといったライブラリを使って、自作クラスのインスタンスをJSON形式の文字列に変換(シリアライズ)し、それをPlayerPrefs.SetString()で保存する方法があります。これは比較的手軽で一般的な手法です。- より大規模で複雑なセーブデータの場合は、専用のセーブファイル(バイナリ形式など)を作成する方が、パフォーマンスや拡張性の面で優れています。
まとめ
PlayerPrefsは、Unityにおけるデータ永続化の入門として最適なツールです。
int,float,stringの3つの型を、キーと値のペアで簡単に保存できる。Setメソッドで保存し、Getメソッドで読み込む。Getメソッドでは、データが存在しない場合に備えてデフォルト値を指定するのが鉄則。- データは暗号化されないため、ハイスコアなどの改ざんされたくないデータの保存には向かない。
- 複雑なデータ構造の保存には、JSONへのシリアライズなどを組み合わせる工夫が必要。
PlayerPrefsの長所と短所を正しく理解し、音量設定のような単純なオプションにはPlayerPrefsを、セーブデータのような複雑で 重要な情報にはより堅牢なファイルベースのシステムを、というように適切に使い分けることが重要です。