絵本レビューとWwbと…

unityで簡単なゲームの作る方法

Unityで簡単なシューティングゲームを作る[8]

Step8:ゲームオーバーの設定

始まりがあれば終わりあり…と言う訳でゲームオーバーの設定を行う。

※このサイトのチュートリアルはとりあえず自力でゲームを作ってみることを目的としているため、プログラム言語に関する解説部分はかなり大雑把で意訳気味です。プログラム言語(C#)について正しく、詳しく学びたい方は、入門書やUnityの解説サイトなどをご参考にしていただけたらと思います。また、このサイトはコピープロテクトをかけているため、画面上からスクリプトのコピペができません。「スクリプトはこちら」というリンクからテキストファイルを表示して使ってください。面倒くさくてすみません。

ルールと仕様を考える

はじめに、どうなったらゲームオーバーになるかルールを決める。今回はごくシンプルに敵を撃ち損なってしまったらゲームオーバーという形にする。そして次に仕様を考える。ゲームオーバーの処理としては「Game Over」と表示し、弾が打てなくなる、スコアが更新しなくなるなどが考えられるが、今回はごくシンプルに「Game Over」表示し、プレイヤーをステージから消すという処理を行う。プレイヤーをステージから消してしまえば弾を打つこともできないし、スコアが更新されることもないからだ。

パネルを作成する

まず、ゲームオーバーの画面を作成する。今ある画面の上に重ねる形でGame Overのテキストやリトライボタンを表示したいのでパネルを作成する。

ヒエラルキーリストの「Canvas」を選択した状態で、「+」ボタンをクリックし「UI」から「Panel」を作成。

ヒエラルキーリストの「Cancas」の「Score」の下にパネルが作成されるので、名前を「GOPanel」と変更する。「GOPanel」のインスペクタでは背景色の指定もできる。今回はゲームオーバー感がでるよう、半透明の赤色に設定。

ゲームビューに切り替えると、ステージとプレイヤーの上に半透明の赤い色がかぶさっているのがわかる。

Game Overのテキストを作成

作成したパネルの中にゲームオーバーのテキストを配置する。シーンビューに戻りヒエラルキービューの「GOpanel」を選択した状態で「+」をクリックし「UI」から「Text」を作成。

「GOPanel」の下に「Text」が作成されるので名前を「GameOver」と変更。「GOPanel」のインスペクタを以下のように設定する。ゲームビューに切り替えバランスを見ながら設定するとよい。

Rotation:X:0,Y:0,Z:0
Text:GAME OVER
Font Style:Bold
Font Size:25
Alignment:中央中揃え
Color:白

パネル切り替えのスクリプトを作成

ゲームオーバーのパネルができたらそのパネルの表示・非表示を切り替えるスクリプトを作成する。「Asetts」から「Create」でC#を作成し、ファイル名を「PanelManager」とする。

ファイルを作成したら以下のスクリプトを記述する。スクリプトはこちらから。

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

public class PanelManager : MonoBehaviour
{

	[SerializeField] GameObject GOPanel;

public void Start()
    {
		Playgame();        
    }
public void Stopgame(){
		GOPanel.SetActive(true);
}

public void Playgame(){
		GOPanel.SetActive(false);
}

}

今回もユーザインタフェースに関わるスクリプトなのでusing UnityEngine.UI;を記述しておく。[SerializeField] は変数をUnityエディターから変数の値を格納したい時に使用する。

	[SerializeField] GameObject GOPanel;

そして指定したオブジェクト「GOPanel」をパネルを表示する(=ゲームオーバー)Stopgame、パネルを非表示にするPlaygameという二つの関数を作る。

 // パネルを表示する
public void Stopgame(){
		GOPanel.SetActive(true);
}
 // パネルを非表示
public void Playgame(){
		GOPanel.SetActive(false);
}

そしてスタート時にはパネルを非表示にするPlaygameを命令させる。

 // スタート時にパネルを非表示
public void Start()
    {
		Playgame();        
    }
スクリプトをアタッチする

スクリプトができたらオブジェクトにアタッチする。まずはアタッチするための空のオブジェクトを作成し名前を「PanelScript」とする。

作成したオブジェクト「PanelScript」に「PanelManager」をアタッチする。

関連づけを行う

スクリプトをアタッチした「PanelScript」のインスペクタを確認すると「PanelManager」の項目ができている。ここの「GOPanel」の欄が「No Object」となっているので、ここにヒエラルキーリストの「GOPanel」をドラッグ&ドロップして、関連づけをする。

関連づけがされると以下のように「GOPanel」と表示される。

この状態でゲームビューに切り替えてみると、先ほどのようにゲームオーバーの表示がされていない。「PanelManager」の中にあるスタート時はパネルを非表示にするという命令がきいているためである。

ゲームオーバーの処理を記述する

ゲームオーバーの画面ができたところで、今度はゲームオーバーの処理を記述する。まずゲームオーバー時にはプレイヤーを消したいので、プレイヤーを制御している「PlayerController」を開き、赤字の部分を追記する。スクリプトはこちらから。

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

public class PlayerController : MonoBehaviour{

public GameObject bulletPrefab;

	void Update () {
		
  transform.localPosition = Range.ClampPosition( transform.localPosition );

		if (Input.GetKey (KeyCode.LeftArrow)) {
			transform.Translate (-0.1f, 0, 0);
		}
		if (Input.GetKey (KeyCode.RightArrow)) {
			transform.Translate ( 0.1f, 0, 0);
		}
		if (Input.GetKey (KeyCode.UpArrow)) {
			transform.Translate ( 0,0.1f, 0);
		}
		if (Input.GetKey (KeyCode.DownArrow)) {
			transform.Translate ( 0,-0.1f, 0);
		}
		if (Input.GetKeyDown (KeyCode.Space)) {
			Instantiate (bulletPrefab, transform.position, Quaternion.identity);
		}
	}

public void Deleteplayer (){
	Destroy (gameObject);
  }

}

画面からプレイヤーを削除するDeleteplayerという関数を作成し、これをゲームオーバーの時に呼び出すようにする。続いてゲームのルールを記載している「GameSystem」を開き、赤字の部分を追記する。スクリプトはこちらから。

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

public class GameSystem : MonoBehaviour
{
	int score = 0;
	GameObject scoreText;
    bool isCalledOnce = false;

public void GameOver(){
		if (!isCalledOnce) {
        isCalledOnce = true;
		GameObject.Find ("PanelScript").GetComponent ().Stopgame();
		GameObject.Find ("player").GetComponent ().Deleteplayer();
	  }
	}

	public void AddScore(){
		this.score += 1;
	}

	void Start () {
		this.scoreText = GameObject.Find ("Score");
	}

	void Update () {
		scoreText.GetComponent ().text = "Score:" + score.ToString("D4");
	}
}

ゲームオーバーの処理は最初に敵がステージを通り越した時に1度だけ行いたい。そのため、1回だけ実行したい処理をif文内に記述し、同ブロック内でboolの値を切り替える。Updateメソッドはフレームごとに繰り返し実行されるが、このifのブロックは1回しか実行されない。

bool isCalledOnce = false;
public void GameOver(){
		if (!isCalledOnce) {
        isCalledOnce = true;

ifのブロック内にゲームオーバー 時に行いたい処理を記述する。一つ目は「PlayerController」内に記述されたDeleteplayer関数を呼び出す。(=プレイヤーを消す。)二つ目は「PanelManager」に記述されたStopgame関数を呼び出す。(=ゲームオーバーパネルを表示する。)

//プレイヤーを消し
GameObject.Find ("player").GetComponent ().Deleteplayer();
//ゲームオーバーパネルを表示する
GameObject.Find ("PanelScript").GetComponent ().Stopgame();

最後にゲームオーバーを判定するスクリプトを記述する。今回のゲームオーバー判定は敵を撃ち損なうなので、敵が弾に当たらずステージ下まで行ってしまったら負け、ということになる。そこで敵の動きを処理している「EnemyController」を開き、赤字の一文を追記する。スクリプトはこちらから。

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

public class EnemyController : MonoBehaviour{

	float fallSpeed;
	float rotSpeed;

public void Start () {
		this.fallSpeed = 0.01f + 0.1f * Random.value;
		this.rotSpeed = 6f + 3f * Random.value;
	}
	
public void Update () {
		transform.Translate( 0, -fallSpeed, 0, Space.World);
		transform.Rotate(0, 0, rotSpeed );
		if (transform.position.y < -5.5f) {
			Destroy (gameObject);
			GameObject.Find ("Canvas").GetComponent ().GameOver ();
		}
	}
}

敵がステージの下の端まで行ったら敵を消す、のスクリプトに続けて、ステージ上の「Canvas」にアタッチされているスクリプト「GameSystem」の中に記述されたGameOver関数の処理を行うよう命令している。

動作確認をする

保存してゲームビューで動作確認をする。ゲームオーバーになると、プレイヤーが消えて「GAMEOVER」の文字が表示される。

次回の「Step9:リトライボタンの設定」ではここにゲームをリロードするためのリトライボタンをつけていく。

★チュートリアル一覧

  1. Step1:プロジェクトの設定
  2. Step2:プレイヤーを動かす
  3. Step3:移動範囲を制限する
  4. Step4:弾を発射する
  5. Step5:敵を動かす
  6. Step6:弾で敵を倒す
  7. Step7:スコアを更新する
  8. Step8:ゲームオーバーの設定
  9. Step9:リトライボタンの設定
  10. Step10:背景を動かす
  11. Step11:BGMを設定
  12. Step12:爆破エフェクトをつける
  13. Step13:ゲームをビルドする

2020.6.3投稿

最近の投稿

レビュー記事

Work-life

Hobby

Diary