最初に
・実行環境のUnityはバージョン[2019.3.1f1]です!
・OnTriggerEnter()やOnCollisionEnter()で当たり判定じゃなくて、RayCast()でヒットした判定を行いたい。
・引数にLayerMaskを指定する場合で特定のオブジェクトのLayerを(「Project Settings」の「Physics」の「Layer Collision Matrix」のマトリクスを)引数にしたい場合。
#日本語がもう駄目かも
ごにゃごにゃ書くの面倒なのでソースと結果(画像)を乗っけます。
(マトリクス作成)汎用的なスクリプトか何か
GameSetting.cs
using UnityEngine;
using System.Collections.Generic;
public class GameSetting : ScriptableObject {
private static GameSetting s_instance = null;
public static GameSetting Instance {
get {
if (s_instance == null) {
InitMaskTable();
s_instance = CreateInstance<GameSetting>();
}
return s_instance;
}
}
private static Dictionary<int, int> _masksByLayer;
private static void InitMaskTable() {
_masksByLayer = new Dictionary<int, int>();
for (int i = 0; i < 32; i++) {
int mask = 0;
List<string> name = new List<string>();
for (int j = 0; j < 32; j++) {
if (!Physics.GetIgnoreLayerCollision(i, j)) {
mask |= 1 << j;
//Debug
if (LayerMask.LayerToName(j) != "") {
name.Add(LayerMask.LayerToName(j));
}
}
}
//Debug
if (LayerMask.LayerToName(i) != "") {
Debug.Log("[" + LayerMask.LayerToName(i) + "] is masked [" + string.Join(",", name) + "]");
}
_masksByLayer.Add(i, mask);
}
}
public int MaskForLayer(int layer) {
return _masksByLayer[layer];
}
}
(使い方)RayCastで当たり判定を行おうとしているスクリプトのやつ。
Bullet.cs
~~ 省略 ~~
if (Physics.Raycast(startPosition, direction, out RaycastHit hit, distance, GameSetting.Instance.MaskForLayer(gameobject.layer), QueryTriggerInteraction.UseGlobal))
~~ 省略 ~~
結果
Unity起動してのログ
Physicsのマトリクスで指定したと通りのログが出力されてます。
※例を挙げるとマトリクス(左下)で[Area]にチェックが入っているのは[PeopleForArea]だけで、
ログ(右下)でも"[Area] is masked [PeopleForArea]"と確認できる。
[情報元]
https://forum.unity.com/threads/is-there-a-way-to-get-the-layer-collision-matrix.260744/