Unityで衝突(コライダー)を扱うの時、衝突判定をしたいオブジェクト、したくないオブジェクトが出るかと思います。今回は、衝突判定のON/OFFをレイヤーベースで切り分けるメモです。
はじめに
Unityのバージョンは2021.3.14f1です。
今回実装するのは、下記のような「弾は壁を抜けるが、プレイヤーは壁を抜けない」みたいなものです。色々な方法がありますが、今回はLayerで切り分ける方法で実装してみます。
実装開始
オブジェクトを作成し動くようにしてから、衝突検出の設定をしていきます。
オブジェクト作成
「2D Object」→「Sprites」→「Square」を2つ追加します。それぞれの名称を「Player」と「Wall」にしておきます。
「Wall」はスケールを変更し、色を薄くして壁にします。
左の白四角がプレイヤー、真ん中の線が壁です。
プレイヤーの設定
Playerオブジェクトに「Rigidbody2D」と「BoxCollider2D」をアタッチします。GravityScale(重力)は0に。
下記スクリプトを作成してPlayerオブジェクトにアタッチします。とりあえずキー操作で動くようにしてあります。
using UnityEngine; public class Movement : MonoBehaviour { private float speed = 5.0f; private Rigidbody2D _rb; private Vector2 movement; private void Awake() { _rb = GetComponent<Rigidbody2D>(); } private void Update() { movement.x = Input.GetAxisRaw("Horizontal"); movement.y = Input.GetAxisRaw("Vertical"); _rb.velocity = movement * speed; } }
Wallには「BoxCollider2D」をアタッチします。
この状態で動かしてみるとコライダーが設定してあるので、下記のようにプレイヤーは壁にぶつかります。
弾の作成
次に弾を設定していきます。「2D Object」→「Sprites」→「Circle」を追加します。
名前をballにしてサイズと色を変更。
ballに「Rigidbody2D」と「CircleCollider2D」をアタッチ。GravityScaleは0に。
下記スクリプトを作成してballにアタッチ。弾を右方向に動かすスクリプトです。
using UnityEngine; public class ballMove : MonoBehaviour { private float _force = 10.0f; private Rigidbody2D _rb; private void Start() { _rb = GetComponent<Rigidbody2D>(); _rb.velocity = transform.right * _force; } }
スクリプトをアタッチしたら弾をプレハブ化して、ヒエラルキーから削除します。
弾を発射
次に下記スクリプトを作成、スペースキーを押すと弾を発射するスクリプトです。
using UnityEngine; public class Shoot : MonoBehaviour { [SerializeField] private GameObject _ball; private void Update() { if (Input.GetKeyDown(KeyCode.Space)) ShootBall(); } void ShootBall() { Vector2 _ballPos = new Vector2(transform.position.x + 1, transform.position.y); Instantiate(_ball, _ballPos, transform.rotation); } }
Playerにスクリプトをアタッチして、変数にballプレハブをセット。
この状態で動かしてみます。スペースキーを押して弾を発射すると壁にぶつかります。
Layerを設定
各オブジェクトにLayerを設定して「弾は壁を通過」、「プレイヤーは壁にぶつかる」ようにしていきます。
まずは「Add Layer…」からLayerを追加します。
追加するのは「Player」、「Wall」、「Ball」の3つ。
それぞれのオブジェクトにLayerをセットします。
次に、「Edit」→「ProjectSettings…」を選択。
Physics2Dの一番下にある「LayerCollisionMatrix」を設定します。今回「Ball」と「Wall」は衝突してほしくないので、BallとWallのクロスする場所のチェックを外します。
これで実行すると、弾は壁を抜けるようになります。詳しくは下記のドキュメントが参考になりますね。