Unity) LayerMask
LayerMask 란
오브젝트를 Layer 별로 묶어놓고, 특정 묶음끼리만 부딪히게 하거나 통과할 수 있도록 하는 기능입니다.
- LayerMask같은 경우는 32개의 칸, bitMask로 작동한다.
그렇다보니 기본적으로 성능 좋다.
1. Tag 와 Layer 의 차이
==Tag== : 단순한 인식표
==Layer== : 오브젝트들의 그룹을 만들고 관리하는 용
태그 | 레이어 | |
|---|---|---|
언제 판단하나 | 부딪히거나 맞은 뒤에 | 부딪히거나 맞기 전에 |
누가 판단하나 | 내가 쓴 코드 | 엔진 |
무엇을 지정하나 | 오브젝트 하나 | 묶음 전체 |
2. Layer
- Layer Collision Matrix ( Edit > Project Settings > Physics )

체크가 되어있는 레이어끼리만 충돌한다.
2-1) 레이어 번호와 마스크의 차이
레이어 번호와 레이어 마스크는 서로 다른 값입니다.
레이어 번호 : 그 레이어가 32칸 중 몇번째 칸인지를 나타내는 값
레이어 마스크 : 32칸 각각을 쓸지 말지 표시한 값
| 정수 | 켜진 자리 | 가리키는 레이어 |
|---|---|---|
1 | 0번 | Default |
2 | 1번 | TransparentFX |
4 | 2번 | Ignore Raycast |
8 | 3번 | 3번 레이어 |
9 | 0번과 3번 | Default와 3번 레이어 |
정수 9를 자리로 펼치면 ==00001001== 이고, 1이 켜져있는 값은 0,3번 자리이기 때문입니다.
비트 연산자를 통해 켜는법
왼쪽 시프트 연산자인 ==<<== 를 사용하여 마스크 위치를 가르킵니다.
int mask = 1 << 8;
위 코드를 보면 0번자리의 1 을 ++8칸 왼쪽++으로 밀어 8번 자리 하나만 켜진 값 이 됩니다.
이로써, ==1 << N== 이 곧 N번 레이어 하나짜리 마스크 라는 뜻이 됩니다.
int mask = (1 << 8) | (1 << 9);
비트 OR 연산자 ==|== 를 사용하여 8번,9번자리 모두 켜진 마스크를 지정할 수도 있습니다.
※ 비트 OR 연산자 ==|== 와 참,거짓을 보는 ==||== 는 다른 연산자이므로, 주의합니다.
2-2) NameToLayer, GetMask
레이어의 자리를 이름으로 얻는 방법입니다.
Debug.Log(LayerMask.NameToLayer("Enemy")); // 출력 : 8 / 몇번째 칸에 있는가
Debug.Log(LayerMask.GetMask("Enemy")); // 출력 : 256 / 해당 칸을 int로 변환한 값 (1 << 8)
하지만, 굳이 LayerMask를 문자열로 쓰진 않는다.
2-3) Inspector 창에서 Layer 노출
스크립트에서 public 또는 [SerializeField] 로 Inspector 창에 노출시키게 되면 이렇게 뜬다.
위와 같이 다중선택도 가능하다.
2-4) Raycast의 레이어 필터
==Physics.Raycast(ray, out RaycastHit hit, 거리제한, 레이어 마스크 )==
매개변수 넷째 자리가 마스크이며,
광선을 쏠 때 콜라이더를 선택적으로 무시하는데 쓰는 레이어 마스크 라고 공식문서에서 밝히고 있습니다.
거리를 제한하고 싶지 않다면 거리 자리에 무한대를 넣습니다. -> ==Mathf.Infinity==
TargetLayer와 동일한 Layer를 가지고 있는 객체만 Raycast에 반응하도록 하는 코드
public LayerMask TargetLayer;
[SerializeField] private int _rayDistance;
private void Update()
{
ShotRay();
}
private void ShotRay()
{
Ray ray = new Ray(transform.position, transform.forward);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, _rayDistance, TargetLayer))
{
Debug.Log(hit.transform.name);
}
}
Physics.Raycast(ray, out hit, _rayDistance, TargetLayer)
-> Raycast에 검출된 객체의 Layer가 TargetLayer와 동일한가
- 내가 찾고자 하는 레이어를 찾을 때 는 AND연산자 ==&를,
==해당 레이어가 존재하는지 알고자 할 때는 OR 연산자==|== 를 사용한다.
private void OnTriggerEnter(Collider other)
{
int layer = (1 << other.gameObject.layer);
if ((TargetLayer.value & layer) != 0)
{
Debug.Log("찾음");
}
}

