ゴマちゃんフロンティア

アザラシが大好きなエンジニアの開発日記です

【Unity】レイヤー設定でオブジェクト同士の衝突判定を無くす方法

time 2017/04/26

というわけで、会社のUPSに掃除機に挿して負荷電源を叩き落したりべるんです。
・・・接続されていたのが自分のPCだけでよかったです。いや本当に。
無知って罪ですね。

今回は「レイヤーを設定してオブジェクト間の衝突判定を無くす」お話です!
「特定のオブジェクト同士のみ衝突判定を無くしたい!」と思うことはあります。自分のゲームで言えば、プレイヤーキャラクターと敵キャラクターとの衝突判定が邪魔になってきました。とは言え、判定をトリガーにしてしまうと地形等をすり抜けてしまいます。
そんなときはレイヤーの設定を行うとさくっと解決できます。知っている人には今更な話題ですが、割とよく忘れることでもあるので、メモも兼ねて書いてみます。

設定方法

レイヤーの追加

まずオブジェクトに設定するレイヤーを追加します。「Project Settings」→「Tag and Layers」からマネージャを開きましょう。

今回は素直に「プレイヤーキャラクター」と「敵キャラクター」に設定するレイヤーを追加します。
ちなみにすぐ上の「Sorting Layers」は別物なので気を付けます。

オブジェクトにレイヤーを設定

次にオブジェクトにレイヤーを割り当てます。
設定対象のオブジェクトを選択し、インスペクターの右上の「Layer」を変更します。

設定したオブジェクトが子オブジェクトを持つ場合、「子にもレイヤー変更適用します?(要約)」と聞かれます。ここで「親のみに適用する」か、「子にも適用する」かはオブジェクトの構成やゲームの仕組みによって変わってきます。
例えば、攻撃判定やプレイヤー索敵用の判定(Collider系コンポーネント)などが子オブジェクトに設定されている場合、その子オブジェクトまでレイヤーを変えてしまうのはよろしくありません。逆にキャラクターのboneに沿って厳密に判定を設定していたりする場合、子オブジェクトにまで適用しないと衝突してしまいます。

ちなみに自分の場合、キャラクター毎の判定は親オブジェクトのみ、攻撃判定は動的に生成しているので、どちらを選んでもあまり関係なかったりします。

レイヤー同士の衝突判定設定

最後にレイヤー同士の衝突判定を設定します。「Project Settings」→「Physics」を選択します。
インスペクター一番下の「Layer Collision Matrix」から、レイヤー同士の衝突判定を変更できます。

少し分かりにくいのですが、「Player」と「Enemy」が交わる部分のチェックボックスを外します。左軸に登録されたレイヤーから表示されるので、先に登録したレイヤーを探し出し、そこから上軸のレイヤー名と見比べると少しやりやすいかも。
そこまで頻繁に変えるものではないので、最初に設定するときだけ気を付ければ良いと思われます。

衝突しないレイヤーとの判定を行いたい場合

レイヤー設定を行うことで衝突判定を無くすことができますが、トリガー系の判定まで反応しなくなってしまいます。このままでは「OnTriggerEnter()で敵キャラクターの時だけこの処理を~」といったことが面倒になります。
この場合、素直に別オブジェクトでCollider系コンポーネントを1つ追加し、トリガーに設定してしまうのが手っ取り早いです。当然ですが、設定するオブジェクトのレイヤーは別のものにするか、デフォルトのままで変えないようにしましょう。

例えばキャラクターであれば、Amatureの胴体となるboneに判定用として付けるのがよさそうです。レイヤーは別のものに(ry
「レイヤーをもっと細分化する」「動的にレイヤー設定を変更する」でも解決できそうですが、後々の修正・管理を考えるとオブジェクトを追加したほうが楽でしょう。

スクリプトからレイヤー設定を変更する

Physicsクラスの静的フィールドや関数で変更できます。
下のスクリプトの場合、「test1」レイヤーと「test2」レイヤーで衝突を無視するようになります。

void Start () {
    int test1 = LayerMask.NameToLayer("test1");
    int test2 = LayerMask.NameToLayer("test2");

    Physics.IgnoreLayerCollision(test1, test2);
}

レイヤーマトリックスを動的に変えることはあまりないと思われますが、一応こんなこともできるということで。
また、IgnoreLayerCollision()実行時に影響を受けるコライダーはリセットされるようなので気をつける必要があります。

あとがき

そんなわけで、Unityのレイヤー設定について少し書いてみました。
レイヤーは直接的な物理演算の他、レイキャスト時の対象を選別する際にも使用することが多いので、あれこれ混ざらないように整理したいところです。

down

コメントする