[Unity] 인풋 시스템으로 카메라 움직임 만들기

요구르트·2025년 3월 14일

Unity

목록 보기
4/7

저번에는 Perspective 카메라를 사용하여 카메라의 회전과 줌잇/아웃을 구현했습니다.
이번에는 Orthographic 카메라를 이용해서 카메라의 움직임과 핀치 줌을 구현해 보도록 하겠습니다.
* 처음에 만들었던 핀치 줌을 기준으로 스크립트를 수정할 예정입니다. (참고)

그전에 카메라 Projection(카메라의 원근 시뮬레이션)에 대해 알아보도록 하겠습니다.

Projection

카메라 렌더링은 총 두 가지가 있습니다.
거리별로 원근감을 보여주는 Perspective, 원근감 없이 균일하게 보여주는 Orthographic이 있습니다.
사진으로 예시를 들어보겠습니다.

위 사진이 Perspective이고,

위 사진이 Orthographic입니다.
보시면 아시겠지만, 보통 3D 게임에서는 Perspective를 사용하고 2D에서는 Orthographic을 사용합니다.

카메라 렌더링은 Camera 컴포넌트에서 설정할 수 있습니다. 원하시는 렌더링 스타일에 따라 바꾸시면 될 듯 합니다.

카메라에 있는 다른 프로퍼티를 알고 싶으시다면, 유니티 공식 문서를 참고하시면 됩니다.

Orthgraphic 핀치 줌

Orthgraphic은 Perspective와 다르게 z좌표를 뒤로 밀어도 똑같이 보이게 됩니다.

흰 선 안에 있는 게 현재 뷰를 나타내는데, Orthgraphic은 앞과 뒤가 모두 일정하기 때문에 z좌표를 뒤로 밀어도 똑같이 보이는거죠.
따라서 저 주황색 선의 범위를 변경해야 핀치 줌이 제대로 작동할 것입니다.
저 주황색 범위는 어떻게 늘릴 수 있을까요?

Orthgraphic로 변경하면, Size라는 친구가 뜰겁니다. 이 친구가 위에 있는 주황색 범위를 바꿀 수 있는 값입니다.
값이 작아질 수록 범위가 줄어들고(확대), 값이 커질수록 범위가 늘어납니다(축소).

따라서 아래와 같이 코드를 작성하였습니다.

// CameraInput.cs

        private IEnumerator ZoomDetection()
        {
            float prevDistance = Vector2.Distance(inputSO.GetPrimaryPosition(), inputSO.GetSecondaryPosition());
            while (true)
            {
                float distance = Vector2.Distance(inputSO.GetPrimaryPosition(), inputSO.GetSecondaryPosition());
                float deltaDistance = distance - prevDistance;

                Camera.main.orthographicSize = Mathf.Clamp(Camera.main.orthographicSize - deltaDistance * camSpeed, 50f, 950f);

                prevDistance = distance;
                yield return null;
            }
        }

prevDistance와 distance, deltaDistance까지는 똑같습니다.
다만 저 값들을 넣어줄 위치와 방법이 약간 바뀌었습니다.

Camera.main.orthographicSize = Mathf.Clamp(Camera.main.orthographicSize - deltaDistance * camSpeed, 50f, 950f);

delta값을 구해준 후 아까 말했던 size값(Camera.main.orthographicSize)에 넣어줄 겁니다.
Mathf.Clamp는 값을 제한하는 친구입니다. Mathf.Clamp(제한할 값, 최소값, 최대값)을 대입해주면 최소값과 최대값 사이의 값으로 조정됩니다.
제한할 값은 Camera.main.orthographicSize - deltaDistance * camSpeed, 최소값은 50, 최대값은 950이죠.

deltaDistance는 현재 터치간 거리를 처음 터치간 거리로 뺀 값입니다. 값이 클수록 확대를 하고, 값이 작을수록 축소를 합니다.
size의 경우에는 값이 작아질수록 확대를 하기 때문에 - deltaDistance를 해주었습니다.

Orthgraphic 카메라 움직임

카메라 움직임은 이전 코드인 카메라 회전을 참고하여서 만들었습니다.
카메라 움직임은 매우 간단합니다. 아래 gif를 보면 한번에 이해할 수 있습니다.

이렇게 z축을 고정하고 x,y축을 움직이면 해결할 수 있습니다.
따라서 아래와 같이 코드를 수정하였습니다.

// CameraInput.cs

        private IEnumerator MoveCoroutine()
        {
            float prevX = inputSO.GetPrimaryPosition().x;
            float prevY = inputSO.GetPrimaryPosition().y;
            Vector3 curPos = Camera.main.transform.localPosition;

            while (true)
            {
                float deltaX = inputSO.GetPrimaryPosition().x - prevX;
                float deltaY = inputSO.GetPrimaryPosition().y - prevY;

                float value = Camera.main.orthographicSize / 950;
                if (value <= 0) value = 1;

                Camera.main.transform.localPosition += new Vector3(-deltaX, -deltaY) * (moveSpeed * value);

                prevX = inputSO.GetPrimaryPosition().x;
                prevY = inputSO.GetPrimaryPosition().y;
                yield return null;
            }
        }

포지션을 움직일 때 -를 하는 이유는 다음과 같습니다.

첫번째 터치 위치에서 왼쪽에 배치된 두번째 위치를 빼면 무조건 +값이 나오겠죠?

하지만 여기서 +값으로 가게된다면 오른쪽으로 가게 될 것입니다.
따라서 값을 대입하기 전에 -로 부호를 바꿔서 움직이게 하는 겁니다.

value는 거리당 속도 감소를 위해 만들었습니다. 확대할수록 속도가 느려지고, 축소할수록 속도가 빨라지길 원하는 기획자의 말을 전달받아 만들게 되었습니다.
줌아웃의 최대 값이 950이므로, size/950을 하면 확대할수록 0.x배로 속도가 느려집니다.

profile
경기게임마이스터고 4기

0개의 댓글