Quick Comparison
| 도구 | 결정하는 것 | 적용 범위 | 흔한 혼동 |
|---|---|---|---|
GameObject Layer | 객체의 단일 분류 번호 | 오브젝트별 | Layer 번호와 bitmask는 같은 값이 아닙니다. |
LayerMask | query에 포함할 layer 집합 | Raycast, overlap, cast 호출별 | Collision Matrix가 query도 자동 필터한다고 생각합니다. |
| Collision Matrix | 두 layer의 물리 collision/trigger pair | Project Settings > Physics | raycast target 필터로 사용합니다. |
QueryTriggerInteraction | query가 trigger를 맞힐지 | 호출별 또는 Physics 전역 기본 | trigger 포함 여부를 생략합니다. |
[SerializeField] private LayerMask interactableMask;
bool found = Physics.Raycast(
origin,
direction,
out RaycastHit hit,
interactDistance,
interactableMask,
QueryTriggerInteraction.Ignore
);설정과 코드의 역할
Collision Matrix는 layer A와 B가 접촉할 때 collision/trigger 처리를 할지 정하는 전역 pair 규칙입니다. 투사체와 발사자, AI와 감지 전용 trigger처럼 서로 부딪히지 말아야 하는 물리 pair를 여기서 끕니다. 반면 Raycast는 호출의 layerMask와 QueryTriggerInteraction으로 무엇을 볼지 정합니다. Matrix에서 충돌을 껐다고 raycast가 해당 layer를 자동으로 무시하는 것은 아닙니다.
LayerMask 필드는 Inspector에서 체크박스로 보여 안전합니다. 코드로 만들 때는 layer index를 bit로 바꿉니다. LayerMask.NameToLayer("Enemy")가 돌려주는 것은 index이므로 그대로 query에 넘기면 잘못된 mask가 됩니다.
int enemyLayer = LayerMask.NameToLayer("Enemy");
if (enemyLayer < 0)
{
Debug.LogError("Enemy layer is missing.");
}
else
{
int enemyMask = 1 << enemyLayer;
bool hitEnemy = Physics.Raycast(origin, direction, out RaycastHit hit, range, enemyMask);
}QueryTriggerInteraction.UseGlobal은 Physics.queriesHitTriggers 전역 설정을 따릅니다. 상호작용 ray는 trigger를 무시하고, 감지 ray는 trigger를 포함하는 것처럼 호출 목적이 다르면 Ignore 또는 Collide를 명시해 프로젝트 전역 설정 변경에 덜 흔들리게 합니다.
Layer는 여러 시스템에 쓰이지만 규칙은 별개입니다
Layer는 Camera Culling Mask와 물리 query에도 사용될 수 있지만, 렌더링 제외와 충돌 제외는 별도 설정입니다. "Invisible" layer라는 이름만으로 물리·query까지 제외되는 것은 아닙니다. 팀 규칙에는 layer 이름, collision pair, query에서 허용할 layer, trigger 정책을 함께 기록합니다.
실패를 찾는 순서
| 증상 | 확인 순서 | 원인 |
|---|---|---|
| 투사체가 발사자에게 맞음 | 양쪽 Layer → Collision Matrix → Physics.IgnoreCollision 사용 여부 | pair 규칙이 열려 있거나 runtime 예외 처리가 빠졌습니다. |
| ray가 투명 trigger를 먼저 맞음 | QueryTriggerInteraction → Physics.queriesHitTriggers | trigger 포함 정책을 호출에 쓰지 않았습니다. |
| enemy만 찾고 싶은데 다른 객체를 맞음 | target의 Layer → mask bit → max distance | tag만 확인하고 query 필터는 열어 뒀습니다. |
| 코드 mask가 Inspector와 다름 | layer index와 1 << index | index를 mask 자리에 넘겼습니다. |
| 카메라에는 안 보이는데 ray가 맞음 | Camera Culling Mask와 LayerMask를 분리 | 렌더링 설정을 query 설정으로 오해했습니다. |
Layer는 32개뿐인 전역 계약입니다. 기능마다 임시 layer를 만들기보다, 물리 pair와 query 목적이 정말 다른 경우에만 분리합니다. 이름·Matrix·코드 mask를 함께 바꾸지 않으면 씬마다 재현이 다른 물리 버그가 생깁니다.
참고 링크
3 sources