"깊이"가 다른 게임개발자 허민영

유저에서 게임까지, 철학에서 코딩까지, 본질을 보는 게임개발

소프트웨어 공학/코딩

Unity] LayerMask, Layer, 비트연산

허민영 2025. 2. 18. 20:37

Unity에서 LayerMask는 특정 레이어를 감지하거나 제외하는 기능을 제공하는 중요한 개념이다.
이는 충돌 감지(Collision Detection), Raycast 처리, AI 시스템 등에서 자주 사용되며,
불필요한 연산을 줄이고 게임의 성능을 최적화하는 데 큰 역할을 한다.

LayerMask를 올바르게 활용하려면 **비트 연산(Bitwise Operation)**을 이해하는 것이 중요하다.
이 글에서는 LayerMask의 기본 개념부터 비트 연산을 이용한 효율적인 레이어 필터링 방법,
그리고 Layer Collision Matrix를 활용한 최적화 방법까지 심층적으로 다뤄보겠다.

1. Layer와 LayerMask의 개념

Layer(레이어)란?

Unity에서는 **최대 32개의 레이어(0~31번까지)**를 사용할 수 있으며,
각 오브젝트는 하나의 레이어를 할당받아 특정 그룹으로 분류될 수 있다.
이를 통해 충돌 감지, 카메라 필터링, Raycast 처리 등에 활용할 수 있다.

예를 들어 다음과 같은 레이어가 있다고 가정하자.

 

레이어 번호                 레이어 이름

0 Default
1 TransparentFX
2 Ignore Raycast
3 Player
4 Enemy
5 Environment

 

LayerMask는 이러한 레이어들을 비트 마스크(Bit Mask) 형태로 저장하는 정수(int) 값으로,
여러 개의 레이어를 한 번에 선택하거나 제외하는 기능을 수행한다.

2. LayerMask의 활용 목적

LayerMask는 다음과 같은 경우에 주로 사용된다.

  1. Raycast가 특정 레이어에만 반응하도록 설정
    • 예: 총알이 "Enemy" 레이어에만 충돌하도록 설정
  2. 특정 레이어와의 충돌을 감지하거나 무시
    • 예: "Player"는 벽과 충돌하지만, "Ignore Raycast" 레이어는 무시하도록 설정
  3. NavMesh 및 AI 시스템에서 특정 레이어만 감지
    • 예: AI가 "Ground"만 걷도록 설정하고, "Obstacle"은 감지하지 않도록 필터링

3. LayerMask와 비트 연산

Unity의 LayerMask는 비트(Bit) 연산을 활용하여 특정 레이어를 감지하는 방식으로 동작한다.
특히, 다음과 같은 조건문을 활용하면 특정 레이어가 포함되었는지 확인할 수 있다.이 코드의 핵심 부분을 하나씩 분석해 보자.

if ((1 << other.gameObject.layer) & LayerMask.GetMask("Enemy") != 0)
{
    Debug.Log("적과 충돌 감지");
}
    • 비트 연산을 활용한 레이어 확인 방식

※ 1 << layerIndex의 동작 원리

1 << layerIndex는 특정 레이어를 비트 플래그(Bit Flag)로 변환하는 과정이다.
이는 2의 거듭제곱 형태로 값을 변환하여 특정 비트를 활성화하는 방식으로 동작한다.

다음과 같은 예제를 보자.

레이어 번호2진수 표현 (1 << layerIndex)
0 (Default) 00000000000000000000000000000001 (1)
1 (TransparentFX) 00000000000000000000000000000010 (2)
2 (Ignore Raycast) 00000000000000000000000000000100 (4)
3 (Player) 00000000000000000000000000001000 (8)
4 (Enemy) 00000000000000000000000000010000 (16)

 

즉, 1 << layerIndex는 해당 레이어의 비트 위치를 활성화하는 역할을 한다.

int enemyLayerMask = LayerMask.GetMask("Enemy"); // "Enemy" 레이어의 비트마스크 가져오기
int objectLayerMask = 1 << other.gameObject.layer; // 충돌한 오브젝트의 레이어를 비트마스크로 변환

 

  & LayerMask.GetMask("Enemy") 연산의 의미

&(비트 AND 연산자)를 활용하면 특정 레이어가 포함되었는지 확인할 수 있다.

if ((1 << other.gameObject.layer) & LayerMask.GetMask("Enemy") != 0)

 

위 코드는 다음과 같은 방식으로 동작한다.

  1. 1 << other.gameObject.layer → 충돌한 오브젝트의 레이어를 비트 형태로 변환
  2. LayerMask.GetMask("Enemy") → "Enemy" 레이어만 활성화된 비트마스크를 반환
  3. & 연산자로 두 값을 비교 → 해당 비트가 켜져 있으면 충돌 감지 성공
  4. 결과가 0이 아니면 (!= 0) 해당 레이어가 감지된 것임

즉, 해당 연산을 통해 오브젝트의 레이어가 "Enemy"인지 효율적으로 확인할 수 있다.

4. Layer Collision Matrix를 활용한 추가 최적화

LayerMask를 활용하는 것도 중요하지만, Unity의 "Layer Collision Matrix"를 활용하면 더욱 강력한 최적화가 가능하다.

 1) Layer Collision Matrix란?

Unity의 **Physics Settings (Edit > Project Settings > Physics)**에서 설정할 수 있는 충돌 필터링 시스템이다.
이를 통해 불필요한 충돌 검사를 원천적으로 차단할 수 있다.

 2) Layer Collision Matrix 설정 방법

  1. Unity에서 "Edit > Project Settings > Physics"를 연다.
  2. "Layer Collision Matrix"를 확인한다.
  3. 충돌이 필요 없는 레이어의 체크박스를 비활성화한다.

예를 들어, 다음과 같이 설정한다고 가정하자.

레이어 Player Enemy Environment Ignore Raycast
Player O O O X
Enemy O X O X
Environment O O O X
Ignore Raycast X X X X

 

위 설정에 따르면:

  • Player는 Enemy, Environment와 충돌 가능하지만 Ignore Raycast는 무시된다.
  • Enemy는 Player와 충돌 가능하지만 다른 적과는 충돌하지 않는다.

 3) Layer Collision Matrix를 활용한 최적화

LayerMask 없이도 Layer Collision Matrix 설정만으로 충돌 검사 횟수를 줄일 수 있다.
즉, Physics.Raycast에서 LayerMask를 사용하지 않아도 불필요한 충돌 검사가 실행되지 않도록 설정할 수 있다.