
게임 오브젝트를 그룹으로 나누어서 처리하고 싶을 때 사용한다. 물리 처리에서 유용하다
Layer Mask태그. 특정 그룹들 간의 처리를 한다면 레이어



Culling Mask에서 표시할 레이어들만 선택할 수 있다. 여기서 큐브, 스피어만 체크하고 실린더는 체크 해제 해본다
// 0, 어떤 레이어도 선택되지 않음
// 00000000000000000000000000000000
private int _layerMask = 0;
// 1을 좌측으로 0칸 이동, 즉 첫번째 레이어
// 00000000000000000000000000000001
private int _layerMask = (1 << 0);
// 1을 좌측으로 4칸 이동, 즉 다섯번째 레이어
// 00000000000000000000000000010000
private int _layerMask = (1 << 4);
bool타입 배열처럼 사용하는 것이다.| 기호 | 의미 | 설명 |
|---|---|---|
| & | AND | 이진법의 동일한 자리가 둘 다 1이라면 1로 치환 |
| | | OR | 이진법의 동일한 자리가 하나만 1이어도 1로 치환 |
| ~ | NOT | 0과 1을 반전시킨다 |
AND
...1010 0010
AND ...0010 0100
---------------
=> ...0010 0000
OR
...1000 0000
OR ...0000 1000
---------------
=> ...1000 1000
NOT
...0101 0010
NOT => ...1010 1101
LayerMask는 struct 구조체다. 그래서 LayerMask 타입의 변수 값을 변경하려면 함수에서 ref 키워드를 써야 한다public static class LayerUtil
{
// LayerMask는 구조체이기 때문에, 값을 변경하려면 ref 타입으로 해야 된다
public static void AddLayer(ref LayerMask target, params string[] name)
{
// params parameter로 이름을 배열로 받아 여러이름을 추가할 수 있다
foreach(string n in name)
{
target |= 1 << LayerMask.NameToLayer(n);
}
}
public static void RemoveLayer(ref LayerMask target, string name)
{
target &= ~(1 << LayerMask.NameToLayer(name));
// name이 8번 레이어 일 경우, 8번만 제외된다
}
}
public class CameraRaycaster : MonoBehaviour
{
private Camera _cam;
[Header("Set Raycast Config")]
[SerializeField][Range(0, 100)] private float _rayDistance = 100;
[SerializeField] private KeyCode _actionKey = KeyCode.Mouse0;
[SerializeField] private LayerMask _targetLayer = 0;
private void Awake() => Init();
private void Update() => RayShoot();
private void Init()
{
_cam = Camera.main;
// LayerUtil.AddLayer(ref _targetLayer, "Player", "Monster");
LayerUtil.RemoveLayer(ref _targetLayer, "Item");
}
private void RayShoot()
{
if(!Input.GetKeyDown(_actionKey)) return;
Ray ray = _cam.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if(Physics.Raycast(ray, out hit, _rayDistance, _targetLayer))
{
// 0000 0000 _ 0000 0000 _ 0000 0000 _ 0000 0000
// EX> Monster (9 Layer) 를 클릭해서 '제외'한다고 가정.
// hitLayerNumber = 9
int hitLayerNumber = hit.transform.gameObject.layer;
// ...0000 0010 0000 0000
int hitLayer = (1 << hitLayerNumber);
// ...1111 1101 1111 1111
int notLayer = ~hitLayer;
// _cam.cullingMask = ...1111 1111 1111 1111
// not Layer = ...1111 1101 1111 1111
// And => ...1111 1101 1111 1111
_cam.cullingMask &= notLayer;
}
}
}
layer |= 1<<5;
layer |= (1<<3|1<<5|1<<6);
layer &= ~(1<<4);
layer &= ~(1<<3|1<<5|1<<6);
TIP
지금의LayerUtil과 같이 쓸만한 기능들은, 미리미리static class에 함수를 구현해서 쓰는 것을 추천한다. 코딩이 쉬워진다