[Unity] Layer
https://docs.unity3d.com/kr/560/Manual/Layers.html
레이어 - Unity 매뉴얼
레이어(Layers) 는 카메라 가 씬의 일부만 렌더링하고 광원 이 씬의 일부만 비추기 위해 가장 많이 사용됩니다. 그 외에도 콜라이더를 선별적으로 무시하거나 충돌을 생성하기 위해 레이캐스팅에
docs.unity3d.com
Unity의 Layer는 게임 오브젝트를 그룹화하여 특정 작업이나 연산에 대해 선택적으로 처리할 수 있도록 하는 기능이다.
Layer는 보통 물리 연산, 카메라 렌더링, 레이캐스트, 컬링(culling) 등의 작업에서 활용된다.
기본개념
Unity의 Layer는 게임 오브젝트를 논리적으로 그룹화하는 시스템이다. Tag와 마찬가지로, 각 게임 오브젝트는 하나의 Layer에 할당될 수 있다. Unity 프로젝트를 생성하면, 다음과 같이 기본적으로 몇 가지 Layer를 제공하고 있는 것을 볼 수 있다.
- Default: 모든 오브젝트의 기본 Layer.
- TransparentFX: 반투명한 효과를 가진 오브젝트를 위해 사용.
- Ignore Raycast: 레이캐스트에 의해 무시될 오브젝트.
- Water: 물 표면을 표현하는 오브젝트.
- UI: 사용자 인터페이스(UI) 요소.
활용
Layer는 다양한 작업에 사용될 수 있다. 주요 활용 방법을 보면 다음과 같다.
1. 물리연산 (Physics) - 충돌 마스크 (Collision Mask)
- Unity의 물리 시스템에서 Layer는 충돌 여부를 설정하는 데 사용된다.
- Physics Settings > Layer Collision Matrix에서 두 Layer 간의 충돌 여부를 설정할 수 있다.
- 이때, 특정 Layer를 충돌 처리에서 제외하거나 포함시킬 수 있다.
// 특정 Layer간 충돌 여부 설정
using UnityEngine;
public class CollisionLayerExample : MonoBehaviour
{
void Start()
{
// Player와 Enemy Layer 간 충돌 여부 비활성화
Physics.IgnoreLayerCollision(LayerMask.NameToLayer("Player"), LayerMask.NameToLayer("Enemy"), true);
Debug.Log("Player와 Enemy Layer 간 충돌이 비활성화되었습니다.");
}
}
2. 레이스트 (Raycast)
- 레이케스트를 사용할 때, 특정 Layer만 대상으로 설정할 수 있다.
// 레이캐스트에서 특정 Layer만 타겟으로 하는 예시
using UnityEngine;
public class RaycastLayerExample : MonoBehaviour
{
void Update()
{
// 카메라의 중심에서 앞으로 레이 발사
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
// Enemy Layer만 대상으로 레이캐스트
int layerMask = 1 << LayerMask.NameToLayer("Enemy");
if (Physics.Raycast(ray, out hit, 100f, layerMask))
{
Debug.Log($"Hit: {hit.collider.name}");
}
}
}
3. 카메라 렌더링 (Camera Rendering)
- 카메라의 Culling Mask를 설정하여 특정 Layer만 렌더링하거나 제외할 수 있다.
- 즉, 카메라가 렌더링하지 않아야 할(보이지 않아야 할) 오브젝트는 해당 Layer를 Culling Mask에서 제외하여 처리할 수 있다.
// 카메라가 특정 Layer만 렌더링하도록 설정
using UnityEngine;
public class CameraCullingExample : MonoBehaviour
{
public Camera mainCamera;
void Start()
{
// Player와 Enemy Layer만 카메라에서 렌더링
int layerMask = (1 << LayerMask.NameToLayer("Player")) | (1 << LayerMask.NameToLayer("Enemy"));
mainCamera.cullingMask = layerMask;
Debug.Log("카메라가 Player와 Enemy Layer만 렌더링하도록 설정되었습니다.");
}
}
4. 퍼포먼스 최적화
- Culling: 보이지 않는 오브젝트를 렌더링하지 않도록 설정하여 성능을 최적화하는 방법
- 보통, LOD (Level of Detail)와 함께 사용하여 특정 Layer를 동적으로 처리한다.
using UnityEngine;
public class LayerPerformanceExample : MonoBehaviour
{
void OnBecameVisible()
{
// 오브젝트가 카메라에 보이게 되었을 때
gameObject.layer = LayerMask.NameToLayer("Visible");
Debug.Log($"{gameObject.name} is now Visible.");
}
void OnBecameInvisible()
{
// 오브젝트가 카메라에 보이지 않을 때
gameObject.layer = LayerMask.NameToLayer("Invisible");
Debug.Log($"{gameObject.name} is now Invisible.");
}
}
// LayerMask를 이용한 다양한 Layer 설정 방법
using UnityEngine;
public class MultiLayerMaskExample : MonoBehaviour
{
void Start()
{
// Player, Enemy, Obstacle Layer를 결합
int layerMask = (1 << LayerMask.NameToLayer("Player")) |
(1 << LayerMask.NameToLayer("Enemy")) |
(1 << LayerMask.NameToLayer("Obstacle"));
Debug.Log($"LayerMask 설정 완료: {layerMask}");
}
}
응용하면, 비트 연산자를 통해 여러 Layer를 결합하고, 이렇게 만든 LayerMask를 레이캐스트, 충돌 연산 등에 재사용하여 레이어가 지나치게 많아지는 것도 방지할 수 있다.
Custom Layer
Tag와 마찬가지로, 기본적으로 제공되는 Layer 이외에도 사용자 지정 Layer 생성이 가능하다.
Layer 생성
- 상단 메뉴바에서 Edit > Project Settings > Tags and Layers로 이동.
- Inspector의 Layers 섹션에서 빈 슬롯을 클릭하고 새로운 Layer 이름을 입력
Layer 할당
- Inspector에서 오브젝트를 선택하고 Layer 드롭다운 메뉴에서 원하는 Layer를 선택.
LayerMask
LayerMask는 여러 Layer를 비트마스크로 표현한 값으로, 이를 통해 복수의 Layer를 한 번에 처리할 수 있다.
- LayerMask 설정
- 비트 연산을 활용하여 여러 Layer를 조합할 수 있다.
int layerMask = (1 << LayerMask.NameToLayer("Player")) | (1 << LayerMask.NameToLayer("Enemy"));
Layer 마스크를 활용하여 레이캐스트 충돌을 다음과 같이 확인할 수 있다.
if (Physics.Raycast(ray, out hit, maxDistance, layerMask))
{
Debug.Log("레이캐스트가 충돌했습니다!");
}
Layer와 Tag는 분명 비슷한 점이 많다. 하지만 분명한 차이가 존재한다.
- Layer는 주로 물리 연산, 렌더링, 레이캐스트 등의 기술적 처리에 사용.
- Tag는 게임 오브젝트를 식별하기 위한 논리적 구분으로 사용.
Layer는 게임의 렌더링, 물리, 로직에서 중요한 역할을 한다. 또한 필요에 따라 Custom Layer를 적절히 활용하여 더 정교한 제어도 가능하다.