Unity LayerMask란 무엇인가?
유니티에서 카메라 가림 처리, 레이캐스트, 충돌 검사 같은 기능을 구현하다 보면 자주 보게 되는 타입이 LayerMask다.
예를 들면 이런 코드다.
public LayerMask obstacleMask;
처음 보면 이런 의문이 생긴다.
- 이건 클래스인가 구조체인가?
- 그냥 Layer랑 뭐가 다른가?
- 왜 int가 아니라 LayerMask를 쓰는가?
- 레이캐스트에서 이 값은 정확히 어떤 역할을 하는가?
결론부터 말하면, LayerMask는 유니티에서 특정 레이어들만 골라서 검사하기 위해 사용하는 구조체(struct) 이다.
그리고 내부적으로는 비트마스크(bitmask) 개념을 사용한다.
즉, LayerMask는 오브젝트가 어느 레이어에 속하느냐를 나타내는 값이 아니라,
어떤 레이어들을 검사 대상으로 포함할 것인가를 나타내는 필터 값에 가깝다.
1. 먼저 Layer부터 이해하기
LayerMask를 이해하려면 먼저 Layer가 뭔지부터 알아야 한다.
유니티의 Layer는 오브젝트를 그룹으로 나누는 기능이다.
예를 들면 이런 식이다.
- Player
- Ground
- Enemy
- UI
- FadeObstacle
이렇게 레이어를 나눠두면, 나중에 코드나 물리 시스템에서
“이 그룹만 검사한다”, “이 그룹은 무시한다” 같은 처리를 할 수 있다.
중요한 점은 하나의 GameObject는 보통 하나의 Layer만 가진다는 것이다.
즉 어떤 벽이 있다면:
- 이 벽은 FadeObstacle 레이어
- 이 바닥은 Ground 레이어
- 이 플레이어는 Player 레이어
처럼 설정하는 방식이다.
2. Layer와 LayerMask의 차이
이 둘은 이름이 비슷해서 많이 헷갈린다.
Layer
오브젝트의 소속 그룹이다.
예:
- 이 벽은 FadeObstacle 레이어에 속한다.
LayerMask
검사할 레이어들의 집합이다.
예:
- 레이캐스트는 FadeObstacle 레이어만 검사한다.
- SphereCast는 Ground와 FadeObstacle 둘 다 검사한다.
즉 정리하면:
- Layer = 오브젝트의 그룹
- LayerMask = 어떤 그룹을 검사할지 정하는 필터
3. LayerMask는 클래스가 아니라 구조체다
LayerMask는 class가 아니라 struct 다.
왜냐하면 이 타입은 복잡한 참조형 오브젝트라기보다,
사실상 비트마스크 정수값 하나를 감싸는 값 타입에 가깝기 때문이다.
개념적으로는 이런 느낌으로 생각해도 된다.
struct LayerMask
{
int value;
}
실제로 유니티는 레이어를 숫자로 관리하고,
LayerMask는 그 숫자들을 비트 단위로 켜고 끄는 식으로 동작한다.
즉 LayerMask는 유니티 Inspector에서 보기 좋고, 코드에서도 쓰기 편한 레이어 필터용 구조체라고 이해하면 된다.
4. 왜 int가 아니라 LayerMask를 쓸까?
사실 레이어 마스크는 내부적으로 int에 가깝게 동작한다.
그렇다면 그냥 int를 써도 되지 않을까?
가능은 하다. 하지만 LayerMask를 쓰는 이유는 명확하다.
1) Inspector에서 훨씬 편하다
예를 들어 이런 코드가 있다고 해보자.
public int obstacleMask;
이렇게 하면 Inspector에서 그냥 숫자 하나로 보인다.
사람이 보기에도 의미가 불분명하고, 실수하기도 쉽다.
반면:
public LayerMask obstacleMask;
이렇게 쓰면 Inspector에서 레이어 이름이 체크박스 형태로 보인다.
예:
- Default
- Ground
- Player
- FadeObstacle
즉 개발자가 숫자를 기억하지 않아도,
이름으로 필요한 레이어를 선택할 수 있다.
2) 의도가 더 분명하다
int라고 쓰면 “이 숫자가 뭐지?”라는 생각이 들 수 있다.
하지만 LayerMask라고 쓰면 “아, 레이어 필터용 값이구나”가 바로 보인다.
즉 코드의 의미도 더 명확해진다.
5. 비트마스크(bitmask)란 무엇인가?
LayerMask를 이해할 때 핵심은 비트마스크 개념이다.
유니티의 각 레이어는 내부적으로 숫자 인덱스를 가진다.
예를 들어 아주 단순하게 보면:
- Layer 0
- Layer 1
- Layer 2
- Layer 3
이런 식이다.
그런데 LayerMask는 “레이어 하나”를 저장하는 게 아니라,
여러 레이어를 동시에 선택할 수 있어야 한다.
그래서 각 레이어를 비트 하나로 표현한다.
예를 들어:
- 0001 = Layer 0만 포함
- 0010 = Layer 1만 포함
- 0100 = Layer 2만 포함
- 0011 = Layer 0과 Layer 1 포함
이런 식이다.
즉 LayerMask는
“어떤 레이어들이 켜져 있는가”를 비트 조합으로 표현하는 값이라고 볼 수 있다.
이 구조 덕분에 유니티는 물리 검사에서 매우 빠르게
이 오브젝트의 레이어가 검사 대상인가?를 판별할 수 있다.
6. 실제 코드에서 LayerMask는 어떻게 쓰일까?
가장 흔한 예시는 레이캐스트나 스피어캐스트다.
public LayerMask obstacleMask;
RaycastHit[] hits = Physics.SphereCastAll(
start,
sphereRadius,
direction.normalized,
distance,
obstacleMask,
QueryTriggerInteraction.Ignore
);
여기서 obstacleMask의 역할은 이렇다.
- SphereCastAll이 충돌체를 찾을 때
- 모든 오브젝트를 다 보는 것이 아니라
- obstacleMask에 포함된 레이어만 검사하게 만든다
예를 들어 씬에 이런 오브젝트들이 있다고 해보자.
- 플레이어: Player
- 바닥: Ground
- 높은 벽: FadeObstacle
- 장식물: Decoration
그리고 obstacleMask에 FadeObstacle만 선택해두면,
이 검사는 오직 FadeObstacle 레이어의 충돌체만 찾는다.
즉:
- 플레이어 무시
- 바닥 무시
- 장식물 무시
- 높은 벽만 감지
이렇게 원하는 것만 선별할 수 있다.
7. 왜 이런 필터링이 중요한가?
만약 LayerMask 없이 물리 검사를 하면,
씬에 있는 수많은 오브젝트를 전부 대상으로 삼게 된다.
그 결과:
- 필요 없는 오브젝트까지 충돌 판정에 걸리고
- 디버깅이 어려워지고
- 성능도 아쉬워지고
- 로직도 불안정해질 수 있다
예를 들어 카메라 가림 처리에서는
우리가 “플레이어를 가리는 큰 벽”만 찾고 싶은데,
바닥이나 장식물까지 전부 맞아버리면 엉뚱한 오브젝트가 투명해질 수 있다.
즉 LayerMask는 단순 편의 기능이 아니라,
로직의 정확도와 성능을 동시에 지키는 필터링 도구다.
8. LayerMask는 어떻게 만들고 사용할까?
방법 1: Inspector에서 직접 선택
가장 많이 쓰는 방식이다.
public LayerMask obstacleMask;
이렇게 선언하면 Inspector에서 체크박스로 고를 수 있다.
예:
- FadeObstacle 체크
- Ground 체크 해제
- Player 체크 해제
이 방식은 가장 직관적이고 편하다.
방법 2: 코드에서 만들기
코드에서 직접 레이어 마스크를 만들 수도 있다.
int mask = LayerMask.GetMask("FadeObstacle");
혹은 여러 레이어를 한 번에:
int mask = LayerMask.GetMask("FadeObstacle", "Ground");
이렇게 하면 이름으로 마스크 값을 생성할 수 있다.
동적으로 마스크를 구성해야 하는 경우 유용하다.
9. LayerMask와 헷갈리기 쉬운 것들
Tag와 다르다
Tag는 주로 “이 오브젝트의 역할이나 정체성”을 구분할 때 쓴다.
예:
- Player
- Enemy
- Item
반면 Layer는 보통:
- 물리 검사 필터링
- 카메라 가림 처리
- 충돌 매트릭스같은 시스템 레벨 분류에 더 자주 사용된다.
즉:
- Tag = 정체성
- Layer = 시스템용 그룹
이라고 생각하면 편하다.
Sorting Layer와도 다르다
2D 렌더링에서 보이는 Sorting Layer는 그리기 순서를 조절하는 용도다.
LayerMask와는 관계가 없다.
10. 초보자 관점에서의 핵심 정리
유니티를 처음 쓰는 사람이라면, LayerMask를 이렇게 이해하면 된다.
- 오브젝트는 각각 어떤 레이어에 속해 있다
- 물리 검사나 레이캐스트는 그중 일부만 보고 싶을 때가 많다
- 그 일부를 고르는 필터가 LayerMask다
11. 코드를 읽는 사람 관점에서의 핵심 정리
코드를 읽는 입장에서는 LayerMask를 이렇게 이해하면 된다.
- LayerMask는 struct
- 내부적으로는 비트마스크 정수값
- 물리 쿼리 API에서 레이어 필터 인자로 사용
- Inspector 친화적인 타입
- Layer는 단일 그룹, LayerMask는 그룹 집합
즉 C# 문법 수준에서 보면
LayerMask는 비트마스크 정수에 의미와 편의성을 붙여놓은 유니티 전용 값 타입이라고 볼 수 있다.
12. 실제 프로젝트에서 왜 자주 쓰이는가
LayerMask는 카메라, 이동, 점프, 공격 판정, 상호작용 등 거의 모든 시스템에서 자주 등장한다.
예를 들어:
- 바닥 체크
- 카메라 오클루전 처리
- 총알 히트 판정
- 상호작용 가능한 오브젝트 탐색
- 적 감지 범위 검사
이런 기능들은 공통적으로
씬에 있는 모든 오브젝트를 검사하면 안 되고, 특정 그룹만 골라야 한다.
그래서 LayerMask는 유니티에서 정말 자주 쓰이는 기본 개념이다.
마무리
LayerMask는 처음 보면 단순히 레이어 선택용 변수처럼 보일 수 있다.
하지만 실제로는 유니티에서 물리 검사와 시야 판정, 충돌 필터링을 설계할 때 핵심이 되는 도구다.
정리하면 이렇다.
- Layer는 오브젝트의 소속 그룹
- LayerMask는 검사 대상이 되는 레이어들의 집합
- LayerMask는 class가 아니라 struct
- 내부적으로는 비트마스크 기반으로 동작
- Inspector에서 이름으로 선택할 수 있어 편리하고 명확하다
즉 LayerMask는 단순한 옵션이 아니라,
무엇을 검사하고 무엇을 무시할 것인가를 설계하는 유니티의 기본 장치라고 볼 수 있다.
'Unity - '한 우산 아래'' 카테고리의 다른 글
| 맵툴 제작기 1 - Unity Editor에서 쿼터뷰 퍼즐 게임용 Map Tool 만들기 (0) | 2026.04.08 |
|---|---|
| [한 우산 아래] 캐릭터를 가리는 벽 처리 - Layer 분리와 Material 기반 Occlusion Fade 구현 (0) | 2026.04.01 |
| C#의 foreach와 var를 C++과 비교해보기 (0) | 2026.04.01 |
| Unity - Dictionary (0) | 2026.04.01 |
| Unity-HashSet (0) | 2026.04.01 |