Unityで「当たり判定」(衝突判定)を付ける方法
19/02/11 13:41:25 19/02/17 20:06:16
アクションゲームでは特に当たり判定がゲームの精度のカギを握ります。当たり判定のタイミングがおかしいとユーザーの満足度が圧倒的に下がるでしょう。当たり判定を自分で実装する場合、座標を取得してif文で重なっているかどうかを判定するのが一般的です。
普通に実装しても難しいロジックではないのですが、たとえば敵や壁ごとにいちいちクラスオブジェクト等を呼び出すのは冗長です。そこで便利なのがUnityのコンポーネントです。
これを使えばいちいち自分でコードを書かなくても簡単に当たり判定ができます。
目次
rigidbodyで当たり判定を行う
Unityで当たり判定を行うには、rigidbodyというツールを使用します。rigidbodyは物理演算用のツールなのですが、当たり判定のロジックも物理演算のなかに含まれます。開発者が深く考えずとも、現実の物理法則に従って違和感のないゲームを実現してくれるのです。
普段生きていて物理法則を深く考えることはありませんが、ゲームの世界では当然プログラミングした通りにしか動きません。しかし現実世界ですべての物理法則を正確に捉えているわけではないため、正確にゲームで再現するのは困難です。
これを簡単にするのがrigidbodyなので、当たり判定に限らずrigidbodyはUnityのなかで超重要な機能です。以下に例としてオブジェクトを作り、当たり判定をしてみます。
地面とボールを作る
まず地面オブジェクトを以下のように作ります。
「Hierarchy上で右クリック」→ 3DObject → Cube
これで四角いオブジェクトが作られました。次に、オブジェクトの設定を行います。設定は自由ですが、たとえば以下のように設定します。
Position,Rotation(0,0,0)
Scale(5,1,5)
こうすることで、四角が拡大されて地面のような感じになります。地面ができたらボールを作ります。ボールを作る手順は以下です。
「Hierarchy上で右クリック」→ 3DObject → Sphere
これでボールができました。ボールのポジションは自由ですが、たとえば以下のように設定します。
Position(0,5,0)
これで地面の真上にボールが来ます。次に、いよいよrigidbodyを設定していきます。
rigidbodyを設定する
rigidbodyを設定する流れは以下です。
ボールを選択する → AddComponentボタンを押す → rigidbodyを検索し、出てきたrigidbodyを選択する
これでオブジェクトにrigidbodyが追加されました。次にボールが地面に当たったタイミングで跳ね返るように設定します。具体的には以下の流れです。
ロジェクト上で右クリック→Create→PhysicMaterial をクリック → Bouncinessを0.9に設定 → Physic Material」をクリック
これで勝手にうまく反発するようになりました。当たり判定ではありませんが、ほぼ同じ仕組みです。ここまでで見てきた通り、プログラミングせずに設定だけでオブジェクトとオブジェクトがぶつかったタイミングを把握できます。
これだけで実際当たり判定のようなものなのですが、ゲームの場合たとえば敵にぶつかったらHPが減る、といった処理が必要です。rigidbodyでできるのはオブジェクトが当たったかどうか判定するところまでで、その後HPを減らすような処理は別で実行する必要があります。
流れとしては、当たり判定し、別処理に投げるイメージです。
当たり判定時に実行するプログラムを用意する
上で説明した流れで当たり判定できますが、当たり判定をしたら実行するプログラムが必要です。設定する方法は以下です。
Sphereオブジェクトを選択中に、「InspectorウィンドウのAddComponentボタン」→「NewScript」→ 名前をMyScriptにして「Create and Add」
ここからスクリプトを記述できます。たとえば以下のようにスクリプトを記述します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MyScript : MonoBehaviour {
void OnCollisionEnter(Collision collision)
{
Debug.Log("当たり判定");
}
}
これを実行すると、ボールが地面に当たったタイミングで「当たり判定」とログが出力されるようになります。この処理だとログが出るだけですが、ゲームだとダメージを受けたり逆にダメージを与えたりします。
上のコードのなかでは特にOnCollisionEnterの部分が重要なので、この関数について詳しく見ていきます。
OnCollisionEnterとは
OnCollisionEnterだけのサンプルコードを見てみると、以下のようになります。
void OnCollisionEnter(Collision collision)
{
Debug.Log("当たり判定");
}
OnCollisionEnter関数はオブジェクトが衝突すると自動的に呼び出されるものです。引数は衝突した相手の情報で、情報を取得するメソッドも存在します。たとえば以下のコードを実行すると衝突した相手の名前を取得できます。
void OnCollisionEnter(Collision collision)
{
Debug.Log(collision.gameObject.name);
}
これで衝突した相手の名前を取得することができ、たとえば衝突した相手ごとに処理を変えるようなことも可能です。ゲームだと攻撃ごとに相手に与えるダメージが異なりますが、こういった判定もできます。
また、当たった瞬間だけでなく、当たっている間、離れたとき、といったタイミングで処理を行う関数も存在します。まとめておくと以下のようになります。
OnCollisionEnter
触れたときに呼ばれる
OnCollisionStay
触れている間呼ばれる
OnCollisionExit
離れたときに呼ばれる
またこれは面白い部分でもあるのですが、衝突速度が速すぎるとすり抜けることがあります。Unityでもその他のゲーム開発ツールでもメモリの処理の負担を減らすために衝突速度判定する速度制限があるのですが、それを超えるとすり抜けます。
Unityの場合Fixed Timestepというもので速度制限を上げることができますが、気になる人は調べてみてください。最近のゲームでは意図せずすり抜けるようなことはありませんが、古いゲームだと意図せずすり抜けるようなこともあり、ある意味裏技のように扱われていました。
ゲームの精度を上げるという意味では当然意図せずすり抜けてしまうようなことは避けた方が良いですが、あえてこういった裏技を残しておくなら面白いかもしれません。
まとめ
以上、Unityで当たり判定を付ける方法を解説しました。Unityを使えば当たり判定のロジックを自分で書く必要はなく、関数を使うだけです。関数の使い方さえ覚えれば簡単に実装できます。
今回紹介した以外にも何かしら処理を思いついたら、Unityで実現できないか調べてみるのがおすすめです。
【Unity関連記事】
▼Unityの基礎編
・ 【unityのフリーランス求人・案件情報】エンジニア需要や開発単価、未経験でもいける?
・ 【unity入門】ゲーム開発だけじゃない、Unityで出来ること
▼Unityの外部アセット、リソース編
・ UnityでMMDモデルを自由自在に動かしてみよう!
・ Unity adsを使って簡単に広告を導入しよう
・ Unityのアセットストアの上手な使い方
・ Unityで作られているARアプリをまとめてみました
▼Unityのコンポーネント編
・ Unityのrigidbodyを使って物理演算を導入してみよう
・ コードを使わずにUnityでキャラ追従のカメラを作る方法
・ Unityで簡単にアニメーションを作成する方法をまとめました
・ Unityでオブジェクトを回転させる方法をわかりやすくまとめました
・ Unityのtransformを使ってオブジェクトの座標や回転を操作する
・ Unityのアニメーターを簡単に作成する方法まとめ
・ UnityのShaderの解説と使い方まとめました
・ (この記事)Unityで「当たり判定」(衝突判定)を付ける方法
・ Unityのgetcomponentの上手な使い方と使用時の注意点まとめ
・ Unityでキャラの移動を制御する方法まとめ
・ Unityのraycastを使って出来ることをまとめました
▼Unityのデフォルト機能、ゲーム製作編
・ blenderで作ったオブジェクトをUnityで組み込んでみよう
・ Unityのコルーチンとは?使い方をまとめました
・ Unityで作られているRPGゲームを作るための6つのステップ
・ Unityのパーティクルを使って演出できるエフェクト例
・ UnityでのUIデザインの基礎をまとめてみました
・ Unityのcloud buildの便利な点をまとめました
・ Unityを使って半日でFPSゲームを作ってみよう
人気記事