Uing? Uing!!

카페오냥 개발 - 03. 유니티 2D swipe & zoom 본문

Unity

카페오냥 개발 - 03. 유니티 2D swipe & zoom

Uing!! 2019. 7. 4. 21:27
반응형

고양이의 이동 애니메이션까지 구현 이후, 화면을 이동하는 기능을 추가하였다.

swipe와 zoom 기능을 구현하기 위해 우선 CameraController.cs 파일을 생성하여 Main Camera에 달아 주었다.

 

그리고 아래와 같이 내용을 작성하였다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraController : MonoBehaviour {

    const int MAX_X = 5;
    const int MIN_X = -5;
    const int MAX_Y = 5;
    const int MIN_Y = -5;
    const float fscale = 0.01f;
    const float zoomSpeed = 0.01f;

    Camera cam;

    Vector2 vscale = new Vector2(fscale, fscale);
    Vector2 startPos;
    Vector2 curPos;
    Vector2 change;
    bool hold = false;
    

    // Start is called before the first frame update
    void Start() {
        cam = GetComponent();
    }

    // Update is called once per frame
    void Update() {

        // swipe
        if (Input.touchCount == 1) {
            if (Input.GetMouseButtonDown(0)) {
                this.hold = true;
                this.startPos = Input.mousePosition;
            } else if (Input.GetMouseButtonUp(0)) {
                this.hold = false;
            }
            if (this.hold) {
                this.curPos = Input.mousePosition;
                transform.Translate((cam.orthographicSize / 5) * vscale * (startPos - curPos));
                if (outside()) transform.Translate((cam.orthographicSize/5) * vscale * (curPos - startPos));
                startPos = curPos;
            }
        }

        // zoom
        else if (Input.touchCount > 1) {
            // store both touches
            Touch touchZero = Input.GetTouch(0);
            Touch touchOne = Input.GetTouch(1);

            // check position
            Vector2 touchZeroPrevPos = touchZero.position - touchZero.deltaPosition;
            Vector2 touchOnePrevPos = touchOne.position - touchOne.deltaPosition;

            // check deltas (original current)
            float prevTouchDeltaMag = (touchZeroPrevPos - touchOnePrevPos).magnitude;
            float touchDeltaMag = (touchZero.position - touchOne.position).magnitude;

            // check how much zoom in / out
            float deltaMagnitudeDiff = prevTouchDeltaMag - touchDeltaMag;

            // zoom camera
            float newSize = cam.orthographicSize + (deltaMagnitudeDiff * zoomSpeed);
            newSize = Mathf.Max(newSize, 1f);
            newSize = Mathf.Min(newSize, 6f);
            cam.orthographicSize = newSize;

        }
    }

    // check if outside the boundary
    bool outside() {
        if (transform.position.x > MAX_X || transform.position.x < MIN_X
            || transform.position.y > MAX_Y || transform.position.y < MIN_Y)
            return true;
        else return false;
    }
}

 

코드에 대해 주석을 달자면 swipe 기능의 경우 터치 개수가 하나일 때, zoom 기능의 경우 다중 터치일 때 실행이 된다.

이 둘을 구분해 주지 않으면 zoom하는 과정에서 원치 않는 카메라 이동이 발생하기 쉬워 이렇게 구현하였다.

 

swipe는 직전 터치 위치와 현재 터치 위치 사이의 벡터를 계산하고 거기에 swipe scale을 곱해 카메라를 이동시킨다. 

zoom은 직전 두 손가락 사이의 거리와 현재 두 손가락 사이의 거리를 비교해 그 차이 값에 zoom scale을 곱해 카메라의 size를 변경시킨다(3D라면 카메라의 위치가 가까워지면 되지만, 2D이므로 orthographicSize를 변경해 준다.) 

 

또한 swipe와 zoom 모두 범위를 지정해 주었다. swipe는 outside()함수를 이용해 적절한 범위 안에 있는지 체크해주고 범위가 넘어가면 돌아오게 하였다. zoom에서는 카메라의 새로운 크기에 Mathf.Max와 Mathf.Min함수를 사용해 1과 6 사이의 크기만이 적용되도록 하였다.

 

멀티터치의 경우 모니터 상에서 실제로 테스트하기가 어려운 만큼, 안드로이드 핸드폰으로 빌드한 후에 테스트를 진행하였다. 아래는 갤럭시 S9 상에서 앉은 상태의 고양이를 클로즈업한 사진이다.

 

 

이 다음으로 구현한 기능은 고양이를 대량으로 생상하는 기능이다. 역시 다음 포스팅에서.

반응형
Comments