본문 바로가기
개발/Unity 내일배움캠프 TIL

Unity2D 레이캐스트 (Raycast)

by 석시 2023. 9. 12.



레이캐스트 (Raycast)

씬의 여러 위치에 분포해 있는 오브젝트를 얻어오는 방법 중 하나이다.

쉽게 말해 빔을 쏴서 그 빔을 맞는 오브젝트를 가져온다.

기능 자체는 단순하지만, 바리에이션이 살짝 많기 때문에 다룰 수 있는 함수들에 대해 알아보려 한다.


Ray

Raycast를 호출하면 Raycast를 위해 Ray라는 클래스의 객체가 생성이 된다.

위치와 방향 벡터를 매개변수로 넣던지, Ray를 생성하는 함수를 통해 직접 만들 수도 있다.

 
Ray ray;

// 1. 위치와 방향 벡터를 매개변수로 넣어 생성
ray = new Ray(transform.position, transform.forward);

// 2. 스크린 마우스 위치로 Ray 생성
ray = Camera.main.ScreenPointToRay(Input.mousePosition);

// 3. 카메라 뷰포트로부터 Ray 생성
ray = Camera.main.ViewportPointToRay(new Vector3 (0.5f, 0.5f, 0));


Raycast vs RaycastAll

Raycast는 Ray가 충돌했는지 아닌지를 bool값으로 반환해준다.

내가 하나의 Ray로 여러 객체를 얻어오고 싶다면 RaycastAll을 사용하면 된다.

RaycastHit라는 것을 반환하는데, 이는 충돌 객체에 대한 정보를 담고 있다.

여러 객체를 얻어와야 하기 때문에 RaycastAll의 반환타입은 RaycastHit[] 배열이다.

참고) RaycastAll의 단점

  1. 성능 저하

RaycastAllRay에 충돌하는 객체가 있을 때마다 배열을 새로 선언해서 return 해준다.

즉, 가비지가 엄청나게 발생한다!

이를 방지하기 위해 RaycastNonAlloc이라는 함수를 사용할 수도 있다.

고정된 배열 크기를 가지고 RaycastAll을 수행하는 방식이다.

  1. 순서 보장 X

Raycast의 개념이 뭔가 ray를 맞는 순서대로, 즉 출발점으로부터 거리 순으로 정렬된 Array가 반환될 것 같지만, 절대 그렇지 않다.

RaycastAll은 정의되지 않은 순서로 오브젝트를 검색한다. 따라서 반환되는 요소의 순서를 내가 예측할 수 없다.

따라서 뭔가 거리에 따라 정렬된 오브젝트들이 필요하다면, 내가 직접 해줘야 한다.


LayerMask

LayerMask는 서로 물리나 시스템 상호작용을 할 지 말지를 정해주는 Tag 같은 것이다.

Inspector에서도 실제로 Tag 옆에 있다.

Layer를 설정하고 추가하는건 Tag와 매우 비슷하게 동작한다.

서로 충돌을 하는지 여부를 비트마스크로 저장하기 때문에 최대 32개까지 밖에 지원을 안하니 참고.

LayerMask에 대한 내용은 나중에 따로 다루도록 하겠다.

LayerMask를 이용하여 Raycast 수행 시 충돌감지를 할 지 말지 여부를 Layer로 결정해줄 수 있다.

 
targets = Physics2D.RayCastAll(transform.position, Vector2.one, 100, targetLayer);
 


Boxcast, Circlecast, Capsulecast

Ray가 아닌 도형을 발사하는 cast들이다.

CirclecastAll 같은건 잘 활용하면 일정 거리 이내 공격대상을 받아오는 용도로 활용할 수 있다.

 
targets = Physics2D.CircleCastAll(transform.position, scanRange, Vector2.zero, 0, targetLayer);
 


Uploaded by N2T