1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Cocos Creator 3 カンタン2Dゲーム制作(3)【衝突判定(コライダの使い方)】

Last updated at Posted at 2022-08-24

ページ一覧

Cocos Creator 3 導入編

Cocos Creator 3 カンタン2Dゲーム制作

衝突判定をおこなう

アイテムが出るようになったので、次は衝突判定を行います。
それにはCollider(コライダ)という機能を使います。

準備

2D物理演算システムの設定

メニューバーからProjectProject Settingを選択します。Project Settingダイアログが開きます。
左メニューのFeature Croppingを選択します。
2Dという見出しのあるエリアで、2D Physics Systemの右にあるプルダウンをBuiltin 2D Physics Systemに変更します。

2Dの物理演算システムには「ビルトイン」と「Box2Dベース」の二種類があります。ビルトインは複雑な物理演算はできませんが、処理が軽く、ノードが重なったかどうかの判定処理に適しています。

コリジョンマトリックスの設定

左メニューのPhysicsを選択します。Collision Matrixと書かれたエリアを表示します。
「+」ボタンを押すとテキストボックスが現れるので、Fishと入力し緑のチェックマークを押します。同様にCoinObstacleの2つも入力します。
図に示すようにFishの行と、CoinObstacleの列の交差点にチェックマークを付けます。

この後、ここで定義したGroupとノードを紐づけます。
チェックをONにしたGroup同士が「衝突判定」の対象となります。

Project Settingのダイアログを閉じます。

ノードにコライダを追加する

ヒエラルキーパネルのFishを選択し、インスペクターパネルのAdd Componentを押します。
別の小窓が出るので、Search Nameと書かれたエリアにcolliderと入力します。
いくつか候補が出てきますがここではPolygonCollider2Dを選びます。
インスペクターパネルにcc.PolygonCollider2Dが追加されるので、GroupFishを選択します。

衝突範囲の設定

EditingチェックボックスをONにすると、他のノードとの重なりを判定する範囲の設定ができます。
ここではPolygonCollider2Dを選んだので、非透過部分でくり抜かれた線が自動で設定されています。
マウス操作で頂点を移動できるので任意の範囲に設定します。
編集を終了するにはEditingチェックボックスをOFFにします。

同様の手順で、アセットパネルにあるCoinSyurikenのプレハブにもコライダを設定します。
このとき、設定するコライダはCircleCollider2Dを選びます。
またGroupはそれぞれCoinObstacleを選択します。

先ほどと同様、EditingチェックボックスをONにすると衝突判定する範囲の設定ができます。
今回はCircleCollider2Dですので多角形ではなく円形で、大きさのみ変えられます。

スコアラベルを追加する

メニューバーのPanelNode Libraryでノードライブラリパネルを開きます。
別ウィンドウで開いた場合は、ヘッダ部分をつまんで右側のペインにドッキングします。
その中からLabelを選んでヒエラルキーパネルのCanvasの配下にコピーします。
Canvasを右クリック、Create2D ObjectLabelでも同様です。)
名前をScoreとします。

インスペクターパネルから、positionAnchor PointStringFont Sizeをそれぞれ入力します。

衝突判定スクリプト

アセットパネルに新規スクリプトを追加し、名前をFishCollisionとします。
以下のコードを記述します。

FishCollision.ts
import { _decorator, Component, Node, Collider2D, Contact2DType, IPhysics2DContact, log, Label } from 'cc';
const { ccclass, property } = _decorator;

// コリジョングループ定数
enum CG {
    default = 0,
    fish = 2,
    coin = 4,
    obstacle = 8
}

@ccclass('FishCollision')
export class FishCollision extends Component {

    @property(Label)
    score: Label = null;

    _score: number = 0;

    start() {
        // 衝突判定
        this.enableCollider(true);

        // スコアの初期化
        this.score.string = "0";
    }

    onDestroy() {
        this.enableCollider(false);
    }

    // 衝突判定の有効/無効切り替え
    enableCollider(enable: boolean) {
        let collider = this.getComponent(Collider2D);
        if (enable) {
            collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
        } else {
            collider.off(Contact2DType.BEGIN_CONTACT);
        }
    }

    onBeginContact(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {
        switch (otherCollider.group) {
            case CG.coin:
                // コインにヒットした場合
                this._score += 100;
                break;
            case CG.obstacle:
                // 障害物にヒットした場合
                this._score -= 100;
                break;
        }
        // スコア更新
        this.score.string = this._score.toString();
        // コインまたは障害物の消滅
        otherCollider.node.destroy();
    }
}

魚のノードとスクリプトの紐づけ

ヒエラルキーパネルのFishを選び、インスペクターパネルのAdd Componentで、今追加したスクリプトFishCollisionを紐づけます。
FishCollisionの枠が追加されたら、Scoreの枠がブランクになっているので、右側のアイコンをクリックし、Scoreを選びます。これによりスクリプト内でシーン上のスコアラベルが更新できます。

ここまでの動きの確認

▶ボタン(またはctrl+P)で動きを確認してみましょう。正しく作れていれば、アイテムとヒットしたときにスコアをカウントします。

スクリプトの解説

衝突判定の開始

自身のノード(Fish)からCollider2Dコンポーネントを取得ます。
collider.on()を使ってContact2DType.BEGIN_CONTACTイベント発生時に、this.onBeginContactを呼び出すよう設定しています。

抜粋
let collider = this.getComponent(Collider2D);
collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);

衝突イベント発生

onBeginContact()メソッドでは、イベント発生時の情報が引数として渡されます。
otherCollider.groupを使って衝突した対象のノードの種類を特定し、スコアの加算・減算を行います。

コリジョングループはビット単位で管理されており、コリジョンマトリックスの画面で設定したGroup名に対応するindexの1,2,3は、それぞれ2,4,8となります。

ゲームの演出上、衝突したらアイテムは消したいので、衝突対象に対しdestroy()でノードを消滅させます。

otherCollider.node.destroy();
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?