ブロック崩し(breakout)を簡単に作成。Part2.ブロックを壊す|Unityゲーム制作

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)がないので、次回作成していきます。

タイトルとURLをコピーしました