using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; public interface IPinchHandler { void OnPinchStart(); void OnPinchEnd(); void OnPinchZoom(float gapDelta); } public class PinchZoomModule : MonoBehaviour, IPointerUpHandler,IPointerDownHandler, IDragHandler { private int firstEnterFingerID = -1; private int lastEnterFingerID = -1; private int nowFingersCount = 0; private Vector2 firstFingerPosition; private Vector2 lastFingerPosition; private float distance = 0.0f; public float zoomSpeed = 0.5f; public float minZoom = 0.5f; public float maxZoom = 2.0f; float scale = 1.0f; public float zoomGap = 0.0f; public float zoomGapDelta = 0.0f; public float zoomGapDeltaSpeed = 0.1f; private bool isPinchZooming = false; public IPinchHandler pinchHandler; void Awake() { if(GetComponent(typeof(IPinchHandler)) as IPinchHandler == null) { var add = gameObject.AddComponent(); add.minScale = minZoom; add.maxScale = maxZoom; add.enabled = false; } pinchHandler = GetComponent(typeof(IPinchHandler)) as IPinchHandler; } private void OnEnable() { GetComponent().enabled = true; zoomGap = 0.0f; scale = 1.0f; } private void OnDisable() { GetComponent().enabled = false; } public void OnPointerDown(PointerEventData eventData) { nowFingersCount++; DebugUtil.Log("add new finger, nowFingersCount: " + nowFingersCount); if (nowFingersCount == 1) { firstEnterFingerID = eventData.pointerId; firstFingerPosition = eventData.position; } else if (nowFingersCount == 2) { lastEnterFingerID = eventData.pointerId; lastFingerPosition = eventData.position; distance = Vector2.Distance(firstFingerPosition, lastFingerPosition); isPinchZooming = true; pinchHandler?.OnPinchStart(); } } public void OnPointerUp(PointerEventData eventData) { nowFingersCount--; DebugUtil.Log("remove a finger, nowFingersCount: " + nowFingersCount); if (eventData.pointerId == firstEnterFingerID) { firstEnterFingerID = lastEnterFingerID; firstFingerPosition = lastFingerPosition; lastEnterFingerID = -1; if (isPinchZooming) { isPinchZooming = false; pinchHandler?.OnPinchEnd(); } } else if(eventData.pointerId == lastEnterFingerID) { lastEnterFingerID = -1; if (isPinchZooming) { isPinchZooming = false; pinchHandler?.OnPinchEnd(); } } } public void OnDrag(PointerEventData eventData) { if (isPinchZooming) { if(eventData.pointerId == firstEnterFingerID) { firstFingerPosition = eventData.position; } else if(eventData.pointerId == lastEnterFingerID) { lastFingerPosition = eventData.position; } float nowDistance = Vector2.Distance(firstFingerPosition, lastFingerPosition); zoomGapDelta = nowDistance - distance; zoomGap = zoomGapDelta * zoomSpeed; distance = nowDistance; scale = Mathf.Clamp(scale + zoomGap * zoomGapDeltaSpeed, minZoom, maxZoom); pinchHandler?.OnPinchZoom(scale); } } }