using Sirenix.OdinInspector; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; using UnityEngine.EventSystems; using UnityEngine.UI; public class PageSwiper : MonoBehaviour, IDragHandler, IEndDragHandler, IPointerUpHandler { private Vector3 m_originPosition; private Vector3 panelLocation; public float percentThreshold = 0.2f; public float easing = 0.5f; public UnityEvent OnClick; public int totalPages { get { return transform.childCount; } } private int currentPage = 1; // Start is called before the first frame update void Start() { m_originPosition = transform.position; panelLocation = transform.position; SetWithScreenSize(); } [Button] public void SetWithScreenSize() { var grid = GetComponent(); var parentRect = transform.parent.GetComponent(); //grid.cellSize = new Vector2() //{ // x = res.x / factor, // y = res.y / factor, //}; grid.cellSize = new Vector2() { x = parentRect.rect.width, y = parentRect.rect.height, }; } public int GetPageRatio(out int page1, out float ratio1, out int page2, out float ratio2) { page1 = default; ratio1 = default; page2 = default; ratio2 = default; int pageCount = totalPages; if (pageCount <= 0) { return 0; } if (pageCount == 1) { page1 = 0; ratio1 = 1.0f; return 1; } float percentage = (transform.position.y - m_originPosition.y) / Screen.height; if (percentage < 0) { page1 = 0; ratio1 = 1.0f; return 1; } if (percentage > pageCount - 1) { page1 = pageCount - 1; ratio1 = 1.0f; return 1; } int count = Mathf.FloorToInt(percentage + 0.5f); float ratio = percentage - count; if (Mathf.Abs(ratio) < 0.01f) { page1 = count; ratio1 = 1.0f; return 1; } count = Mathf.FloorToInt(percentage); ratio = percentage - count; page1 = count; ratio1 = 1 - ratio; page2 = count + 1; ratio2 = ratio; return 2; } public void OnDrag(PointerEventData data) { float difference = data.pressPosition.y - data.position.y; transform.position = panelLocation - new Vector3(0, difference, 0); } public void OnEndDrag(PointerEventData data) { float percentage = (data.pressPosition.y - data.position.y) / Screen.height; if (Mathf.Abs(percentage) >= percentThreshold) { Vector3 newLocation = panelLocation; if (percentage < 0 && currentPage < totalPages) { currentPage++; newLocation = m_originPosition + (currentPage - 1) * new Vector3(0, Screen.height, 0); } else if (percentage > 0 && currentPage > 1) { currentPage--; newLocation = m_originPosition + (currentPage - 1) * new Vector3(0, Screen.height, 0); } StopAllCoroutines(); StartCoroutine(SmoothMove(transform.position, newLocation, easing)); panelLocation = newLocation; } else { StopAllCoroutines(); StartCoroutine(SmoothMove(transform.position, panelLocation, easing)); } } IEnumerator SmoothMove(Vector3 startpos, Vector3 endpos, float seconds) { float t = 0f; while (t <= 1.0) { t += Time.deltaTime / seconds; transform.position = Vector3.Lerp(startpos, endpos, Mathf.SmoothStep(0f, 1f, t)); yield return null; } } public void OnPointerUp(PointerEventData eventData) { OnClick.Invoke(); } }