레이어는 유니티에서 게임 오브젝트들을 구분하거나 분류하기 위해 사용합니다.
오브젝트에 레이어를 지정하여 카메라, Raycast, 충돌 감지 등을 특정 레이어만 작동하게 할 수 있습니다. 흔히 태그랑 비슷한 기능이라고 보시면 됩니다!
그럼 기능은 둘다 비슷한데 Tag와 Layer는 왜 나누어져 있는지 궁금하실겁니다.
Tag의 경우 단순히 오브젝트의 정체나 역할을 확인하는 용도로 사용합니다.
예로 이 오브젝트는 플레이어인가 적인가 판별할 때 사용하는거죠.
Layer의 경우 비트 연산자를 사용하기 때문에 성능적인 측면이 필요한 경우에 사용합니다.
그래서 충돌, 카메라, Raycast 같이 물리/렌더링 관련 처리에 사용합니다.
레이어 마스크는 특정 레이어에 속한 오브젝트들만 선택하거나 감지하도록 필터링하는 기능입니다.
쉽게 말하면 지정한 레이어가 있을 거잖아요?
지정한 여러 레이어를 비트 연산 방식으로 묶어서 사용할 수 있게 하는 함수입니다.
유니티의 Layer는 내부적으로 32개(0~31)의 레이어로 이루어져 있고
CPU가 비트 연산을 매우 빠르게 처리하기 때문에 비트 연산을 사용합니다.
✅ 1 << n
: n번 레이어의 1 생성
✅ | (OR)
: 이진법의 동일한 자리가 하나만 1이어도 1로 치환
✅ & (AND)
: 이진법의 동일한 자리가 둘 다 1이라면 1로 치환
int playerMask = 1 << LayerMask.NameToLayer("Player");
만약 6번 레이어면 1을 좌측으로 6칸 이동, 즉 일곱번째 레이어입니다.
→ 1 << 6 → 0000 0000 0100 0000 (64)
int mask = (1 << LayerMask.NameToLayer("Enemy"))
| (1 << LayerMask.NameToLayer("Obstacle"));
Enemy = 8, Obstacle = 9 라면:
1 << 8 → 0001 0000 0000
1 << 9 → 0010 0000 0000
OR 연산 → 0011 0000 0000 → 8번, 9번 레이어 둘 다 포함시킵니다.
if ((mask & (1 << 8)) != 0)
mask → 0000 0000 0011 0000 0000 (768)
8 → 0000 0000 0001 0000 0000 (256)
= 0000 0000 0001 0000 0000 (256)
0이 아니므로 8번 레이어는 Enemy 레이어에 포함합니다.
if ((mask & (1 << 10)) != 0)
mask → 0000 0000 0011 0000 0000 (768)
10 → 0000 0000 0100 0000 0000 (1024)
= 0000 0000 0000 0000 0000 (0)
0 이므로 10번 레이어는 Enemy 레이어에 포함되지 않습니다.