bdfgdfg

투영 본문

게임프로그래밍/Unity

투영

marmelo12 2021. 8. 5. 20:54
반응형

World 좌표계 vs Local 좌표계

World 좌표는 세상(유니티 Scene안의 세상)을 중심으로의 위치를 의미.

Local 좌표는 어느 오브젝트를 기준으로 한 좌표.

 

여기에 Screen(스크린) 좌표도 추가가 되는데.

우리가 화면에서의 좌표는 x,y 좌표밖에 존재하지 않는다. 그렇기에 

void Update()
{
    Debug.Log(Input.mousePosition);
}

위와 같이 코드를 작성해보고 Screen에 마우스를 가져다 대보면.

참고로 유니티 Screen의 좌표계는 좌하단으로 갈수록 0,0에 가깝고 우상단으로 갈수록 x, y값이 증가한다.

 

그리고 Screen좌표이기에 x,y좌표값만 증가, 감소하고 z좌표는 변함이 없는 것을 알 수 있다.

 

카메라에 접근하면 viewportPoint란것도 있다.

Camera.main.ScreenToViewportPoint(Input.mousePosition);

 

(main은 Camera에 태그가 MainCamera인 오브젝트를 가져옴)

이것으로 Log를 찍어보면

Screen좌표와 같이 좌표가 좌하단으로 갈수록 0. 우상단으로 갈수록 높아지지만.

그 값이 0~1사이라는 비율값이란 것을 알 수 있다.

 

그럼 이게 왜 필요할까? 특정 스크린 좌표를 구했을 때 World좌표를 구하기 위함.

즉 2D좌표<->3D좌표를 구해야하기 때문.

 

그렇기에

void Update()
{
    // 마우스좌표를 3D좌표로 변환.
    // x,y는 마우스의 좌표. 마지막에 넣는 z값은 카메라의 near값(깊이값)
    Vector3 mousePos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, Camera.main.nearClipPlane));

    // 위에서 구한 좌표(목적지) - 현재 카메라의위치
    Vector3 dir = mousePos - Camera.main.transform.position;
}

위와같이 dir이라는 방향벡터를 구하면

 

카메라로부터 내가 Screen좌표에서

찍은 마우스좌표까지 가는 방향벡터가 구해진다.

 

이제 normalized를 해 길이(크기)가 1인 벡터로 만들어준 후.

if(Input.GetMouseButtonDown(0))
        {
            // 마우스좌표를 3D좌표로 변환.
            // x,y는 마우스의 좌표. 마지막에 넣는 z값은 카메라의 near값(깊이값)
            Vector3 mousePos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, Camera.main.nearClipPlane));

            // 위에서 구한 좌표(목적지) - 현재 카메라의위치
            Vector3 dir = mousePos - Camera.main.transform.position;
            dir = dir.normalized;


            // 1초동안 레이 유지.
            Debug.DrawRay(Camera.main.transform.position, dir * 100.0f, Color.red, 1.0f);
            RaycastHit hit;
            if (Physics.Raycast(Camera.main.transform.position, dir, out hit,100.0f))
            {
                Debug.Log($"Raycast Camera {hit.transform.gameObject.name}");
            }
        }

위와 같이. 마우스 왼쪽버튼을 스크린에 눌렀을때.

해당 World좌표를 향해 카메라로부터 Ray를 쏠 수 있다.

 

물론 이것을 Unity에서는 기능을 다 구현해놓았기에

if(Input.GetMouseButtonDown(0))
{

    Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);


    // 1초동안 레이 유지.
    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($"Raycast Camera {hit.transform.gameObject.name}");
    }
}

이 코드로 위와 같은 행동을 할 수 있다.

 

반응형

'게임프로그래밍 > Unity' 카테고리의 다른 글

데이터 관리(Json)  (0) 2021.08.08
Coroutine(코루틴)  (0) 2021.08.08
Animation State패턴  (0) 2021.08.06
Raycasting / LayerMask  (0) 2021.08.05
Input Manager / Resource Manager  (0) 2021.08.05
Comments