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}");
}
}