ステージ解放の実装
unity1weekに参加しました。今回のテーマは「密」です。
磁石の力で壁に密着したり、逆に反発の力で飛んだり、、、という
引っ張りアクションゲームです。
【投稿した作品】:MAGNET MONSTER
そのゲームの中で
あるステージをクリアすると遊べるようになるステージが出現する実装
に試みました。
次遊ぶとき(ブラウザを閉じて再度読み込んだとき)にも
前回のクリアデータは保持されるという前提もクリアしたかったです。
PlayerPrefs
今回はPlayerPrefsを使った実装を行いました。
理由としては、手軽さ、ただそれだけです。
多くのデータを保存したり、
改変、閲覧されて困る情報を保存するのには向いていないそうですが、
今回はあまり関係が無いのでセーフです。
実装の詳細
ステージをクリアするまでは
Easyモード以外は???という項目となっており、
選択しても遊べません。
クリア後の画像が下記画像です。
Easyモード以外の項目の文字が???から変更されており、
選択して遊ぶことができます。

コード
**情報を保存する側(SetIntする側)**と
**保存された情報を取り出す側(GetInt)**が必要です。
PlayerPrefs.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();
}
}
下記画像のようにプレイヤーがゴールに衝突した瞬間に
今開いているシーンを参照してセットする値を決めています。

PlayerPrefs.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上での実行時にも保存されるので
削除する機能があるとデバッグがはかどります。
最後に
私はこういう実装でやってますというのがあれば教えてください。
初めての試みなので、なんか動いたからヨシ!って感じです。