레이어 마스크 GetMask vs NameToLayer

레이어 마스크 관련해서는 프로젝트 초기에나 작업하기 때문에 가끔씩 상기시키지 않으면 헷갈리기 쉽다.

 

LayerMask 구조체

유니티에 내장되어 있는 LayerMask 구조체는 내부를 뜯어보면

int 형을 감싸고 있는 래퍼 클래스일 뿐이다.

마스크는 int형에 비트연산을 사용하기 때문에 여러 레이어를 동시에 사용하려면 비트연산을 통해 구해야 한다.

 

레이어 마스크 구하기

public static int GetMask(params string[] layerNames)

LayerMask.GetMask 함수를 통해서 마스크를 구할 수 있다.

앞서 말했듯 기본적으로 비크 마스크 연산이기 때문에 int mask = (1 << 8) | (1 << 9); 등으로도 구할 수 있다.

인자는 params로 선언되어 있으니, 여러 개를 입력하면 OR 연산으로 구한다는 사실도 알 수 있다. 

LayerMask mask = LayerMask.GetMask("Monster") | LayerMask.GetMask("Wall");
LayerMask mask = LayerMask.GetMask("Monster", "Wall");

 

그럼 NameToLayer는 무엇인가?

NameToLayer(string) : 레이어의 '인덱스'를 반환한다.

GetMask(param string[]) : 레이어(들)의 '마스크'를 반환한다.

 

때문에, NameToLayer는 비트 연산을 한번 해줘야 마스크를 반환한다.

LayerMask laymask = LayerMask.GetMask("Interactable");
LayerMask laymask = 1 << LayerMask.NameToLayer("Interactable");

GetMask는 내부에서 NameToLayer를 호출한다.

 

필드 초기화하기

또 하나 중요한 건 MonoBehaviour의 필드 초기화로 NameToLayer를 사용할 수 없다.

(내부적으로 NameToLayer를 호출하는 GetMask도 동일하다)

 

필드 초기화로 NameToLayer를 사용한다면 다음과 같은 오류가 발생한다.

NameToLayer is not allowed to be called from a MonoBehaviour constructor

 

Mono를 상속받지 않은 C# 클래스에서는 호출 가능하니 static 클래스에서 선언하면 된다.

public static class LayerMasks
{
    public static LayerMask myMask = LayerMask.GetMask("myMask");
}

 

 

댓글

Designed by JB FACTORY