こんにちは、slashです。
今回はUnityの当たり判定の設定方法です。
オブジェクト同士が衝突したかどうかの判定、
衝突した時に何らかの命令を実行させる、
といった事をやっていきます。
下準備
今回はオブジェクトの辺り判定を設定するので
適当にオブジェクトの画像を用意しておきます。
①基本的な当たり判定の設定
オブジェクトの設置、当たり判定の設定をしていきます。
playerオブジェクトの設定
まず、プレイヤー画像をシーンに設置します。
オブジェクト名はplayerとしておきます。
Rigidbody2Dをアタッチ
playerオブジェクトを選択し、
AddComponent>physics2D>Rigidbody2Dをアタッチします。
Rigidbody2Dをアタッチする事で
オブジェクトに力をかけて動かしたりと
物理的な挙動をさせる事ができます。
当たり判定の設定
さらにコンポーネントを追加していきます。
AddComponent>physics2D>BoxCollider2Dを選択します。
BoxCollider2Dは矩形の当たり判定です。
BoxCollider2Dをアタッチすると、
オブジェクト周囲に四角の枠が表示されますが、
これが当たり判定となります。
EditColliderの横のアイコンをクリックすると、
当たり判定の大きさや位置を調整できます。
地面の設定
次は地面を作ります。
地面の画像をシーンにドラッグアンドドロップでセットします。
オブジェクト名はgroundとしておきます。
そしてgroundに先ほどと同様の方法でBoxCollider2Dをアタッチします。
playerとgroundの位置関係は
playerがgroundの上に来るように位置を調整しておきましょう。
実行してみる
ゲームを実行してどんな動作になるか確認します。
playerが重力に引っ張られて落下し、
地面にぶつかって止まる動作になるかと思います。
これでplayerとgroundとの当たり判定動作ができました。
②接触した時に何らかの動作をさせる
次に、オブジェクト同士がぶつかった時に
何らかの動作をさせるスクリプトを作ってみます。
C#Scriptを作る
新規でC#Scriptを作り、PlayerControllerという名前にします。
これをplayerオブジェクトにアタッチします。
そして、スクリプトを以下のように更新します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
void OnCollisionEnter2D(Collision2D collision)
{
Debug.Log("Landed!");
}
}
playerオブジェクトが何か他の当たり判定にぶつかった瞬間に
OnCollisionEnter2D(Collision2D collision)
のメソッド内に記述した命令が実行されます。
上記の場合はプレイヤーが他の当たり判定に接触した時に
コンソールにLanded!というメッセージが出る動作となります。
実行する
playerが地面にぶつかった時に
Landed!というメッセージが出たら成功です!
③タグを使ってみる
先ほどの例で、オブジェクト同士が接触した時に
命令を実行させる事ができましたが、
次は接触したオブジェクトに応じて
動作を変えられるようにしたいと思います。
具体的にはオブジェクトにtagを設定し、
接触したオブジェクトのtagに応じて
それぞれ異なる動作ができるようにしていきます。
オブジェクトにtagをつける
ここから、各オブジェクトにタグを設定していきます。
playerのtag
playerオブジェクトを選択し、
インスペクターのTagからPlayerを選択します。
これでplayerのタグ設定は完了です。
groundのtag
groundオブジェクトを選択し、
インスペクターのTagからタグを選びますが、
タグは新しく追加する事ができます。
インスペクターのTag>Add Tag…を選択します。
「Tags」の「+」マークをクリックすると、
タグの名称を入力するウィンドウが出てくるので、
Groundという名前を入力して「Save」をクリックします。
これで「Ground」というタグが新しく使えるようになりました。
その後、groundオブジェクトを再選択>Tag>Groundを選択します。
enemyのタグ
まず、敵キャラの設置をします。
enemy画像をシーンビューにドラッグアンドドロップでセットします。
そして、先ほどplayerに対して行ったのと同様に
rigidbody2Dと当たり判定を設定します。
今回のenemy画像は丸っこい形状をしているので
当たり判定はBoxCollider2Dではなく
CircleCollider2D(円形の当たり判定)をアタッチします。
rigidbody2Dは
playerにアタッチした時と同じ方法で
アタッチしておきます。
これで敵キャラの設置ができたのでタグを設定します。
先ほど、「Ground」タグを作った時と同様の方法で
「Enemy」というタグを作ります。
そして、敵キャラのオブジェクトに対して
「Enemy」タグを設定します。
接触時の動作を作成する
スクリプトを更新して
敵キャラや地面に接触した時の動作を作成します。
PlayerControllerのスクリプトを再度開き、
OnCollisionEnter2Dメソッドを以下のように変更します。
void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.tag == "Ground")
{
Debug.Log("Ground");
}
else if (collision.gameObject.tag == "Enemy")
{
Debug.Log("Enemy");
}
}
collision.gameObject.tagには接触したオブジェクトの
タグが代入されます。
例えば、playerがGroundタグを設定したオブジェクトに接触すると、
collision.gameObject.tagが”Ground”となります。
タグを使い分ける事で
「playerが何に接触したか」を判別可能となり
接触した物に応じてそれぞれ
異なる挙動をさせられるようになるわけです。
上記スクリプトの場合ですと、
playerが
地面に接触するとコンソールに「Ground」という文字列が出力され、
敵キャラに接触すると「Enemy」という文字列が出力される、
という動作になります。
プレイヤーが動けるようにする
さて、接触時の動作を作成したので
早速テストプレイといきたいところですが・・・
このままでは、
地面とプレイヤーは接触できますが、
敵キャラとプレイヤーは動けないので
接触することができません。
そこで、キー入力で
プレイヤーを左右に動かせるようにします。
PlayerControllerを以下のように更新します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
float PlayerSpeed = 0.0f;//プレイヤー速度
// Start is called before the first frame update
void Start()
{
}
void Update()
{
if (Input.GetKey(KeyCode.LeftArrow))
{
//左キーが押されている
PlayerSpeed = -0.1f;
}
else if (Input.GetKey(KeyCode.RightArrow))
{
//右キーが押されている
PlayerSpeed = 0.1f;
}
else
{
//左キーも右キーも押されていない
PlayerSpeed = 0.0f;
}
}
void FixedUpdate()
{
transform.Translate(PlayerSpeed, 0.0f, 0.0f);
}
void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.tag == "Ground")
{
Debug.Log("Ground");
}
else if (collision.gameObject.tag == "Enemy")
{
Debug.Log("Enemy");
}
}
}
プレイヤーの速度を代入する変数として
float型の変動のPlayerSpeedを定義します。
Update()メソッドは毎フレーム実行されるメソッドなので
ここに、キーの入力状況に応じて
PlayerSpeedの値が変化するようにスクリプトを書きます。
Input.GetKey(KeyCode.LeftArrow)は
キーボードの左キーが押されている間はtrue
押されていなければfalseとなるので、
if (Input.GetKey(KeyCode.LeftArrow))と書くと
キーボードの左キーが押されている間だけ
実行される条件分岐ができます。
同様に、Input.GetKey(KeyCode.RightArrow)は
キーボードの右キーが押されているかどうかの
判定に使う事ができます。
上記スクリプトでは、
左キーが押されている間はPlayerSpeedが-0.1、
右キーが押されている間はPlayerSpeedが0.1、
どちらも押されていない場合はPlayerSpeedが0と
なるようにしています。
次にFixedUpdate()メソッド内に
transform.Translate(PlayerSpeed, 0.0f, 0.0f);
と、書くことで
playerをPlayerSpeedの速度で左右に動かす事ができます。
実行して動作確認
それではゲームを実行してみます。
キーボードの左右キーで
プレイヤーを左右に動かす事が
できるようになっているかと思います。
プレイヤーが地面に接触した時に「Ground」
敵に接触した時に「Enemy」が
コンソールに出力されていれば成功です。
結構、記事が長くなったので
part2へ続きます。