본문 바로가기

Game_Making/Unity

Unity NGUI를 이용하여 카메라 활동영역 조정하기

유니티로 앱을 만들던중 계획에 없던 카메라의 줌인 기능이 추가되면서 약간 고생했다..


먼저, 유니티에서 카메라 확대기능을 만들때에는 3가지 방법이 있다.

3D일때는 Field Of View(FOV)를 조절하여 원근법을 조절하는법, 직접 카메라를 움직이는법(유니티에서 기본으로 제공해주는 스크립트가 있

기 때문에 그걸 써도 무방하다)

3D 카메라 튜토리얼 링크 - http://unity3d.com/kr/learn/tutorials/topics/mobile-touch/pinch-zoom 3D관련은 유니티에서 튜토리얼까지 만들어서 알려준다!(2D는 좀 소홀한

편)




마지막으로 2D일때는 OrthographicSize를 조절하는 방법이다. (NGUI한정)

2D 카메라는 Camera - Projection을 orthographic으로 바꾸면 평면카메라가 완성되고 초기사이즈 값은 5로 들어가는데 글쓴이는 편의상 1로

맞추고 작업한다. 

(좌측이 OrthographicSize = 5, 우측이 OrthographicSize = 1


원래대로면 난 2D로 앱을 만들고 있기 때문에 카메라는 Orthographic으로 설정하여 OrthographicSize를 늘리고 줄이면 되지만 

OrthographicSize를 조절하면 카메라 크기에 맞춰 해상도 대응을 해놓은 상태라 메인카메라를 건드리면 해상도가 망가지는 상황이다.

왼쪽) 메인카메라를 기준으로 각 텍스쳐들의 위치를 해상도에 대응하게 잘 맞춰놓았다.

오른쪽) 그러나 화면을 확대하기 위해 메인카메라의 OrthographicSize를 조절하자 앱의 해상도 대응이 망가진다.


그러므로 확대용으로 카메라를 하나 더 만들기로한다. 

이제부터 본론이다.


먼저 카메라를 새로 만들고 Camera - Projection을 orthographic으로 맞춘다.

그다음 Depth값을 메인카메라보다 높게 잡는다. 글쓴이는 메인카메라 Depth가 1이므로 확대용 카메라에는 넉넉히 5를준다.

카메라를 다 만들었으면 오브젝트를 같이 움직여야할 메인카메라 자식으로 넣어준다음 좌표를 0,0,0으로 맞춘다.

(확대용 카메라는 ExpandCamera, 메인으로 보여주는 카메라는 Camera이다.)


그리고 카메라에 확대와 확대했을때 움직이는 스크립트를 붙인다.

새로만든 카메라에 붙인코드


 
using UnityEngine;

public class ExpandCameraScript : MonoBehaviour
{
    int touchCount;

    float m_OldTouchDistance;
    float m_NowTouchDistance;

    Vector3 oldPos;
    Vector3 panOrigin;

    //카메라의 이동, 줌인, 줌아웃 감도 변수
    public float moveSpeed = 2;

    float startTime = 0;

    //줌 인, 줌 아웃 되고 있을때에는 카메라를 움직일 수 없도록 trigger 선언
    bool trigger = false;
    public Camera expandCamera, mainCamera;

    void Awake()
    {
        startTime = Time.time;
    }

    void Update()
    {
        touchCount = Input.touchCount;

        if (touchCount == 2)
        {
            expandCamera.enabled = true;

            if (m_OldTouchDistance == 0)
                m_OldTouchDistance = Vector2.Distance(Input.touches[0].position, Input.touches[1].position);

            m_NowTouchDistance = Vector2.Distance(Input.touches[0].position, Input.touches[1].position);

            if (m_NowTouchDistance > m_OldTouchDistance)
            {
                trigger = true; //줌 인, 줌 아웃 되고 있을때에는 카메라를 움직일 수 없도록 trigger 선언
                ZoomIn();
            }
            else if (m_NowTouchDistance < m_OldTouchDistance)
            {
                trigger = true; //줌 인, 줌 아웃 되고 있을때에는 카메라를 움직일 수 없도록 trigger 선언
                ZoomOut();
            }

            m_OldTouchDistance = m_NowTouchDistance;
        }

        //컴퓨터에서 orthographic을 조절하고 ZoomOut 테스트용, 정상작동하면 지우자
        if (Input.GetKey(KeyCode.Q))
        {
            ZoomOut();
        }

        if (Input.GetMouseButtonDown(0))
        {
            oldPos = transform.position;
            panOrigin = expandCamera.ScreenToViewportPoint(Input.mousePosition);
            return;
        }

        if (Input.GetMouseButton(0))
        {
            if (expandCamera.orthographicSize < 1 && !trigger) //카메라의 orthographicSize가 최대값보다 작고 trigger가 false일때 작동
            {
                Vector3 pos = expandCamera.ScreenToViewportPoint(Input.mousePosition) - panOrigin;

                //moveSpeed로 움직이는 속도 조절
                transform.position = oldPos + -pos * moveSpeed;
                
                //(카메라 사이즈가 줄어든 값) * 10
                float pixelRatio = (1 - expandCamera.orthographicSize) * 10;
 
                //36은 카메라가 줄어들때마다 늘어나는 카메라 x의 최대값
                if (expandCamera.transform.localPosition.x > (36 * pixelRatio) || expandCamera.transform.localPosition.x < -(36 * pixelRatio))
                {
                    Vector3 newCameraPosition = transform.localPosition;
                    newCameraPosition = new Vector3(Mathf.Clamp(newCameraPosition.x, -(36 * pixelRatio), (36 * pixelRatio)), newCameraPosition.y, 0);
                    transform.localPosition = newCameraPosition;
                }

                //64는 카메라가 줄어들때마다 늘어나는 카메라 y의 최대값
                if (expandCamera.transform.localPosition.y > (64 * pixelRatio) || expandCamera.transform.localPosition.y < -(64 * pixelRatio))
                {
                    Vector3 newCameraPosition = transform.localPosition;
                    newCameraPosition = new Vector3(newCameraPosition.x, Mathf.Clamp(newCameraPosition.y, -(64 * pixelRatio), (64 * pixelRatio)), 0);
                    transform.localPosition = newCameraPosition;
                }
            }
        }

        if (Input.GetMouseButtonUp(0))
            trigger = false;

        if (expandCamera.orthographicSize > 1)
            expandCamera.orthographicSize = 1;
        else if (expandCamera.orthographicSize < 0.5f)
            expandCamera.orthographicSize = 0.5f;

        if (expandCamera.orthographicSize == 1)
            expandCamera.enabled = false;
    }

    void ZoomOut()
    {
        if (expandCamera.orthographicSize < 1)
        {
            //moveSpeed로 줌 아웃 속도 조절
            expandCamera.orthographicSize += moveSpeed * Time.deltaTime;

            //줌아웃이 되면서 좌표를 초기값인 0,0,0으로 돌리는 부분
            float journeyLength = Vector3.Distance(expandCamera.transform.localPosition, mainCamera.transform.localPosition);
            float distCovered = (Time.time - startTime) * 10;
            float fracJourney = distCovered / journeyLength;

            Vector3 tempVector = expandCamera.transform.position;
            expandCamera.transform.localPosition = Vector3.Lerp(expandCamera.transform.position, Vector3.zero, fracJourney);
        }
    }

    void ZoomIn()
    {
        if (expandCamera.orthographicSize > 0.5f)
            //moveSpeed로 줌 인 속도 조절
            expandCamera.orthographicSize -= moveSpeed * Time.deltaTime;
    }
}

물론 자기 프로젝트 입맛에 맞게 좀 변경하는걸 권장한다. 글쓴이도 급하게 만든거라 쌈마이하지만. 조금만 손보면 다른곳에서 쓰는 스크립트 부럽지 않을거다.


사용법은 크롬의 페이지 확대기능과 같다. 두번 클릭하면 줌 인/아웃, 줌 되었을때 드래그. 제스쳐로 확대/축소 가능.



마지막으로 다시한번 강조하지만 NGUI를 사용할때 이야기이다.

'Game_Making > Unity' 카테고리의 다른 글

카메라 활동영역 설정하기  (0) 2016.06.01