Unity / C#
Beginner
Unity 2021.3+ / Unity 6
2D/3D 충돌 감지(Collision vs Trigger) 조건 매트릭스와 LayerMask 비트 연산
물리적 반발(Collision)과 통과 감지(Trigger)의 발동 조건 조합표, NonAlloc 레이캐스트를 통한 GC 방지, LayerMask 비트 시프트(1 << layer) 연산 테크닉.
#Unity #Physics #Collision #Trigger #LayerMask #Bitmask
핵심 개념벽에 부딪혀 튕겨 나가는 Collision과 아이템 획득·포탈 진입처럼 통과하면서 이벤트를 트리거하는 Trigger는 Rigidbody의 유무와
IsTrigger 설정에 따라 호출 여부가 완전히 달라집니다. 충돌 매트릭스를 정확히 숙지하고 LayerMask 비트 연산을 활용하면 물리 연산 부하를 80% 이상 줄일 수 있습니다.1. 충돌 이벤트 발생 조건표 (Collision vs Trigger)
| 오브젝트 A (충돌 주체) | 오브젝트 B (상대방) | OnCollision 발생 | OnTrigger 발생 |
|---|---|---|---|
| Rigidbody + Collider | Static Collider (Rigidbody 없음) | O (물리 반발 발생) | X |
| Rigidbody + Collider | Rigidbody + Collider | O (양방향 물리 반발) | X |
| Rigidbody + Trigger | Static Collider | X | O (A, B 모두 이벤트 수신) |
| Static Collider | Static Collider | X (절대 발생 안 함) | X (절대 발생 안 함) |
| Kinematic Rigidbody | Static Collider | X | X (움직여도 이벤트 없음) |
| Kinematic Rigidbody + Trigger | Rigidbody + Collider | X | O |
2. LayerMask 비트 연산 및 GC-Free NonAlloc 레이캐스트
using UnityEngine;
public class PhysicsUtility : MonoBehaviour
{
[SerializeField] private LayerMask targetLayers;
// 매 프레임 배열을 할당하지 않도록 정적 버퍼 사전 캐싱 (GC 0)
private static readonly RaycastHit2D[] HitBuffer = new RaycastHit2D[8];
// 특정 레이어 번호를 LayerMask 비트마스크로 변환
public static LayerMask LayerToMask(int layerIndex)
{
return 1 << layerIndex;
}
// 마스크에 특정 레이어가 포함되어 있는지 검사
public static bool ContainsLayer(LayerMask mask, int layerIndex)
{
return (mask.value & (1 << layerIndex)) != 0;
}
// 가비지 컬렉션 없는 2D 원형 감지
public int DetectEnemiesNonAlloc(Vector2 center, float radius, LayerMask enemyMask)
{
ContactFilter2D filter = new ContactFilter2D();
filter.SetLayerMask(enemyMask);
filter.useLayerMask = true;
filter.useTriggers = false;
// Physics2D.OverlapCircleNonAlloc (또는 CircleCastNonAlloc)
int hitCount = Physics2D.OverlapCircle(center, radius, filter, HitBuffer);
for (int i = 0; i < hitCount; i++)
{
Collider2D target = HitBuffer[i];
// 타겟 처리...
}
return hitCount;
}
}
3. 충돌 매트릭스(Physics Collision Matrix) 최적화 팁
- 불필요한 충돌 쌍 체크 해제:
Project Settings > Physics(2D)의 레이어 충돌 매트릭스에서Enemy와EnemyHitbox,Debris와Background등 서로 부딪힐 일 없는 레이어 간의 체크를 해제하면 광폭 물리 틱 낭비를 방지할 수 있습니다. RaycastAll금지:Physics.RaycastAll은 호출 시마다 새 배열을 힙에 할당합니다. 고성능 루프에서는 반드시Physics.RaycastNonAlloc을 사용해야 합니다.