Unity 공부 (10)

도토코·2025년 3월 4일

Unity공부

목록 보기
10/22

LayerMask

Unity에서 특정 레이어를 선택하거나 필터링할 때 사용되는 데이터 타입. 주로 Raycast, Physics 연산, 충돌 감지 등에서 특정 레이어에 속한 오브젝트만 감지하거나 무시할 때 활용

  • Raycast에서 특정 레이어만 감지
  • 충돌 시스템에서 특정 레이어끼리만 충돌하도록 설정
  • 물리 연산을 최적화하여 불필요한 연산 줄이기

LayerMask의 기본 개념

Unity에서 Layer는 32비트 정수 값(0~31)으로 표현된다.
각 비트는 특정 Layer를 의미하고, 여러개의 Layer를 조합하여 사용할 수 있다.

  • 따라서 Layer Mask는 32개만 만들 수 있다.

  • 오브젝트에게 해당 layer를 붙히면 그 Layer에 해당하는 오브젝트들만을 대상으로 Raycasting을 할 수 있고 카메라 오브젝트에 Culling Mask로 어떤 Layer Mask를 지정하면 그 Layer를 가진 오브젝트만에 카메라에 랜더링된다.

  • Layer Mask를 사용하면 부하를 줄일 수 있다.

    • Raycasting은 부하가 많은 연산인데 안그래도 많은 오브젝트들이 Raycast에 충돌 된다면 성능이 떨어진다.
      • 그래서 와이어가 복잡하게 이루어져 있는 Mesh 의 경우, Mesh 를 바탕으로 Collider를 따는 Mesh Collider를 콜라이더로 사용하면 연산이 어마어마하게 소요 될 것이다.
        • 이처럼 좀 세밀하게 Mesh 모양 그대로를 충돌 처리를 받아야 하는 경우엔 Mesh Collider를 쓰기도 하지만 충돌 전용 Mesh를 따로 만들기도 한다.

활용 예시

위아 같이 8번과 9번에 각각 Monster와 Wall이라는 Layer를 만들어 놓았다.

  • Monster Layer는 0000000000000000000000010000000 -> (1<<8)
  • Wall Layer는 0000000000000000000000100000000 -> (1<<9)
    int mask = (1 << 8); // 8 번 레이어 

    RaycastHit hit;
    if (Physics.Raycast(ray, out hit, 100.0f, mask))
        {
            Debug.Log(hit.collider.gameObject.name);
        }
  • 8번 Layer를 가진 오브젝트들만 Raycasting이 진행된다.
  • (1<<8)은 십진수로 256이기에 int mask = 256;도 가능하다.
    int mask = (1 << 8) | (1 << 9); // 8 번 레이어 + 9 번 레이어

    RaycastHit hit;
    if (Physics.Raycast(ray, out hit, 100.0f, mask))
        {
            Debug.Log(hit.collider.gameObject.name);
        }
  • (1 << 8) | (1 << 9) -> 0000000000000000000000110000000
    • 8번 Layer와 8번 Layer를 가진 오브젝트들만 Raycasting이 진행된다.
    • (1<<8)을은 십진수로 768 int mask = 768;도 가능하다.
    LayerMask mask = LayerMask.GetMask("Monster") | LayerMask.GetMask("Wall")/
    // int mask = (1 << 8) | (1 << 9); 와 동일

    RaycastHit hit;
    if (Physics.Raycast(ray, out hit, 100.0f, mask))
        {
            Debug.Log(hit1.collider.gameObject.name);
        }
  • LayerMask.GetMask(String)
    • 해당 문자열로 저장된 LayerMask 즉, 해단 Layer의 int 크기의 비트를 가져오게 된다.
    • dl 함수를 사용해 레이어 이름으로 지정한 문자열로 비트를 가져올 수 있다.

Tag

큰 기능은 없고 오브젝트들을 그룹지어 구분해주기 위한 정보

GameObject.FindGameObjectWithTag("Monster");
Debug.Log(hit.collider.gameObject.tag);

위와 같이 코드를 작성하면 게임 오브젝트의 태그를 찾아낼 수 있게 된다.

  • 적(Enemy), 아이템(Item), 플레이어(Player) 등 개별 오브젝트 구별
  • 오브젝트를 찾거나 특정한 행동을 할 때 사용

LayerMask와 Tag를 같이 사용

🚀 가능! 서로 다른 역할을 하므로 같이 쓰면 더 효과적!

예제: 특정 태그(Enemy)를 가진 오브젝트 중 특정 레이어(Ground 또는 Water)만 감지

LayerMask mask = LayerMask.GetMask("Ground", "Water");
if ((mask.value & (1 << other.gameObject.layer)) != 0 && other.CompareTag("Enemy"))
{
    Debug.Log("Ground 또는 Water 위에 있는 적 감지!");
}

LayerMask vs Tag 차이점

LayerMaskTag
용도충돌, 물리 연산, 레이캐스트 등의 레이어 필터링특정한 오브젝트를 식별
데이터 타입LayerMask (비트 연산 사용)string (문자열)
설정 방식0~31까지 총 32개의 레이어 슬롯 제공여러 개의 태그 생성 가능 (오브젝트마다 1개만 설정 가능)
주요 기능1. 특정 오브젝트 그룹에 대한 충돌 감지 2. 특정 레이어만 Raycast 감지1. 개별 오브젝트의 역할을 구분하는 용도
인스펙터에서 설정✅ 가능 (드롭다운 선택)✅ 가능 (드롭다운 선택)
코드 예제c#
if ((groundLayer.value & (1 << other.gameObject.layer)) != 0)
{ Debug.Log("Ground 레이어 오브젝트!"); }
c#
if (other.CompareTag("Enemy"))
{ Debug.Log("적을 감지!"); }
여러 개 동시 설정 가능?✅ 가능 (비트 연산으로 다중 선택)❌ 불가능 (오브젝트당 하나의 태그만 가능)
profile
코(딩)(꿈)나무

0개의 댓글