본문 바로가기
Unity/Unity_GUI

[Unity_GUI] EventSystem Drag & Scroll을 통한 Zoom In/Out

by Kyoung2 2022. 8. 22.
반응형

유니티 UGUI 에서 간단하게 드래그 기능과 마우스를 통한 Zoom In/Out 기능을 구현할 수 있다.

해당 방법은 Event System을 이용하고 Interface를 통해 기능을 활용하는 예제이다.

 

프로젝트에서 Canvas를 생성한다.

Unity에서는 UI 요소를 생성할 때, Event System 이 같이 생성된다.

https://docs.unity3d.com/kr/530/ScriptReference/EventSystems.EventSystem.html

 

EventSystems.EventSystem - Unity 스크립팅 API

Handles input, raycasting, and sending events.

docs.unity3d.com

 

Canvas에 이미지를 삽입한다.

 

UIController.cs 파일을 작성한다.

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

public class UIController : MonoBehaviour, IDragHandler, IEndDragHandler, IScrollHandler
{
    //Drag 
    private RectTransform rectTr;

    //Mouse Scorll Zoom In/Out
    private Vector3 minitialScale;
    private float zoomSpeed = 0.1f;
    private float maxZoom = 10.0f;


    private float initialDistance;

    private void Start()
    {
        rectTr = GetComponent<RectTransform>(); //스크립트 위치의 Rect Transform
        minitialScale = transform.localScale;  //현재 Local Scale을 저장

    }

    public void OnDrag(PointerEventData eventData)
    {
        rectTr.anchoredPosition += eventData.delta;  //드래그 이벤트 함수 선언 및 등록
    }

    public void OnEndDrag(PointerEventData eventData)
    {
        rectTr.localPosition = Vector3.zero;  //드래그가 끝났을 때
    }

    public void OnScroll(PointerEventData eventData) //마우스 스크롤 이벤트 등록
    {
        var delta = Vector3.one * (eventData.scrollDelta.y * zoomSpeed);
        var desiredScale = transform.localScale + delta;

        desiredScale = ClampDesiredScale(desiredScale);

        transform.localScale = desiredScale;
    }

    private Vector3 ClampDesiredScale(Vector3 desiredScale) // 마우스 스크롤의 최대 줌인/아웃
    {
        desiredScale = Vector3.Max(minitialScale, desiredScale);
        desiredScale = Vector3.Min(minitialScale * maxZoom, desiredScale);

        return desiredScale;
    }

    /// <summary>
    /// Editor에서는 마우스 스크롤을 사용하여 Zoom In/Out
    /// 모바일에서는 터치 이벤트를 통해 Zoom In/Out 
    /// 현재는 둘 다 사용할 수 있도록 적용.
    /// #if를 통해 플랫폼을 나누는것도 방법이다.
    /// </summary>
    private void Update()
    {
        if (Input.touchCount == 2) //손가락 2개가 들어왔을 시
        {
            var touchZero = Input.GetTouch(0);
            var touchOne = Input.GetTouch(1);

            if (touchZero.phase == TouchPhase.Ended || touchZero.phase == TouchPhase.Canceled
               || touchOne.phase == TouchPhase.Ended || touchOne.phase == TouchPhase.Canceled)
            {
                return;//둘중 한손가락이라도 빠져나가면 return
            }

            if (touchZero.phase == TouchPhase.Began || touchOne.phase == TouchPhase.Began)
            {
                initialDistance = Vector2.Distance(touchZero.position, touchOne.position);
                minitialScale = transform.localScale;
            }
            else
            {
                var currentDistance = Vector2.Distance(touchZero.position, touchOne.position);

                if (Mathf.Approximately(initialDistance, 0))
                    return;

                var factor = currentDistance / initialDistance;

                transform.localScale = minitialScale * factor;
            }
        }
    }
}

위에서 드래그 기능은 원점으로 다시 돌아올수 있도록 구성한 예제이다.

 

    public void OnEndDrag(PointerEventData eventData)
    {
        rectTr.localPosition = Vector3.zero;  //드래그가 끝났을 때
    }

 

UIController.cs 파일을 Image에 AddComponent 한다.


결과 화면

 

 

728x90
반응형

# 로딩 화면 동작 코드(Code) 설정하기
loading