Unity - Raycasting

이승덱·2021년 12월 27일
0

UnityEngine

목록 보기
8/11

Unity - Raycasting

  • 에디터 화면에서 클릭하여 오브젝트를 picking하는 기능과도 같이, 레이저를 쏴 레이저에 충돌한 물체를 판단하는 기법.
  • 클릭시 카메라 위치에서 클릭한 위치로 레이저를 쏴 충돌한 오브젝트가 클릭되었다고 인식.
// 디버그용 레이저 렌더링
Debug.DrawRay(transform.position + Vector3.up, look * 10.0f,Color.red);

// 충돌체를 저장할 변수
RaycastHit hit;

// 레이캐스트
RaycastHit hit;
if(Physics.Raycast(transform.position+Vector3.up, look, out hit,10))
{
   Debug.Log($"Raycast! {hit.collider.gameObject.name}");
}

// 다중 충돌 레이캐스트
RaycastHit[] hits;

hits = Physics.RaycastAll(transform.position + Vector3.up, look, 10);
        
foreach(RaycastHit h in hits)
	Debug.Log($"Raycast hits! {h.collider.gameObject.name}");
투영
  • 3d 좌표를 결국 2d화면인 모니터에 표현을 해야한다.
  • Local -> World -> ViewPort -> Screen(화면)
  • 카메라가 현재 찍는 영역을 절두체라고 하고 절두체 외부에 존재하는 오브젝트는 Culling되어 렌더링 되지 않는다.
  • Clipping Planes을 통해 절두체의 시작점(near)과 끝점(far)을 설정할 수 있다.
  • 3d->2d 변환시 좌표가 하나 없어진다!(깊이값이 없어짐)
  • 따라서 깊이 값에 따라 원근법과 가려진 물체에 대한 렌더링 설정을 수행한 후 2d로 변환되어 그려진다.
Screen 좌표를 표현(2D, 픽셀 기준으로 처리)
Debug.Log(Input.mousePosition);

ViewPort 좌표로 변환 (0 ~ 1 내에서 비율로 처리)
Debug.Log(Camera.main.ScreenToViewportPoint(Input.mousePosition));

그렇다면 돌아와서 Raycast로 마우스 Picking을 어떻게 하는 것인가..

  • 마우스 Picking지점의 Screen좌표를 World좌표로 변환을 한다.
  • 그 후 카메라의 월드좌표에서 마우스 Picking지점의 World좌표로 가는 방향 벡터를 구한다.
  • 그 방향으로 Raycast를 쏜다.
// 마우스 피킹 지점의 월드 좌표를 알아냄
Vector3 mousePos =Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, Camera.main.nearClipPlane));
// 카메라에서 마우스 피킹 지점 방향의 단위벡터
Vector3 dir = (mousePos - Camera.main.transform.position).normalized;

RaycastHit hit;
if(Physics.Raycast(Camera.main.transform.position, dir,out hit))
{
    Debug.Log($"picking {hit.collider.gameObject.name}");
}
if (Input.GetMouseButtonDown(0))
{
    // 아주 간단하게 위 과정을 해주는 코드
    Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);


    Debug.DrawRay(Camera.main.transform.position, ray.direction* 100.0f, Color.red, 1.0f);

    RaycastHit hit;
    if (Physics.Raycast(ray, out hit, 100.0f))
    {
        Debug.Log($"picking {hit.collider.gameObject.name}");
    }
}
profile
공부 기록용 블로그입니다

0개의 댓글