Unityでステージ解放を実装する

#概要
　自作のゲームに複数のステージを登場させたいとき、ステージの解放はどうすれば実装できるのか、その一例をご紹介したいと思います！今回は「1つ前のステージをクリアしたら次を解放する」という条件で解放していきます。


#前提
　ステージ選択画面が存在し、ボタンクリックで各ステージへ行けるようになっている状態を前提とします。

<img width="368" alt="スクリーンショット 2019-05-20 14.31.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416587/ce474538-b620-2fd5-302f-81a8fec853b6.png">

#ステージ解放をしよう
##1. 解放前のボタンを作ろう 
![qii.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416587/ae7f914b-c09f-8cd6-ac6c-4c95948cbe8c.jpeg)

　今回のゴールは画像のように解放前後でボタンの色が変化し、かつ次のステージに行けるようにすることなので、まずは「解放前」と「解放後」の2つのボタンを用意するところから始めます。

　`Command + D` でステージボタンを複製 (Duplicate)します。
　これが解放前のボタンになります。
　名前も分かりやすくを変更しておきましょう。（今回はs2pとします）

![betz.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416587/fe6e5926-9cf7-4c39-6a72-447959bebf62.jpeg)

　次に、解放前のボタンの色を変更します（今回はグレーにします）

![gott.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416587/d8b84d3b-ddfc-c733-cca7-b06212ed0827.jpeg)

　＊注意＊
　元のボタンを複製しているのでクリックするとゲームシーンへ移行するよう関連付けされていると思いますが、それは削除しましょう。
　削除は以下のようにOnClickボックスのー（マイナス）マークを押すとできます。

![Unknown.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416587/90d5bd7f-2da6-7121-64f7-5b08d4f84592.gif)


　これで解放前のボタンができました。
　関連付けをしていないので、クリックしても何も起こりません。

####おまけ： 解放前のボタンをクリックするとポップアップを出す
　もちろんこのままでも大丈夫ですが、クリックした時に「解放されていないよ！」と表示されるポップアップを作ると分かりやすいかもしれません。

　まずHierarchy 上の `Create > UI > Panel` でパネルを作成、大きさや位置、色を調節します。（今回はデフォルトの状態から色を濃くし、画面の真ん中に配置しました）

<img width="368" alt="スクリーンショット 2019-05-20 14.55.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416587/2be2e5e7-c545-ce72-d0e2-598ccabc98d4.png">

　次にパネル上にテキストボックスを作成します。
「まだ解放されていないよ！」と入力しました。

　最後に、ポップアップを消すボタンを作成します。
　ボタンに表示させるテキストには「Back」と入力しました。
　できたのがこちら↓

<img width="368" alt="スクリーンショット 2019-05-20 14.56.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416587/10aecc8a-666d-f66d-8bb0-3ee81657e9e3.png">

　だんだんポップアップらしくなってきましたね。
　最後に、ポップアップを消す「Back」ボタンを作動させるために以下のスクリプトを書いて関連付けします。

```csharp:PopupScript.cs
using System.Collections; 
using System.Collections.Generic;
 using UnityEngine; 
using UnityEngine.UI;//UnityのUI（buttonなどの機能）を使用するおまじない

  public class PopupScript : MonoBehaviour {  
	public GameObject Popup;//Popupというゲームオブジェクトを宣言する

  	  // Use this for initialization
  	void Start () {

 	   } 

	 // Update is called once per frame 
  	 void Update () { 	
	
 	   }  

     //Appear関数が呼び出されるとポップアップが表示される
     public void Appear(){ 
		Popup.SetActive (true); 
	}  
     
　　　//Delete関数が呼び出されるとポップアップが非表示になる
	 public void Delete(){ 
		Popup.SetActive (false); 
	}  

} 
```

　＊解説＊
　SetActiveという関数を使うと、スクリプトからGameObjectの表示・非表示（アクティブな状態にするか否か）の切り替えをすることができます。手動で行う場合は、objectを選択した際の左上のチェックボックスから切り替えができます。

![check.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416587/c498ea78-2df9-5ebc-0c0b-4e081eff15b8.jpeg)

　終わりに、Panel のチェックボックスをはずします。（普段から表示されていなくていいので）
　これで解放前のボタンをクリックするとポップアップが出現し、Backボタンで消せるようになりました！

##2. スクリプトを書こう　
　いよいよステージ解放をしていきましょう。まずは解放の進行具合を管理する変数を作るところから始めます。
　この変数の値を変更することで、現在どのステージまで解放されているのかを把握できるようになります。

　前提の状態から変更・追加するスクリプトは主に以下の２つになります：
　(1) ステージ解放を管理するスクリプトを新たに作成
　(2) ゴールした際のスクリプトに変数を管理する部分の追加（各ステージ）

###解放の流れ・仕組み
　これから書くスクリプトがどのように機能するのか、まずは流れを見ていきましょう。

![nagareeのコピー.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416587/54c5b566-7b4d-1045-27b5-96688eae74e1.jpeg)

###(1) ステージ解放スクリプトの作成・関連付け
　今回はStageScript.cs という名前にしました。
　ここでstage_numの値に応じてステージ解放を行う処理をしていきます！

```csharp:StageScript.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class StageScript : MonoBehaviour {

	public int stage_num; // スコア変数
	public GameObject ni;
	public GameObject san;
	public GameObject yon;
	public GameObject go;

	// Use this for initialization
	void Start () {
		//現在のstage_numを呼び出す
		stage_num = PlayerPrefs.GetInt ("SCORE", 0);
	}
	
	// Update is called once per frame
	void Update () {
		//stage_numが２以上のとき、ステージ２を解放する。以下同様
		if (stage_num >= 2) {
			ni.SetActive (true);
		}

		if (stage_num >= 3) {
			san.SetActive (true);
		}

		if (stage_num >= 4) {
			yon.SetActive (true);
		}

		if (stage_num >= 5) {
			go.SetActive (true);
		}

	}
}
```

　上のようなスクリプトを作成したら、ステージ選択画面に空のオブジェクトを作成して関連付けを行いましょう！
　空のobjectは`Hierarchy > Create > Create Empty`で作ります。
　まずはHelloScript.csを空のオブジェクト上にドラッグ＆ドロップ、次に以下のように各々の項目に対してオブジェクト（今回はステージボタン）を対応させていきます。

![kan.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416587/cbfc862e-1aca-03a1-a012-0fba6288b3f0.jpeg)


###(2) ゴールした際のstage_numの変更

　次に、ゴールした時にstage_numの値が変更されるようにするために以下のスクリプトを作成、ゴールのオブジェクトにドラッグします。

```csharp:ReleaseScript.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ReleaseScript : MonoBehaviour {


	// Use this for initialization
	void Start () {

	}
	
	// Update is called once per frame
	void Update () {
		
	}

	void OnTriggerEnter(Collider other){
		if (other.gameObject.name == "Player") {
　　　　　　  //PlayerPrefsのSCOREに3という値を入れる
			PlayerPrefs.SetInt ("SCORE", 3);
            //PlayerPrefsをセーブする         
			PlayerPrefs.Save ();

		}
	}
}

```

 ゴールのスクリプトはゲームを作った時に関連付けなどが済んでいるはずなので、特に追加で行うことはありません。

##3. 完成！！

　これで完成です。
　今回ご紹介したスクリプトを使うと、解放の状況によってキャラ図鑑も同時に解放されるなどの応用もできるので、ぜひ工夫してみてください！
<img width="513" alt="qiizukan.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416587/f8399b9b-5b5e-1b6c-f526-9b00855b1e9f.png">

　また、記事で使っているスクリーンショットは自作した「Micro」という無料ゲームのものですので、もしよかったら遊んでくださると嬉しいです！
ゲームへのリンク↓
https://www.freem.ne.jp/win/game/20282