본문 바로가기
카테고리 없음

[Unity3D] Raycast 활용법 : 특정 오브젝트 관통하여 뒤의 물체 인식하기

by 타임박스 2021. 3. 17.
반응형


✔ 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은 오브젝트가 많으면 많을수록 속도가 느려지므로 사용하지 않는것을 추천합니다.

 

감사합니다.

반응형

댓글