Unity2Dで「ブロック崩し(breakout)」を作成。Part2ではブロックを壊すのとスコア加算、ボール消失を実装していきます。
はじめに
part1は下記から。
今回やる事
Part1ではパドルとボールを作成しました。Part2では「ブロックを壊す」、「スコア加算」、「ボール消失」を実装していきます。
作成開始
まずはブロックを作成して、スコア加算とボールの消失を作成します。
ブロックを作成
Hierarchyメニューで「2DObject」→「Sprites」から「Square」を追加します。名前を「block」にして色を変更して、「BoxCollider2D」を追加します。
下記スクリプトを作成します。ぶつかったらオブジェクトを破棄しています。
using UnityEngine; public class Block : MonoBehaviour { private void OnCollisionEnter2D(Collision2D collision) { Destroy(gameObject); } }
「block」に追加します。
実行して、下記のようにボールがぶつかった時にブロックがなくなればOKです。
空オブジェクトを追加して「Blocks」という名前にして、配下にblockを移動します。また、シーン名をstage1に変更します。とりあえず仮のステージ1になります。
ボールアウトの設定
Wallをコピーして画面下にボールがアウトになるゾーンを設定します。色を透過して「BoxCollider2D」はIsTriggerにチェックを入れておきます。
下記のような感じですね。見た目は透過しているので変わらないですが、画面下にボールが消えるゾーンを設定しています。
GameManagerの作成
「ボールが画面外に落ちたときの処理」と「ブロックを崩した時にポイントを加算する処理」などを作成していきます。
まずは新規でシーンを作成してシーン名を「manager」にします。空オブジェクトを追加して「GameManager」に名前を変更、同名のスクリプトを追加します。
GameManagerスクリプトは下記のようにします。起動したらStage1のシーンを読み込んでいます。スコアとライフ(ボールの残り数)はGameManagerで管理します。
using UnityEngine; using UnityEngine.SceneManagement; public class GameManager : MonoBehaviour { public static GameManager instance { get; private set; } private int score = 0; private int life = 3; private void Awake() { instance = this; DontDestroyOnLoad(gameObject); } private void Start() { SceneManager.LoadScene("stage1"); } }
BuildSettingsに「manager」と「stage1」のシーンを追加しておきます。
更にGameManagerに下記の3つの関数を追加しておきます。スコアの追加とボールが減った時の処理、ゲームオーバーの処理です。
using UnityEngine; using UnityEngine.SceneManagement; public class GameManager : MonoBehaviour { //省略 //省略 public void AddScore(int score) { this.score += score; } public void DecLife() { this.life--; if (this.life <= 0) GameOver(); else GameObject.Find("Ball").GetComponent<Ball>().ResetBall(); } private void GameOver() { SceneManager.LoadScene("gameover"); } }
スコアの加算とボールのリセット
Blockスクリプトを下記に変更します。ブロックを壊した時にスコアを加算しています。
using UnityEngine; public class Block : MonoBehaviour { private void OnCollisionEnter2D(Collision2D collision) { GameManager.instance.AddScore(10); Destroy(gameObject); } }
OutZone(ボールが下に落ちたとき)のスクリプトを下記のように作成します。
using UnityEngine; public class OutZone : MonoBehaviour { private void OnTriggerEnter2D(Collider2D collision) { GameManager.instance.DecLife(); } }
OutZoneにスクリプトを追加しておきます。
Ballスクリプトを下記に変更します。変更したのは「ResetBall」の部分です。
using UnityEngine; public class Ball : MonoBehaviour { [SerializeField] private float speed = 7.0f; private new Rigidbody2D rigidbody; private Vector2 velocity; private void Awake() { rigidbody = GetComponent<Rigidbody2D>(); ResetBall(); } void FixedUpdate() { rigidbody.velocity = rigidbody.velocity.normalized * speed; velocity = rigidbody.velocity; } private void OnCollisionEnter2D(Collision2D collision) { rigidbody.velocity = Vector2.Reflect(velocity, collision.contacts[0].normal); } public void ResetBall() { transform.position = Vector2.zero; rigidbody.velocity = Vector2.down * speed; } }
「Blocks」に同名でスクリプトを追加します。
Blocksスクリプトの中身を下記に変更します。全てのブロックを破壊したら次のステージに行きます。
using UnityEngine; public class Blocks : MonoBehaviour { void Update() { if (this.transform.childCount == 0) GameManager.instance.NextStage(); } }
GameManagerスクリプトを下記のように変更します。
using UnityEngine; using UnityEngine.SceneManagement; public class GameManager : MonoBehaviour { public static GameManager instance { get; private set; } private int stage = 1; private int score = 0; private int life = 3; private void Awake() { instance = this; DontDestroyOnLoad(gameObject); } private void Start() { LoadStage(1); } private void LoadStage(int stage) { this.stage = stage; SceneManager.LoadScene("stage" + stage); } public void AddScore(int score) { this.score += score; } public void NextStage() { LoadStage(this.stage + 1); } public void DecLife() { this.life--; if (this.life <= 0) GameOver(); else GameObject.Find("Ball").GetComponent<Ball>().ResetBall(); } private void GameOver() { SceneManager.LoadScene("gameover"); } }
stage1のシーンを複製してステージ2,3…を作成すると一通りの流れが完成しますが、終了画面(gameover)がないので、次回作成していきます。