PlayerPrefsを用いたセーブ・ロード処理とインターフェースを使ったデバッグシステムの開発 | Unity入門の森 ゲームの作り方

PlayerPrefsを用いたセーブ・ロード処理とインターフェースを使ったデバッグシステムの開発

Unity 放置インフレ系クリッカーゲームの作り方 (スマホ化対応)


Unity入門の森オリジナル本格ゲーム制作講座はこちら
11種類の本格ゲームの全ソースコード公開・画像&動画による解説付き

前回でコイン獲得時のアニメーション処理を作り、ゲームのメイン処理ができあがりました。

前回の記事↓

羊を購入できるお店スクリプトの作成とGrid Layout Groupを用いたUI画面整形
前回は、SheepButtonを作成して、羊購入処理等を作りました。 前回の記事↓ 今回はそのSheepButtonを複数並べるためのShopオブジェクトを実装していき、一通りクリッカーゲームとして遊べる状態を目指していきます。 また、記事...

ですが、インフレ系クリッカーゲームは一度のプレイで完結しないため、セーブシステムが欠かせません。

ここでは、PlayerPrefsやインターフェースを用いてセーブ・ロードシステムを開発し、遊べるゲームとしての完成を目指します。


【Line登録者限定のプレゼントもあるよ!】

unityゲームのセーブ・ロードシステムの作り方

クリッカーゲームは根を詰めてプレイするというより、気が向いた時に開いてポチポチやって。というスタイルです。

そのためにはオートセーブ機能オートロード機能が不可欠です(毎回所持金0円、羊0頭から始めたくないですよね)

では、まず要件を詰めましょう。
今回のゲームで、セーブ・ロードをしたいデータはというと

  • ①所持金
  • ②各羊の頭数

だけになると思います。

(ゲームを終了させる前に出ていた羊毛(wool) は? とおっしゃる方もおられるかとは思いますがさすがにそこまでは対応しない事とします(もちろんやればできますが))

要件も決まりましたので、SaveとLoadをするオブジェクトSaveLoadManager」を作りましょう。

Sceneビュー上でCTRL+SHIFT+Nキーを押してオブジェクトを新規作成し、
名前を「SaveLoadManager」に、AddComponent新規スクリプトを追加
こちらも名前を「SaveLoadManager」にしておきます。

では、SaveLoadManagerスクリプトを以下のように修正します。

メンバ変数には、保存対象としている所持金を持っている Walletオブジェクトと、羊の頭数を持っているSheepButtonを複数管理するShopオブジェクトが必要です。

まず、ゲームを終了する時にオートセーブさせたいのですが、そういうときには

OnApplicationQuit というメソッドを使います。
これは、StartメソッドUpdateメソッドと同じ、Unity側から適宜呼ばれるメソッドの一つで、アプリケーション終了時に呼ばれるメソッドになります。
そのため、一字一句、大文字小文字含め完全にこの名前でないと呼ばれませんので、注意してください。

この中にセーブ処理を書きたい、のですがとりあえず今は”セーブ”とログ出力だけにしています。

次に、オートロードにしたいので、Startメソッドでロード処理を行いたい、のですがとりあえず今は”ロード”とログ出力だけにしています。

ではスクリプトを保存し、UnityEditorのInspectorでWalletオブジェクトShopオブジェクトをセットします。

なお、HierarchyからWalletオブジェクトShopオブジェクトを見つけるのが大変な時は、Inspectorの◎をクリックすると検索ウインドウが開き、そこからセットすることもできます。(Shopスクリプトを探す時は、自動的にShopスクリプトが割り当てられたScene上のオブジェクトが絞り込まれて表示されます)

適宜使いやすい方法を選びましょう。

Consoleウインドウに実行時に「ロード」、終了時に「セーブ」と出てきましたね。

ログが正しく出力されない(特に「ロード」)場合は、スクリプトの修正が誤っている可能性が高いです。見直してみましょう。

PlayerPrefsによるセーブ・ロード処理の実装

さて、今回欲しいのは「セーブ機能」と「ロード機能」です。

一番簡単な方法をとると PlayerPrefsを使うのが簡単です。これは、Unityが用意している簡易なセーブロード機能で使い方は

  • PlayerPrefs.SetInt(キー文字列,保存するintの値);
  • PlayerPrefs.SetFloat(キー文字列,保存するfloatの値);
  • PlayerPrefs.SetString(キー文字列,保存するstringの値);

このようにSet~ で文字列と値をペアにして保存することが出来ます。

保存したデータを逆に取得(ロード)したい場合は

  • PlayerPrefs.GetInt(キー文字列,存在しなかった場合のintの値);
  • PlayerPrefs.GetFloat(キー文字列,存在しなかった場合のfloatの値);
  • PlayerPrefs.GetString(キー文字列,存在しなかった場合のstringの値);

このようにGet~ で文字列を指定するとペアになっている値が返却されますし、もしそのキー文字列での保存されたデータが無い場合(初回など)は第二引数で指定した値をデフォルト値として返却するものです。

今回のキー文字列とデータ内容については以下の通りとします。

キー文字列 内容 データ型
MONEY 所持金 string(本当はBigIntegerだが、文字列にして格納)
SHEEP0~7 羊の頭数 int

それでは、上記キー文字列でPlayerPrefsを使ってセーブ・ロード処理を書くとこのようになります。

PlayerPrefsによるセーブ処理の作成

まずセーブ処理ですが、

所持金は PlayerPrefs.SetString("MONEY", wallet.money.ToString()); と、wallet.moneyをToStringメソッドで文字列にしてから保存しています。これはPlayerPrefsはintとfloatとstringしか対応していないからです。

そして各種類の羊の頭数はShopオブジェクトが持っているsheepButtonList内のSheepButtonが所持しているので、for文で全ての羊購入ボタン(SheepButton)を取得してPlayerPrefs.SetInt($"SHEEP{index}", sheepButton.currentCnt); で保存をしています。

これにより

SheepButton配列0番目 は Sheep0 という名前で保存
SheepButton配列1番目 は Sheep1 という名前で保存

SheepButton配列7番目 は Sheep7 という名前で保存

としているわけです

PlayerPrefsによるロード処理の作成

次にロード処理ですが、

所持金のロードは、文字列で保存をしているのでPlayerPrefs.GetString("MONEY", "0")で取得した保存された文字列化された所持金データを、BigInteger.Parseメソッドで文字列→BigIntegerに戻して格納しています。

また各種羊の頭数は

でSheepButtonの現在数を保存したデータから戻してますが、加えて大事なことがあります。

というのも、SheepButtonの数だけロードしても、実際の各羊の数が増えるわけではないからです。

そのため、ここで各羊をもともと居た頭数分生成してあげているのが以下の処理になります。

for文で生成する羊の頭数分だけ繰り返して、SheepButtonが持っているsheepGeneratorを使って羊を生成しています。

ではスクリプトを保存して再生をし、ある程度羊を生成して1回停止→再生で停止前の状態が復元できるか確認をしてみましょう。

(※テストの為に初期羊毛の金額を20,000にしてあります。)

 

Tips: PlayerPrefsの初期化の方法

PlayerPrefsを使って実際にセーブやロード処理を何度かテストしていると、もちろんセーブデータが出来ている状態になるので、逆に「セーブデータが保存されていない状態」を作りたくなることがあります(レベルデザインで1からプレイし直したい時など)

そんな場合は、ツールバーのEditClear All PlayerPrefs で初期化をすることが出来ます。

本当に初期化(削除)してよいかダイアログが出てくるので、良い場合は「YES」を選びましょう。

「この操作は元に戻せないけど良いですか?」

インタフェースの使い方とデバッグシステムの換装

※ここからは余裕のある方、プログラムを専門としない方などは飛ばしてしまっても構いません

さて、PlayerPrefsを使ってセーブとロードが出来るようになりました。

これにて完成! と言っても良いのですが、実はPlayerPrefsを使ったセーブ・ロードはあまり性能が良くなく、人によっては拒否反応を示すことがあります(個人的には全然使えるので使えばいいと思っていますが)
そうじゃなくても保存をローカルではなく、ネットワーク上のサーバーに保持する事だって考えられます。

ここで重要なのはSaveLoadManagerオブジェクトが欲しいのはあくまでも所持金と羊頭数のセーブとロードという「機能・出来る事」であって、その先の方法・保存先がPlayerPrefsなのかファイルなのかネットワーク上のクラウドなのかは実は知る必要がありません。

こういう場合に便利なのが「インタフェース(interface)」になります。

早速使ってみましょう。

続きを読む

このコンテンツはパスワードで保護されています。 コンテンツを読みたい方はUnity入門の森ショップ(https://unityforest.shop/)で講座閲覧権を取得してね。

おさらいと次回予告

今回はセーブ・ロード処理とデバッグシステムの作成を行い一旦のゲーム完成となりました。

次回はサウンドの追加をしていきます。

サウンドの追加にはサウンドマネージャーを使用します。
第1回~10回まで通しで読んでいただいたあなたには申し訳ないのですが、一度サウンドマネージャー作成の方を先に見ていただき、改めて第11回講座の方を読んでいくとスムーズかと思われます。

サウンドマネージャーの作り方はこちら↓

【Unity入門】汎用サウンドマネージャー(Sound Manager)の作り方 前編
ゲームを作るに当たって、最後に手を入れがちですが、とても重要なのが「サウンド」です。 Unityには標準のサウンド機能(AudioClip,AudioSource,AudioListener)があるのですが、これをそのまま使うのはちょっと大...

第11回目講座はこちら↓

サウンドマネージャー機能を使って効果音を付ける
前回はコイン取得演出の追加と、セーブ・ロード処理を追加し、ほぼ完成という状態になりました。 前回の記事↓ 今回はサウンドの追加を行い、ゲームとしての完成を目指します。 サウンドの追加にはサウンドマネージャーを使用します。ここまで通して読んで...

 



Unity入門の森オリジナル本格ゲーム制作講座はこちら
11種類の本格ゲームの全ソースコード公開・画像&動画による解説付き

コメント

  1. ばこ より:

    【講座最後の自動セーブ処理の実装について】
    まず、OnApplicationQuitメソッドの中身をpublic型にし、saveメソッドを作ります。

    public void Save()
    {
    Debug.Log(“セーブ”);
    //所持金を保存
    saveData.SaveMoney(wallet.money);
    //全ての羊の頭数を保存しておく
    for (var index = 0; index < shop.sheepButtonList.Count; index++){ var sheepButton = shop.sheepButtonList[index]; saveData.SaveSheepCnt(index, sheepButton.currentCnt); } }

    OnApplicationQuitメソッドの中身をSave();に変更しましょう。
    そして、SheepGenerator.csを開き、

    [SerializeField] private SaveLoadManager saveLoadManager; //羊購入時のデータ保存処理

    を追加します。
    さらに、CreateSheepメソッドの最後に
    saveLoadManager.Save();
    の命令を追加します。
    最後にインスペクター画面でSheepGeneratorオブジェクトにSaveLoadManagerをアタッチすれば完成です。

    これで、羊の購入ボタンを押した際に自動でセーブ処理が行われます。
    毎回コインを獲得する度にセーブ処理を行ってもよいのですが呼び出し回数が増大してしまうため、このような形で簡易セーブシステムを実装しました。

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