Developer

【初心者Unity】懐かしのゲームを作ってみよう!⑥
2021.11.01
Lv1

【初心者Unity】懐かしのゲームを作ってみよう!⑥


はじめに

今回は前回に引き続き、↓のゲームを作っていきます。

前回はPaddleを動かすところまで行きました。
今回はPaddleとぶつかったBallを跳ね返らせる処理を実装します。
これにてPaddleが一時的に完成します。。。
それでは早速作りましょう!


第3段階:Paddleを作成しよう!(3)

タイトルは「Paddleを作成しよう」となっていますが、跳ね返る主人公はBallなので、実は今回編集するスクリプトはBallScriptとなります。。。
しかしそのきっかけを与えるのはPaddleということで、まあPaddleの章にあるわけです(笑)
細かいことは気にせず行っちゃいましょう!
それでは早速設計から入るわけですが、今回重要なことは二つ、「もしPaddleに当たったら」「跳ね返る」です。
「もしPaddleに当たったら」というのは何やら新しいですね。。。
これはUpdate()メソッドでどうこうできる処理ではありません。
オブジェクトの衝突を検知できるメソッドであるOnTriggerEnter2D()を使います。
このメソッドはオブジェクトの衝突を検知するとメソッド内の処理を走らせます。
ということでメソッドをスクリプトに書いてみましょう。

public class BallScript : MonoBehaviour
{
    Vector2 pos;
    int directionX;
    int directionY;
    // Start is called before the first frame update
    void Start()
    {
        pos = transform.position;
        directionX = 1;
        directionY = 1;
    }

    // Update is called once per frame
    void Update()
    {
        //斜め45度に進ませる
        Move();

        //右端に着いた時の処理
        if (IsRightEdge())
        {
            directionX = -1;
        }

        //左端に着いた時の処理
        if (IsLeftEdge())
        {
            directionX = 1;
        }

        //上端に着いた時の処理
        if (IsUpperEdge())
        {
            directionY = -1;
        }

        //下端に着いた時の処理
        if (IsLowerEdge())
        {
            directionY = 1;
        }
    }

    void Move()
    {
        pos.x += 0.03f * directionX;
        pos.y += 0.03f * directionY;
        transform.position = pos;
    }

    bool IsRightEdge()
    {
        return pos.x > 2.5;
    }
    
    bool IsLeftEdge()
    {
        return pos.x < -2.5;
    }
    
    bool IsUpperEdge()
    {
        return pos.y > 5;
    }
    
    bool IsLowerEdge()
    {
        return pos.y < -5;
    }
    
    private void OnTriggerEnter2D(Collider2D collision)
    {
        //跳ね返りの処理
    }
}

それでは「跳ね返りの処理」はどうなるの?というところですが、これは実は過去に触れています。
いつ触れたか覚えていますか?そうです、Ballを壁で跳ね返らせる時です!
壁でどの様に跳ね返らせたか思い出していただけたらこの処理は割と簡単です。
Ballのy軸の増加方向を反対方向にすればよいのです。
もう少し丁寧にいきましょう。
BallがPaddleに当たるときBallはどのような動きをしているでしょうか?
そう、下方向に動いているのですね。
それをどうしたいのかというと、上方向に向かせたい。。。これだけ!
ここで使うのが過去に定義した「directionY」という変数です。
この変数はBallの向きの内、y軸方向を制御する変数でした。
「directionY = 1」の時は上方向に進み、「directionY = -1」の時は下方向に進むといった具合です。
今回は下方向だったものを上方向に変えるということだったので、「directionY = 1」というのが跳ね返りの処理になります。

public class BallScript : MonoBehaviour
{
    Vector2 pos;
    int directionX;
    int directionY;
    // Start is called before the first frame update
    void Start()
    {
        pos = transform.position;
        directionX = 1;
        directionY = 1;
    }

    // Update is called once per frame
    void Update()
    {
        //斜め45度に進ませる
        Move();

        //右端に着いた時の処理
        if (IsRightEdge())
        {
            directionX = -1;
        }

        //左端に着いた時の処理
        if (IsLeftEdge())
        {
            directionX = 1;
        }

        //上端に着いた時の処理
        if (IsUpperEdge())
        {
            directionY = -1;
        }

        //下端に着いた時の処理
        if (IsLowerEdge())
        {
            directionY = 1;
        }
    }

    void Move()
    {
        pos.x += 0.03f * directionX;
        pos.y += 0.03f * directionY;
        transform.position = pos;
    }

    bool IsRightEdge()
    {
        return pos.x > 2.5;
    }
    
    bool IsLeftEdge()
    {
        return pos.x < -2.5;
    }
    
    bool IsUpperEdge()
    {
        return pos.y > 5;
    }
    
    bool IsLowerEdge()
    {
        return pos.y < -5;
    }
    
    private void OnTriggerEnter2D(Collider2D collision)
    {
        directionY = 1;
    }
}

よっしゃ!これで動くぞ!と思いきや。。。
スタートボタンを押して、BallとPaddleがぶつかってもすり抜けてしまうのではないでしょうか。。。?
そうなんです、残念ながらまだ完成ではないのです。。。
プログラム的には完成なのですが、BallとPaddleそれぞれに衝突を判定させるためのあるコンポーネントを追加しなければなりません。
それは「Rigidbody 2D」と「Collider 2D」です。
「Rigidbody 2D」はオブジェクトに物理演算を加えるもので、「衝突」という物理的な事象もこのコンポーネントがあることによって検知されます。
「Collider 2D」はオブジェクトの当たり判定の範囲を定義することができます。これがついていないと、そもそもの当たり所が無くなってしまい、存在は見えているけれども触れられない。。。まるで雲?幽霊?の様な存在になってしまいます。
これら2つのコンポーネントをそれぞれに付けてあげましょう。
「Rigidbody 2D」付け方は簡単で、それぞれ「Hierarchy」上の「Ball」または「Paddle」をクリックした後、「Add Component」をクリックし、検索ボックスで「ri」辺りまで入力して「Rigidbody 2D」をクリックすれば完成です。これだけ!

次に「Collider 2D」は少々ややこしく、BallとPaddleで加えるコンポーネントがやや異なります。それぞれ「Hierarchy」上の「Ball」または「Paddle」をクリックした後、「Add Component」をクリックし、検索ボックスで「co」辺りまで入力します。次に、Ballは「Circle Collider 2D」を、Paddleは「Box Collider 2D」をそれぞれクリックすれば完成です。

さあ、ようやく完成か。。。と思いきや、最後にもう一息です。
今回は衝突と言えども、実際に衝突させて物理的な処理を加えるというよりも、衝突を「検知」して、数字上で変化させるという処理を取っています。
前者ではない理由としては、実際に物理的に衝突させると、その反動でPaddleが吹っ飛ばされたりするからです(笑)
そこで、今回はあくまで「検知」だけですよーということを示すべく、Ball、PaddleそれぞれのColliderの「is Trigger」チェックボックスにチェックを入れてようやく完成です。お疲れ様でした!

実際にゲームを実行すると。。。いかがでしょうか?無事、PaddleがBallを跳ね返したのではないでしょうか??


おわりに

3回の記事を経てようやくPaddleが一段落着きました。。。
いかがでしょう?時間はかかりましたが、その分、プログラムを書く際にどの様な思考をしてどの様な方針で進めれば良いかが実感できたのではないでしょうか?
次回はいよいよブロックを置くことでよりゲーム感を高めていきます!
勘の良い方がお気づきかもしれませんが、ここでも今回出てきた衝突判定が出てきます。
少々新しい知識も必要とはなりますが、基本的には今までの知識を活用すれば実装できる内容となっていますので、安心してついてきてください!
乞うご期待!

 


連載目次リンク

「初心者のための」Unityゲーム制作 目次

Unity実践編 - 目次リンク

実践Unityゲームプログラミング 連載目次