【Unity】セーブとロードの実装方法【おすすめアセットあり】

クリエイティブ
記事内に広告が含まれています。

※本ページはプロモーションが含まれています。

今回はUnityのセーブ・ロードの実装についてかなり初歩的な内容から説明したいと思います。

よしお
よしお

筆者の情報

・理系 非情報系出身 非エンジニア

・Unity歴1年

Unityのセーブとロードの実装は難しくない!

Unityのセーブ・ロードの実装は難しくないです!

僕はUnityでセーブ・ロードは実装が難しいものだと思ってました。

「Unityの教科書」からUnityを学んだのですが、本書ではセーブ・ロードの実装については語られていなかったためです。間違いなく良書ですが、その辺は自分で調べる必要があったわけですね。

わかってしまえば特に難しいことはなかったのですが、こういう思い込みをしている人もいるんじゃないかなと思い、初心に返ってかなーり簡単に説明します。

何が難しそうだと思ったか

僕のようにゲーム開発もプログラミングも何もわからない人で、ゲームはしたことがあるという人は思ったんじゃないかなーと思うんですが

どうやって初期化とロードをするの?」ってところで意味がわからなかったんですよね。

例えばUnityでRPGを作るとします。

セーブとかロードのことを何も知らない場合は、プレイヤーのレベルを初期化するときはとりあえず以下のように書くと思います。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour {
    private int playerLv;

    private void Start () 
    {
       playerLv = 1;
    }
}

ただ、この場合だとゲームを再起動させたときにプレイヤーのレベルが1に戻っちゃうんですよね。

でも再起動前の状態を引き継ぐ方法わかんないし、訳わかんねーってなってこうなっちゃいました。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour {
    private int playerLv;

    private void Start () 
    {
       playerLv = ここに何を書いたらいいの~~~~~~~~~~!?!?!;
    }
}

解決法:とりあえずロードをする

解決方法はとりあえず最初にロード処理をするってことでした

これも最初意味分からなかった。

僕たちって初めてRPGのゲームするとき、「つづきから」じゃなくて「はじめから」を選択しますよね。そもそも「つづきから」は選択できないと思います。

でも、実際Unityでゲームを作る際は「つづきから(ロード)」を実行してやって、セーブデータがなかったら初期値を代入するといった方法になります。

例えば、プレイヤーレベルのロードの場合は以下のように記述します。

//「PlayerLv」というキーにデータがなければ1を返す
playerLv = PlayerPrefs.GetInt("PlayerLv", 1);

PlayerPrefsとはなんぞや

セーブ・ロードの実装はUnityの標準機能であるPlayerPrefsを使います。

PlayerPrefsでは「キー」というものでデータを識別します。

上の例では「PlayerLv」というキーに保存されているデータをplayerLvという変数に代入するという意味になります。

ロードの場合はPlayerPrefs.Get型名(“キー”,既定値)

セーブの場合はPlayerPrefs.Set型名(“キー”,セーブする値or変数)というふうに記述します。

既定値にはセーブデータがない場合に代入する値を入れます。(プレイヤーのレベルの場合は1ですね)

実際に記述例を示します。

ゲームの開始時はStart関数が呼ばれるので、Start関数内にロード処理を書きましょう。

また、レベルアップ時はレベルアップ処理(playerLvを+1する)の後にその値を保存してあげればいいです。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour {
    private int playerLv;

    private void Start () 
    {
        //「PlayerLv」というキーにデータがなければ1を返す
        playerLv = PlayerPrefs.GetInt("PlayerLv", 1);
    }

    //レベルアップ時に呼ばれる関数
    private void LevelUp()
    {
        //プレイヤーレベルを1増やす
        playerLv++;
        //プレイヤーレベルをキーにセットする
        PlayerPrefs.SetInt("PlayerLv",playerLv);
        //セーブする
        PlayerPrefs.Save ();
    }
}

上記のように記述することで再起動後は前回にLevelUp関数で保存されたデータがplayerLvに代入されるので前の状態を引き継ぐことができます。

なお、データの削除も簡単です。

//指定したキーに保存されているデータを削除する
PlayerPrefs.DeleteKey(キー名称);

//全てのデータを削除する
PlayerPrefs.DeleteAll();

PlayerPrefsの弱点

こんなに簡単にセーブ・ロードが実装できるPlayerPrefsですがデメリットがあります。

保存できる型がIntFloatBoolしかないのです。それだけではなく複数のデータを保存できなかったり、保存場所に問題があったりであまり利用を推奨されていないみたいです。(普通に使う分には問題ないと思いますが)

中でも保存できる型が少ないというのはなかなか不便です。

3Dゲームでプレイヤーの位置情報を保存するという場合は、Vector3型で保存したくなりますが

PrayerPrefsを使おうとすると以下のようになると思います。

【セーブする場合】

// プレイヤーのゲームオブジェクトを名前で取得
GameObject playerObject = GameObject.Find("Player");

// プレイヤーのゲームオブジェクトからプレイヤーの位置を取得
Vector3 playerPosition = playerObject.transform.position;

//プレイヤーのx座標をセーブ
PlayerPrefs.SetFloat("PlayerPositionX",playerPosition.x);
//プレイヤーのy座標をセーブ
PlayerPrefs.SetFloat("PlayerPositionY",playerPosition.y);
//プレイヤーのz座標をセーブ
PlayerPrefs.SetFloat("PlayerPositionZ",playerPosition.z);

【ロードする場合】

// プレイヤーのx座標をロード
float playerPositionX = PlayerPrefs.GetFloat("PlayerPositionX");
// プレイヤーのy座標をロード
float playerPositionY = PlayerPrefs.GetFloat("PlayerPositionY");
// プレイヤーのz座標をロード
float playerPositionZ = PlayerPrefs.GetFloat("PlayerPositionZ");

//Vector3型のloadPositionに座標を与える
Vector3 loadPosition = new Vector3(playerPositionX,playerPositionY,playerPositionZ);
//プレイヤーの位置を変更する
playerObject.transform.position = loadPosition;

できないことはなさそうですがめんどくさいですね。

Easy Saveが簡単で便利

Easy Save

Easy Save - The Complete Save Data & Serializer System | Utilities Tools | Unity Asset Store
Use the Easy Save - The Complete Save Data & Serializer System from Moodkie on your next project. Find this utility tool...

有料ですが「Easy Save」というアセットがあります。
これはPlayerPrefsよりも使える型が多く暗号化もできる高性能アセットです。
なのに、PlayerPrefsとほとんど同じ使い方なので移行もめちゃくちゃ簡単です

ロードの場合はES3.Load<型名>(“キー”,defaultValue:既定値)
セーブの場合はES3.Save<型名>(“キー”,セーブする値or変数)というふうに記述します。

ほとんど同じですね。

EasySaveを使ってプレイヤーの位置をセーブ・ロードするコードを書いてみると以下のようになります。

【セーブする場合】

// プレイヤーのゲームオブジェクトを名前で取得
GameObject playerObject = GameObject.Find("Player");

// プレイヤーのゲームオブジェクトからプレイヤーの位置を取得
Vector3 playerPosition = playerObject.transform.position;

//プレイヤーの座標をセーブ
ES3.Save<Vector3>("PlayerPosition",playerPosition);

【ロードする場合】

//プレイヤーの座標をロード(既定値はなくても可)
playerObject.transform.position = ES3.Load<Vector3>("PlayerPosition");

便利ですね!!

データ削除も以下のように記述することでできます。

//指定したキーに保存されているデータを削除する
ES3.DeleteKey("キー名称");

//ディレクトリ丸ごと消す
ES3.DeleteDirectory("ディレクトリ名称");

//ファイル丸ごと消す
ES3.DeleteFile("ファイル名称(.es3)");

おわりに

というわけで、Unityのセーブ関係の説明とアセットについて説明してみました。

Easy Saveは人気アセットで年に何回か50%OFFセールをしたりするので、これからゲームを本格的に作りたい方は買ってみてください!

それでは!

独学に限界を感じているあなたに

ゲーム制作に特化したプログラミングスクール「テックスタジアム」をご紹介します。
テックスタジアムは数あるプログラミングスクールでもゲームに特化しており、完全オンライン」でUnity、3DCGを学ぶことができます

また、第一線で活躍する講師に質問し放題。ゲーム業界への無料就職サポートも行っており、就職決定者には、授業料が全額返還される特典も
オンラインで無料相談が可能なので、独学に限界を感じた場合は検討してみてください。

コメント

タイトルとURLをコピーしました