【第13回】落下判定用のColliderを配置するUnityチュートリアル

【第13回】落下判定用のColliderを配置するUnityチュートリアル

前回のチュートリアルでは、ボールの飛距離を更新し続け、停止した時のハイスコアを表示する方法をお送りしました。

ボールの飛距離が変わっていくと、今動いているのかどうか、プレイヤーも分かりやすくなります。

さて、現在の実装ではボールが止まった時に、飛距離の測定停止とハイスコアの更新を行なっています。

ここでひとつ問題が……。ボールが止まらなかった場合に、延々と計測が続いちゃうんです。ボールが止まらないケースと言えば、ボールが飛び上がった後、地面に衝突することなく落ちていくケース。

今回は地面をコースとみなし、コースアウトしたことを検知するためのオブジェクトを配置します。

前回のチュートリアルはこちらから。

 

今回の目的

ボールがコースアウトしたことを検知するためのオブジェクトを配置します。

スクリプトによる処理は次回行います。

これはいわゆる落下判定なので、このチュートリアルで作っているゴルフっぽいゲームや、アクションゲームで超お役立ちです。

プロジェクトの準備

前回のチュートリアルで作成したプロジェクトをそのまま使います。

このページに先にたどり着いた方は、チュートリアルの初回から追っていただけるといいかもしれません。

衝突判定について

ある特定の領域まで飛んで行ってしまったら飛距離の計測を止めたいので、それを判定する仕組みを作ります。

判定はアクションゲームとかでよく聞く「当たり判定」をイメージしてもらえるといいかも。アクションゲームでは敵キャラの形に合わせて当たり判定が作られているけど、今回は何もない空中に当たり判定を作りたいんです。

画面には映っていないけど、判定を行う領域が存在している、という状態ね。

Unityで当たり判定を検知するのは、Collider(コライダー: 衝突装置)コンポーネント。Colliderコンポーネントがアタッチされている別のゲームオブジェクトとColliderの範囲が重なった時、衝突したとみなして処理を行います。CERNのLHC(Large Hadron Collider)に出てくるColliderと同じ綴りです。

これまで特に触れていませんでしたが、ボールとして使っている『Sphere』オブジェクトや、地面として使っている『Plane』オブジェクトにも、ちゃんとColliderが付いています。あ、物理特性マテリアルの時にちょっと触れたかな。

Colliderコンポーネント
実はこっそりいたのだポッター

 

これがあるおかげで、地面との衝突が実現しているんです。

Sphere Colliderコンポーネントの場合は、RadiusによってColliderの大きさが決められます。デフォルトでは『Sphere』オブジェクトと同じ大きさになっていますが、試しにRadiusを[1.0]にしてゲームを実行してみましょう。すると……。

Colliderの大きさを変えたもの
う、浮いてる……!

 

球のメッシュの大きさによらず、Colliderの大きさによって衝突したと判断されます。『Scene』ウィンドウだと、以下のようにColliderの大きさが表示されます。緑色がColliderを示す線。

緑の線がCollider
『Sphere』オブジェクトの周りにうっすらとCollider

 

ここから言えることは、「メッシュを表示しなくても衝突判定できそう」ということ。透明のボックスを配置して、そのボックスと衝突したことを検知したら、落下扱いにする、なんて処理ができそうですね。

実際に落下判定に使うメッシュを配置する前に、もう一個実験をはさみます。

 

トリガーとして使う

『Sphere』オブジェクトと『Plane』オブジェクトのColliderが重なった時、今の状態では物理特性マテリアルによって、ぶつかって跳ね返る様子が表現されています。

上で、メッシュが表示されない透明なボックスを用意すると言いましたが、そのボックスのColliderとごっつんこして跳ね返っては意味がありません。

実はColliderには物理的な衝突処理を行うだけではなく、衝突判定だけ検知する方法があるんです。それはトリガーとして使うこと。

Unity公式のマニュアル内『コライダー』に、「IsTriggerにチェックを入れると判定だけするよ(意訳)」と記載があるので、それを使いましょ。

試しに『Plane』オブジェクトのColliderでIsTriggerにチェックを入れてみます。

IsTriggerの設定
判定だけお願いしまーす

 

ゲームを実行するとこんな感じ。開始直後に自由落下していきます。『Plane』オブジェクトのColliderでIsTriggerにチェックが入っていると、物理的にはすり抜けてしまうんですね。あ、確認が終わったらisTriggerを外しておくのを忘れずに。

床をすり抜ける
これが……これが量子トンネル……!

 

画面ではすり抜けているものの、内部では衝突があったことを検知しているので、イベント関数のOnTriggerEnter()を使ってスクリプトから拾うことができます。名前がズバリな感じです。

だんだんとできそうな気がしてきました。これを踏まえて、落下判定用のColliderを作りましょ。

落下判定用のオブジェクトを作成

上の実験から、メッシュなしでもColliderが置けて、しかもIsTriggerを使えば、跳ね返りもなく落下判定エリアに到達したことを検知できそうです。

メッシュなしでColliderだけ持ったオブジェクトを作るなら、 立方体を作った後、Mesh関係のコンポーネントを非アクティブにするのが簡単そう。

『Hierarchy』ウィンドウで右クリックまたは二本指タップしてコンテキストメニューを開き、[3D Object] -> [Cube]を選択します。この時、他のオブジェクトを選択していないことに注意。選択した状態だと、そのオブジェクトの子オブジェクトとして作られますからね。

Cube作成
まずは立方体を作成

 

作成されたオブジェクトは『FallChecker』にリネームしました。例のごとくTransformコンポーネントの歯車アイコンから位置を[Reset]したら、『Hierarchy』ウィンドウで『Plane』オブジェクトの下に移動させます。

あとこっそりBox ColliderコンポーネントのIs Triggerにもチェックを入れました。

リネームと位置がえ
デフォルトでBoxColliderがついている

 

このままだと『Game』ウィンドウに立方体が表示されてしまいますが、Mesh Rendererコンポーネントの名前の左にあるチェックボックスをオフにすると、メッシュが描画されなくなります。

MeshRendererの設定
非アクティブにするとメッシュは描画されない

 

メッシュが非表示だと『Game』ウィンドウには映りませんが、『Scene』ウィンドウを見ると、『Sphere』オブジェクトのあたりに、立方体のColliderを示す緑の線がうっすらと見えています。

Box Collider
『Scene』ウィンドウでColliderを確認

 

空のゲームオブジェクトにBox Colliderをアタッチする方法でもいいのですが、この緑の線、細くて見づらいんですよね。このチュートリアルは初心者向けなので、メッシュで位置が判別できるよう、分かりやすい方法で実装しています。

 

落下判定オブジェクトの配置

落下判定オブジェクトを作成したら、実際に判定したい場所に配置します。

まずは『Plane』オブジェクトの下に広げてみましょ。

『Plane』オブジェクトのTransformを参考に、Y軸方向に5m下げてみました。PositionのXに[15]を入力し、Yに[-5]を入力します。

ScaleはXが[100]、Zが[50]くらいでしょうか。『Plane』オブジェクトのScale1は、『Cube』オブジェクトのScale10に相当するので、大きめに設定しておくとベネ。

FallCkeckerのTransform
Scaleは大きく

 

『Scene』ビューではこんな感じに表示されます。Mesh Rendererは非アクティブにした方がいいかも。

Colliderの確認
地面の下に落下判定オブジェクト

 

この範囲を超えてしまうと判定されなくなりますが、まずは落下判定の機能確認をしてみましょ。

それがうまくいきそうなら範囲をもっと広げるのと、ボールに加える力にも制限をかけましょう。

さて、このままスクリプトの方に……と言いたいところですが、尺の問題でイカ次回。

まとめ

今回は落下判定用のオブジェクトを配置するチュートリアルでした。

落下判定を行う方法として、ColliderコンポーネントのIsTriggerを使って検知する方法で進めています。

検知したイベントはスクリプトから拾うので、次回のチュートリアルでスクリプトの編集を行います。

アセット作ってます!

CTA-IMAGE

Unityでの開発に役立つアセットを作っています。

3DダンジョンRPGを開発するスピードを200%加速するAssetや、ファンタジーRPGのダンジョンを彩るパーツを取り揃えています。

特に3DダンジョンRPGのゲームを1から作るのは結構時間がかかります。ダンジョン部分の作成はこうしたアセットを使って、開発をブーストさせてみませんか?