Posted in: Unity, 메서드 & 팁 정리

Overlap | 일정 범위 충돌체를 감지

유니티의 Overlap 메서드는 특정 범위안에 있는 충돌체들을 감지하는데 사용합니다. 알아놓으면 매우 다양한 곳에서 활용 가능합니다.

3D 프로젝트의 경우 아래 메서드 사용


메서드설명
OverlapBox접촉한 모든 콜라이더나 내부의 박스(box)와 함께 배열을 반환합니다.
OverlapBoxNonAlloc접촉한 콜라이더의 개수를 반환합니다.
OverlapSphere접촉한 모든 콜라이더나 내부의 구체(sphere)와 함께 배열을 반환합니다.
OverlapSphereNonAlloc접촉한 콜라이더의 개수를 반환합니다.

2D 프로젝트의 경우 아래 메서드 사용


메서드설명
OverlapArea충돌체가 직사각형 영역 내에 있는지 확인합니다.
OverlapAreaAll직사각형 영역에 속하는 모든 충돌체 목록을 가져옵니다.
OverlapAreaNonAlloc지정된 영역에 속하는 모든 충돌체 개수를가져옵니다.
OverlapBox충돌체가 상자 영역 내에 있는지 확인합니다.
OverlapBoxAll상자 영역에 속하는 모든 충돌체 목록을 가져옵니다.
OverlapBoxNonAlloc상자 영역에 속하는 모든 충돌체 개수를가져옵니다.
OverlapCapsule충돌체가 캡슐 영역 내에 있는지 확인합니다.
OverlapCapsuleAll캡슐 영역에 속하는 모든 충돌체 목록을 가져옵니다.
OverlapCapsuleNonAlloc캡슐 영역에 속하는 모든 충돌체 개수를가져옵니다.
OverlapCircle충돌체가 원형 영역 내에 있는지 확인합니다.
OverlapCircleAll원형 영역에 속하는 모든 충돌체 목록을 가져옵니다.
OverlapCircleNonAlloc원형 영역에 속하는 모든 충돌체 개수를가져옵니다.
OverlapCollider주어진 콜 라이더와 겹치는 모든 콜 라이더 목록을 가져옵니다.
OverlapPoint충돌체가 공간의 한 지점과 겹치는 지 확인합니다.
OverlapPointAll공간의 한 지점과 겹치는 모든 충돌체의 목록을 가져옵니다.
OverlapPointNonAlloc공간의 한 지점과 겹치는 모든 충돌체의 개수를 가져옵니다.

각 링크를 따라가면 유니티에서 직접 서술한 내용을 볼 수 있습니다. 3D와 2D 모두 지원되고 엄청 다양한 모양을 지원합니다. 유니티 게임 엔진은 메서드의 다형성을 적극적으로 보장하기 때문에 로직의 상황에 따라 적절한 매개 변수 형식을 선택하여 사용하면 됩니다.

사용방법


특별히 다른 매개 변수를 가진 메서드도 있지만 보통 Overlap 시리즈는 매개 변수가 비슷합니다. 하나만 사용법을 알아놓고 각 상황에 맞추어 필요한 모양을 사용하면 됩니다. 물론 반환하는 데이터 타입을 잘 보고 사용하셔야 됩니다.

어쨌든 2D 게임에 많이 사용되는 OverlapBox를 간단하게 알아보겠습니다.

//Vector2 point, Vector2 size, float angle, int layerMask
Collider2D Physics2D.OverlapBox(point, size, angle);
Collider2D Physics2D.OverlapBox(point, size, angle, layerMask);

point는 OverlapBox가 시작되는 원점입니다. size는 OverlapBox의 범위입니다. angle은 OverlapBox 범위의 각도입니다. layerMask는 특정 레이어만 감지하는데 사용합니다.

물론 OverlapBox는 더욱 다양한 반환값과 매개변수를 지원합니다만 간단한 예제만 알아보겠습니다.

예제


해당 예제에서의 Player는 여우입니다. 여우의 Box모양 반경내에 체리가 있다면 감지하는 코드를 봅시다.

public Vector2 size;
public LayerMask whatIsLayer;

void Start()
{
    Collider2D hit = Physics2D.OverlapBox(transform.position, size, 0, whatIsLayer);
    Debug.Log(hit.name);
}

void OnDrawGizmos()
{
    Gizmos.color = Color.red;
    Gizmos.DrawWireCube(transform.position, size);
}

위 코드는 OverlapBox(Player의 위치, Vector2 사이즈, 각도는 0, 레이어 선택); 으로 해석할 수 있고 충돌체가 있다면 오브젝트의 이름을 콘솔에 출력하도록 되어있습니다. OnDrawGizmos()는 Scene 창에서 눈으로 확인하기 위함이니 너무 신경쓰지 마세요.

인스펙터에서 Vector2 size의 크기와 Layer 설정을 하였습니다. 보다싶이 콘솔창에 cherry가 출력되었죠.

당연히 size의 크기가 커져서 gem이 범위 내에 들어와도 매개변수의 Layer로 특정 레이어만 감지하기 때문에 gem은 감지되지 않습니다.

그렇다면 cherry와 gem이 같은 레이어(object)여서 같은 범위 내에 들어온다면 어떻게 될까요? 둘이 함께 출력될까요? 결과는 하나만 출력됩니다. 출력되는 기준은 모르겠지만 cherry만 출력 되더군요.

cherry와 gem 둘 다 감지하고 싶은데 방법은 없을까요? 있습니다. OverlapBoxAll 메서드를 사용하면 됩니다. 밑에서 코드를 확인해보세요.

public Vector2 size;
public LayerMask whatIsLayer;

void Start()
{
    Collider2D[] hit = Physics2D.OverlapBoxAll(transform.position, size, 0, whatIsLayer);
    
    for(int i = 0; i < hit.Length; ++i)
    {
        Debug.Log(hit[i].name);
    }
}

void OnDrawGizmos()
{
    Gizmos.color = Color.red;
    Gizmos.DrawWireCube(transform.position, size);
}

코드가 달라진게 보이나요? OverlapBoxAll 메서드는 Collider2D 배열을 반환합니다. 그래서 Collider2D 배열로 충돌 결과를 대입하죠.

그리고 충돌되는 오브젝트들의 이름을 출력하고 있습니다. cherry와 gem이 둘 다 출력되는지 확인해보죠.

cherry와 gem이 출력 되는군요. 여러 오브젝트를 감지하고 싶다면 OverlapBoxAll 메서드를 사용하면 되는군요!

이처럼 필요한 범위(모양)와 반환하는 데이터 타입을 보고 적절한 메서드를 사용하면 원하는 결과를 얻을 수 있을 것입니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 항목은 *(으)로 표시합니다