✔ Unity - LayerMask, Ray, Raycast, RaycastAll
마우스 포인트에서 특정 오브젝트 찾기(Raycast 활용)
◆ Ray 란 어떤 지점의 위치와 방향에서 일직선상의 선을 그어봅니다.
선이 지나가면서 충돌되는 오브젝트들을 판단하는 것이 Raycast 입니다.
일반적으로 많이 사용되는 Raycast, RaycastAll에 대해서 설명 드립니다.
Raycast : 선이 지나가면서 처음 충돌한 오브젝트를 반환.
RaycastAll : 선이 지나가면서 충돌하는 모든 오브젝트를 반환.
◆ Raycast 사용법 예제 : 현재 마우스 위치에서 충돌되는 오브젝트가 있다면 그 위치로 변경.
//마우스 위치에서 레이
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
if (hit != null)
{
transform.postion = hit.point;
}
}
◆ RaycastAll 사용법 예제 : 충돌되는 모든 오브젝트를 그중에 특정하나만 뽑아서 위치 변경
//마우스 위치에서 레이
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
//충돌된 모든 오브젝트를 불러오고 원하는 조건을 넣음.
RaycastHit hit = Physics.RaycastAll(ray).OrderBy(h => h.distance)
.Where(h => h.transform.tag != "player").FirstOrDefault();
if (hit.transform != null)
{
transform.position = hit.point;
}
위 RaycastAll은 약간 응용하여 예제를 넣어봤습니다.
-> 현재 마우스 위치에서 충돌되는 모든 오브젝트를 찾는다.
-> 거리가 가까운순으로 정렬한다.
-> 특정 태그는 제외시킨다.
-> 첫번째 오브젝트에서 충돌된 위치를 찾는다.
◆ Raycast 응용 : Ray의 선상에 있는 오브젝트들 중에서 특정 오브젝트만 추출.
1. 특정 레이어의 오브젝트는 관통하고 다른 레이어 오브젝트를 찾기
현재 마우스 위치에서 내 앞에 있는 오브젝트가 바라보고 있는 오브젝트를 찾고싶은 경우가 있다.
예를 들어 플레이어가 있고 플레이어가 바라보고 있는 오브젝트가 무엇인지 찾아낼때 사용한다.
기법은 Ray를 인식할때 플레이어를 제외하는 방법이다.
먼저 Unity에서 레이어를 추가해주고 설정해주어야한다.
Layers에서 원하는 위치에 레이어 이름을 넣어준다.
다시 Player 오브젝트를 클릭하고 Layer에서 추가한 레이어를 선택한다.
그리고 스크립트를 생성하여 아래 부분을 넣으면 플레이어 뒤에 있는 물체를 알아낼 수 있다.
//플레이어 레이어만 제외함.
int layerMask = (-1) - (1 << LayerMask.NameToLayer("Player"));
Ray ray = camera.ScreenPointToRay(Input.mousePosition);
if ( Physics.Raycast(ray, out RaycastHit hit, Mathf.Infinity, layerMask))
{
Debug.Log(hit.collider.gameObject);
}
2. 특정 레이어의 오브젝트만 찾고 나머지 레이어는 관통하기
아래 코드는 위와는 반대로 특정레이어만 인식하는 방식이다.
//플레이어 레이어만 체크함
int layerMask = 1 << LayerMask.NameToLayer("Player");
Ray ray = camera.ScreenPointToRay(Input.mousePosition);
if ( Physics.Raycast(ray, out RaycastHit hit, Mathf.Infinity, layerMask))
{
Debug.Log(hit.collider.gameObject);
}
3. RaycastAll로 일직선상 모든 오브젝트를 찾아 특정 레이어만 뽑아내기
또 한가지 방법은 RaycastAll 사용하여 특정 레이어를 찾는 방법이다.
이 방법은 위에서 설명했던 RaycastAll 부분에서 조건만 변경하면 됩니다.
하지만 RaycastAll은 오브젝트가 많으면 많을수록 속도가 느려지므로 사용하지 않는것을 추천합니다.
감사합니다.
댓글