どんなゲームにも「当たり判定」が必要です。

当たり判定によって、敵キャラクターに当たったり、壁にぶつかった事をシステムが判断します。例えば、スーパーマリオでマリオがクリボーに当たったのに、マリオもクリボーにも何の影響も無いなんてのはゲームではありませんよね。

当然、Unityでもこの当たり判定を実装する事ができます。しかも、昔のゲーム開発に比べるとすごく簡単に。当たり判定については色々と覚える事もあるのですが、基本的な考えを学んでおけば応用できますので、基本をしっかりと押さえておきたい所です。

という事で、今回は3Dのオブジェクトを使って、Unityでの当たり判定について解説をしていきます。

Unityで簡単に当たり判定を実装する方法

Unityでは様々な方法で当たり判定を行う事ができますが、最も簡単なのは以下の2つのコンポーネント(オブジェクトの処理をまとめた様なもの)を使用する方法です。

  • Collider(コライダー)
  • Rigidbody(リジッドボディ)

実際の所、この2つのコンポーネントを使用すれば大抵の当たり判定はできてしまいます。まずは、この2つのコンポーネントについてざっくりと紹介します。

■Collider(コライダー)
Colliderはオブジェクト同士がぶつかった時のイベントを定義するものです。厳密には当たり判定のオブジェクト形状を定義するものと言われています。

■Rigidbody(リジッドボディ)
Rigidbodyはオブジェクトの物理的要素・イベントを定義するものです。

オブジェクトに重力を与えたい場合などによく活用されます。ColliderとRigidbodyを活用した簡単なゲームを作っていますので、こちらを見てもらうと使い方が分かるかもしれません。

Collider(コライダー)とRigidbody(リジッドボディ)を活用した当たり判定

ではCollider(コライダー)とRigidbody(リジッドボディ)を活用して当たり判定を実装してみましょう。実は、ColliderとRigidbodyの基本的な使い方は以前既に紹介しているので、今回は、この時に作成したものを基に話を進めます。

■ColliderとRigidbodyを使ったアニメーション

3Dのボールが坂をころころと転がるアニメーションです。

このアニメーションでも当たり判定を実装しているんですが、もっと説明を分かりやすくするために、ここからさらに変更してみました。

まずは3Dのボール(Sphereオブジェクト)を追加で配置します。

■ボール(Sphereオブジェクト)を配置

配置したボールのInspecterウィンドウを見てみて下さい。実は既にCollider(コライダー)のコンポーネントが付与されています。これはUnity側が3Dオブジェクトを作ったら、Colliderも使うでしょ!と考えてデフォルトで設定してくれているのだと思います。

ただ、よく見ると名前がSphere Colliderとなっていると思います。実はUnityにはオブジェクトに応じていくつかのColliderが用意されています。これはオブジェクトの形状によって、当たり判定の形が異なるため用意されていると覚えておけば良いです。ボールの場合はSphereオブジェクトなので、最初からSphere Colliderが付いているんだという認識でOKです。
※当たり判定の形状を自由に変えたり、2つの当たり判定を組み合わせたりする事もあります。これは本格的にゲームを作る時に重要になります。

■InspecterウィンドウのCollider(コライダー)

とりあえず、このまま実行してみると以下の様になります。

■実行結果

青いボールが追加したボールにぶつかって、反発していますね。反発しているという事は既に物理演算もされた上で「当たり判定」がされているのです。

UniyでCollider(コライダー)の当たり判定がされていないとどうなるのか?

さて、Unityで当たり判定されている場合のイベント処理について紹介をしました。ただ、これだけだと何が当たり判定なのかよく分からないかもしれません。今度はCollider(コライダー)のチェックをOFFにしてみましょう。

■InspecterウィンドウのCollider(コライダー)

この状態で実行してみます。

■実行結果

今度はボールとボールがぶつかってもすり抜けてしまいます。Collider(コライダー)による当たり判定が実装されていないとオブジェクト同士が衝突しても何の判定もしない状態、つまり「当たり判定」をしていない状態になります。

昔のゲーム開発は、当たり判定を実装するのが当然だったので、ここから当たり判定を実装する必要がありました。Unityの場合はオブジェクトを作った時点で当たり判定をしてくれます。これは本当に便利です!

Unityの当たり判定でボールが消えるイベントを作る!

さて、当たり判定ができていても、何のイベントも起こらないのではつまらないですよね。

ここから当たり判定でイベントを発生させる処理を追加してみましょう。ボールがボールにぶつかった時にイベントを発生させるにはOnCollisionEnterというメソッドを使います。

C#スクリプトでOnCollisionEnterを呼び出すため以下の様なコードを書きます。このコードはぶつかった瞬間にオブジェクトを破壊するというイベント処理になります。

■C#スクリプト

このC#スクリプトをドラッグしてアタッチしましょう。今回新しく配置したボールの方にアタッチします。
※ここでC#スクリプトのファイル名も「BallColliderTest.cs」としておいて下さい。

■オブジェクトにドラッグしてアタッチ

もしエラーがでたら?

ちなみにC#スクリプトをアタッチした際に、以下の様なエラーが出力される事があります。

「Can’t add script behaviour AssemblyInfo.cs. The script needs to derive from MonoBehaviour!」

これはC#スクリプトのファイル名とメソッド名が異なる際によく出力されるエラーになります。つまり、C#スクリプトのファイル名が「BallColliderTest.cs」となっていない場合はこのエラーが出力されます。

OnCollisionEnterを使ったイベントを実行してみよう!

C#スクリプトをアタッチしたらさっそく実行してみましょう。

■実施結果

ボールとボールが衝突した瞬間、つまり当たり判定された瞬間に、ボールが消えていますね。これが当たり判定時のイベント処理になります。3Dだと少し迫力がでますよね!出ませんか?

実際にゲームを作る際には、当たり判定によるイベントを作る事で、ゲームの世界にどんどん動き出して楽しいですよ。

その他の当たり判定

基本的な当たり判定の実装方法を紹介しましたが、少し変わった当たり判定についてもご紹介しておきます。

衝突はさせない当たり判定

物理的な衝突はさせずに当たり判定を行う方法を紹介します。

まずはCollider(コライダー)に「Is Trigger」というチェックボックスがあると思いますが、この「Is Trigger」のチェックを外して下さい。このチェックを外すと、物理的な効果を伴う衝突を発生させずに当たり判定のみを行うと覚えておけばOKです。

■Collider(コライダー)の「Is Trigger」のチェックをOFF

次にC#スクリプトにOnTriggerEnterという関数を追加しましょう。

既に作成しているC#スクリプトと同じ様にOnTriggerEnterの中オブジェクトを破壊する処理を実装しておきます。

■C#スクリプト

■実行結果
ボール同士がぶつかっても衝突イベントが起こる訳ではありません。その証拠にCollider(コライダー)のチェックをOFFにした時とは違ってボール同士が当たっても、青いボールは反発していません。そのまますり抜ける様に画面前方側に転がってきています。

作成するゲームやアニメーションによっては、この様な制御が必要になる事もあります。

例えば、マリオカートという有名なゲームがありますが、「Is Trigger」により物理衝突を行うか否かという判定を使いこなす事で、以下の様な条件分けができます。

  • カートが壁にぶつかった⇒物理衝突をしてカートが跳ね返る
  • カートがアイテムにぶつかった⇒物理衝突はしないので、カートは走り続けるが、アイテムを取得する

各オブジェクトとの当たり判定時のイベントは変わるので、状況に合わせて適切な当たり判定を行う必要があります。

その他の当たり判定時のイベント

OnCollisionEnterやOnTriggerEnterなどの関数を使って、当たり判定時のイベントを制御する方法を紹介しました。ただ、UnityのCollider(コライダー)には他にも様々な関数が用意されています。ここでは他の関数も併せて紹介しておきます。

Unityの公式リファレンスも紹介しておきますので、詳細についてはそちらを参考にして下さい。

■当たり判定時のイベント

引用元URL(Unityの公式リファレンス):https://docs.unity3d.com/ja/540/ScriptReference/Collider.html

※上記は公式リファレンスではColliderのメッセージという形で紹介されています。

まとめ

今回はUnityの当たり判定と、その実装方法を中心に解説をしました。

ご紹介した内容をまとめると、

  • Collider(コライダー)とRigidbody(リジッドボディ)で当たり判定を行う
  • デフォルトのオブジェクト生成時は基本的にColliderは設定されている
  • 基本的な当たり判定を行う関数はOnCollisionEnter
  • OnCollisionEnter以外にも当たり判定時のイベント処理を行う関数が複数ある

となります。

もし分からない部分があれば、もう一度今回の記事の流れをおさらいしていただければと思います。