LoginSignup
1
3

More than 3 years have passed since last update.

【Unity(C#)】PlayerPrefsを使用したステージ解放の実装

Last updated at Posted at 2020-05-05

ステージ解放の実装

unity1weekに参加しました。今回のテーマは「密」です。
磁石の力で壁に密着したり、逆に反発の力で飛んだり、、、という
引っ張りアクションゲームです。
MMTitleSSFix.PNG

【投稿した作品】:MAGNET MONSTER

そのゲームの中で
あるステージをクリアすると遊べるようになるステージが出現する実装
に試みました。

次遊ぶとき(ブラウザを閉じて再度読み込んだとき)にも
前回のクリアデータは保持されるという前提もクリアしたかったです。

PlayerPrefs

今回はPlayerPrefsを使った実装を行いました。
理由としては、手軽さ、ただそれだけです。

多くのデータを保存したり、
改変、閲覧されて困る情報を保存するのには向いていないそうですが、
今回はあまり関係が無いのでセーフです。

実装の詳細

ステージをクリアするまでは
Easyモード以外は???という項目となっており、
選択しても遊べません。
MMMenuReset.PNG

クリア後の画像が下記画像です。
Easyモード以外の項目の文字が???から変更されており、
選択して遊ぶことができます。

MMMenu.PNG

コード

情報を保存する側(SetIntする側)
保存された情報を取り出す側(GetInt)が必要です。

PlayerPrefs.SetInt

まずは情報を保存する側(SetIntする側)を見ていきます。

SetIntする側 プレイヤーにアタッチ
private void OnCollisionEnter(Collision other)
{
    if (other.gameObject.layer == LayerMask.NameToLayer("Goal"))
    {
        //どのシーンをクリアしたかでSetIntする数字を変更
        if (SceneManager.GetActiveScene().name == "EasyScene")
        {
            PlayerPrefs.SetInt ("LEVEL", 1);
        }   
        else if (SceneManager.GetActiveScene().name == "NormalScene")
        {
            PlayerPrefs.SetInt ("LEVEL", 2);
        }
        else if (SceneManager.GetActiveScene().name == "HardScene")
        {
            IsClearHardThisTime = true;
            PlayerPrefs.SetInt ("LEVEL", 3);
        }

        //念のためセーブしとく クラッシュすることあるらしい
        PlayerPrefs.Save();
    }
}

下記画像のようにプレイヤーがゴールに衝突した瞬間に
今開いているシーンを参照してセットする値を決めています。

EXPrefs.PNG

PlayerPrefs.GetInt

保存された情報を取り出す側(GetInt)です。

GetIntする側
using UnityEngine;
using UnityEngine.UI;    

public class TitleSceneManager : MonoBehaviour
{
    [SerializeField] private Image _normalImage;
    [SerializeField] private Image _hardImage;
    [SerializeField] private Image _rankingImage;

    [SerializeField] private Sprite _normalSprite;
    [SerializeField] private Sprite _hardSprite;
    [SerializeField] private Sprite _rankingSprite;

    private void Start()
    { 
        int clearLevel = PlayerPrefs.GetInt("LEVEL",0);

        //レベルに応じてUI画像入れ替え
        switch (clearLevel)
        {
            case 1:
                _normalImage.sprite = _normalSprite;
                break;
            case 2:
                _normalImage.sprite = _normalSprite;
                _hardImage.sprite = _hardSprite;
                break;
            case 3:
                _normalImage.sprite = _normalSprite;
                _hardImage.sprite = _hardSprite;
                _rankingImage.sprite = _rankingSprite;
                break;
        }
    }
}

タイトルシーンの読み込み時に
保存されたステージクリアの情報を取得して、
画像の差し替えを行っています。

あとはステージ選択ボタンを押したら、、、という処理に
if文でReturn処理を書くなどすればボタンの選択も制限できます。

PlayerPrefs.Save

このSaveのタイミング、どうやらタイミング次第では
たまにデータが吹き飛ぶことがあるそうなので
SetIntするたびにPlayerPrefs.Save();
呼び出しておいた方がよさそうです

【参考リンク】:Playerprefsを確実に保存するリンク

デバッグ時のリセット

#if UNITY_EDITOR

using UnityEngine;
using UnityEditor;

/// <summary>
/// PlayerPrefsを初期化するクラス
/// </summary>
public static class PrefsClear
{
    [MenuItem("Tools/Reset PlayerPrefs")]
    public static void ResetPlayerPrefs()
    {
        PlayerPrefs.DeleteAll();
        PlayerPrefs.Save();
        Debug.Log("Reset PlayerPrefs");
    }
}
#endif

下記参考リンクから頂戴しました。

【参考リンク】:PlayerPrefsをリセットするメニューを追加する【Unity】【エディタ拡張】

クリアしたデータはEditor上での実行時にも保存されるので
削除する機能があるとデバッグがはかどります。

最後に

私はこういう実装でやってますというのがあれば教えてください。
初めての試みなので、なんか動いたからヨシ!って感じです。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3