[Unity 2D]当たり判定

はじめに

Unityでゲームを作成する際、当たり判定は必須の要素です。

前回は、自機からミサイルが発射されるようにしましたので、自機に当たり判定の設定をする方法を見ていきます。

過去記事は以下の通りです。

Collider

Collider(コライダー)とは当たり判定を可能にするオブジェクトです。

はじめに、ヘリコプターにColliderを設定します。Sceneビューのヘリコプターを選択してInspectorビューで[Add Component]ボタンをクリックします。

メニューが表示されるので[Physics 2D]を選択し、一覧から「Box Collider 2D」を選択します。

コライダーは、他のスプライトのコライダーとぶつかります。また反発をするようになります。

当たったということだけがわかれば良い場合は、[Is Trigger]にチェックをつけます。この場合は、ぶつかっても反発はしませんが、何かに当たったと認識した場合にトリガーが発動するようになります。

次に、当たり判定のエリアを設定します。エリアのサイズは上図のSizeで設定します。また、上図の[Edit Collider]というボタンをクリックすると、Colliderの枠が表示され、マウスでサイズ変更することができます。数値で入力して設定するよりも、範囲がわかりやすくなります。今回はBox Colliderを選択しているので矩形になっていますが Circle Colliderをアタッチしておけば円形のコライダーを使用することもできます。

壁を作成する

当たり判定を確認するために壁を作成します。

縦長の壁をイメージしたスプライトを準備してSceneビューに配置します。

作成した壁にRigidbody 2DとBox Collider 2Dを設定して、Is Triggerのチェックは外しておきます。

また、ヘリコプター側のIs Triggerのチェックも外しておいてください。これで、ヘリコプターは壁にぶつかるはずです。

実行してみると、以下のようにヘリコプターが壁に衝突すると、壁が飛ばされます。またヘリコプターはぶつかった衝撃で傾きます。

衝突時のメソッド実装

Collider 2DのIs Triggerをチェックしておくと、トリガーが発動することを説明しました。

トリガー発動時はOnTriggerEnter2Dメソッドが実行されます。

また、衝突時にオブジェクトを削除したい場合はDestroyメソッドを使用し、引数には削除したいオブジェクトを指定します。

// 衝突時のメソッド
void OnTriggerEnter2D(Collider2D c)
{
    // プレイヤーを削除
    Destroy(gameObject);
}

上記コードをheli.csに実装して実行すると、以下のように衝突時にヘリコプターが消えます。

[Unity 2D]ミサイルを発射してみる(2)

はじめに

前回はミサイルを追加して飛ばしてみるところまでを説明しました。しかし、自機から発射されているわけではないため、決まった位置から1回しか発射されません。今回は、自機からミサイルが発射されるようにします。

過去記事は以下の通りです。

シーンのミサイルを削除する

ゲームの開始時点からミサイルが表示されているのは変ですね。通常は必要なタイミングで、ミサイルをシーンに登場させる必要があります。

よってミサイルをシーンから一旦削除します。

ミサイルはすでにプレハブ(テンプレート)化してありますので、これをコードから複製して使用します。

HierarchyビューでPlayerMissileを右クリックして「Delete」を選択します。

コルーチンを作成する

Updateメソッドは、毎フレーム呼び出されるメソッドなので、主な処理はここに記述します。しかし、時間の掛かる処理をUpdateメソッド内に記述してしまうと、その処理が終了するまでゲームは待機することになってしまいます。

これを避けるために、特定の処理が終了するまで待機できるコルーチンを作成して処理します。

コルーチンは、以下の様な書式のメソッドです。

IEnumerator メソッド名() {
    for または while {
        なんらかの処理
        yield return 戻り値;
    }
}

自機のスクリプト(heli.cs)を以下の様に編集します。ここではFireメソッドをコルーチンとして作成し、Updateメソッドから呼び出しています。Fireメソッド内ではfor文で3回繰り返していますので、3発のミサイルが発射されることになります。

ちなみに、コルーチンは[f]キーが押されたときに実行する様にしています。コルーチンの実行はStartCorutineメソッドで行います。

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

public class Heli : MonoBehaviour {

 
    public float speed = 100.0F;    // 移動早さ

    //ミサイルのプレハブ格納用
    public GameObject missile;  //★ 追加

    // ★ Startメソッドをコルーチン化
    void Start () {

    }

    IEnumerator Fire()
    {
        Debug.Log("発射");
        for (int i = 0; i < 3; i++)
        {
            // ミサイルを自機と同じ位置と角度で作成する
            Instantiate(missile, transform.position, transform.rotation);
            // 0.05秒待つ
            yield return new WaitForSeconds(0.05f);
        }
    }

    // Update is called once per frame
    void Update () {
        //Debug.Log("Inputed");
        // 矢印キーの入力情報を取得
        var h = Input.GetAxis("Horizontal");
        var v = Input.GetAxis("Vertical");

        // 移動する向きを作成する
        Vector2 direction = new Vector2(h, v).normalized;

        if (Input.GetKeyDown("f"))
        {
            IEnumerator coroutine = Fire();

            StartCoroutine(coroutine);

            Debug.Log("Fire");
        }

        // 移動する向きとスピードを代入
        GetComponent().velocity = direction * speed;


    }
}

さて、スクリプト内ではプレハブを格納できるようにGameObject型の変数missileを定義しています。これにより、Hierarchyで自機(heli)を選択してInspectorビューのHeli(Script)を確認すると、missile欄ができていることがわかります。

この時点ではNone(Game Object)となっており、自機にはミサイルが関連付いていません。

ProjectビューでPrefabsフォルダを選択し、プレハブ化したPlayerMissileをHeli(Script)のMissileにドラッグ&ドロップします。

以上で作成完了です。

実行してみる

[Unity 2D]ミサイルを発射してみる(1)

はじめに

前回は、キャラクターをキーボードで操作する方法について説明しました。今回と次回で、自機からミサイルを発射する方法について説明します。

過去記事は以下の通りです。

ミサイルのスプライトを追加する

はじめに、ミサイル用の画像を準備してSpritesフォルダに追加します。

続いて、Sceneビューにミサイルを配置します。

GameObjectを作成する

GameObjectは、コンテナ(入れ物)であってそれ自体は何もしません。GameObjectは作成したいゲームに合わせて、様々なコンポーネントの設定をして使用します。例えば、移動を表すtransformは、コンポーネントの1つにあたります。コンポーネントは非常に多くの種類があるので、使用していくうちに理解できてきます。

では、GameObjectを作成しましょう。メニューの[GameObject]-[Create Empty]を選択します。

これで、空のGameObjectが作成されます。作成したGameObjectにはtransformコンポーネントが備わっています。

作成したGameObjectを以下の様にPlayerMissileと名称変更します。

Rigidbodyの追加

前回の記事を参考に、PlayerMissileにRigidbodyを追加してください。追加したRigidbodyの各値は変更せず、デフォルト値のままとします。

作成したGameObjectにミサイルを関連付ける

さて、GameObjectを作成しましたが、どのキャラクターも関連付いていません。ここで、ミサイルと関連付けをします。

Hierarchyビューで、missileを作成したGameObejctであるPlayerMissileにドラッグ&ドロップします。すると以下の様に親子関係ができます。


Unityにおいて親子関係を作成すると、親に追従して子が動くようになります。例えば、親を回転させれば子も回転しますし、親を移動させれば子も移動するようになります。

複数のミサイルを同時に飛ばしたいような場合は、このような親子関係を作成するのが一般的です。

プレハブの作成

プレハブとは、Unityにおけるテンプレートのことです。単純に、スプライトなどをコピーして使用すると、それらのオブジェクトは独立したものになってしまうため、プレハブ化して使用をします。

はじめにプレハブを保存するためのPrefabsフォルダを作成します。

次に、HierarchyからProjectビューのPrefabsフォルダーに、PlayerMissileをドラッグ&ドロップします。これでプレハブが作成されます。プレハブ化されたオブジェクトは、Projectビューでは青字になります。

ミサイルを移動するスクリプトの作成

ミサイルを移動するスクリプトを作成します。ScriptsフォルダにFire.csというスクリプトファイルを作成して、以下のように編集をします。

一度だけミサイルを飛ばしてみるのでStartメソッド内に記述することとします。

GetComponent<Rigidbody2D>().velocityでミサイルの移動をします。また代入時のVector2.left.normalizedは画面左方向を表しています。

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

public class Fire : MonoBehaviour {

    public int speed = 5;

    // Use this for initialization
    void Start () {
        GetComponent<Rigidbody2D>().velocity = Vector2.left.normalized * speed;
    }
	
	// Update is called once per frame
	void Update () {
		
	}
}

作成したスクリプトのアタッチ

スクリプトが作成できたので、PlayerMissileにスクリプトをアタッチしてください。前回記事同様、スクリプトファイルをPlayerMissileにドラッグ&ドロップしてアタッチします。

アタッチしたらPlayerMissileのApplyボタンを押して更新をしておきましょう。

実行してみる

実行すると、以下のように左方向にミサイルが発射されます。

もし、ミサイルが発射されないような場合は、スクリプトファイルがアタッチされているかどうか、PlayerMissileにRigidbody 2Dが追加されているかどうかを確認してください。

放物線を描いてミサイルが発射されました。真横に飛ばしたい婆は、Rigidbody 2Dの設定でGravityを0にしてみてください。