1. 程式人生 > 其它 >unity scrollRect 按頁翻頁實現

unity scrollRect 按頁翻頁實現

技術標籤:UnityC#

參考
https://blog.csdn.net/liu_sanad/article/details/81131894
https://github.com/Hperigo/Unity-ScrollRectController

兩個的實現都多少有點問題,已經在評論貼指出
以下為我根據兩個帖子綜合了一下寫出來的

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

[RequireComponent
(typeof(ScrollRect))] public class ScrollPageTool : UIBehaviour, IEndDragHandler, IBeginDragHandler { public RectTransform scrollTransformRect; //content public RectTransform baseRect; //子控制元件 public float spacing = 0;//間距 public int durationFrame = 10; public AnimationCurve curve = AnimationCurve.
Linear(0f, 0f, 1f, 1f); int targetIndex = 0; Vector2 baseRectSize; public enum eAxis { Horizontal, Vertical } public eAxis mAxis = eAxis.Vertical; public float mScale = 1; //TODO //public enum eDirection //{ // Normal = 1, // Backwards = -1
//} //public eDirection mDirection = eDirection.Normal; protected override void Awake() { baseRectSize = new Vector2(baseRect.rect.width, baseRect.rect.height); SetPositionFromIndex(0, false); } // 開始拖動 public void OnBeginDrag(PointerEventData eventData) { StopAllCoroutines(); } // 結束拖動 public void OnEndDrag(PointerEventData eventData) { targetIndex = GetCurrentPositionIndex(); StartCoroutine(SnapRect()); } private IEnumerator SnapRect() { float timer = 0f; float speed = Mathf.Max(0.01f, (float)1 / durationFrame); int axis = (int)mAxis; float oldPosition = scrollTransformRect.anchoredPosition[axis]; float targetPosition = GetPositionFromIndex(targetIndex)[axis]; Vector2 targetVector = new Vector2(); while (timer < 1f) { float pos = Mathf.Lerp(oldPosition, targetPosition, curve.Evaluate(timer)); timer += speed; targetVector[axis] = pos; scrollTransformRect.anchoredPosition = targetVector; yield return new WaitForEndOfFrame(); } targetVector[axis] = targetPosition; scrollTransformRect.anchoredPosition = targetVector; } // 根據index 設定 position void SetPositionFromIndex(int i, bool animate = true) { StopAllCoroutines(); int max = scrollTransformRect.gameObject.transform.childCount - 1; targetIndex = Mathf.Clamp(i, 0, max); if (!animate) { var pos = GetPositionFromIndex(i); scrollTransformRect.anchoredPosition = pos; } else { StartCoroutine(SnapRect()); } } //根據index 獲得 position Vector2 GetPositionFromIndex(int i) { int axis = (int)mAxis; Vector2 v = new Vector2(0f, 0f); int plus = eAxis.Horizontal == mAxis ? -1 : 1; v[axis] = (baseRectSize[axis] + spacing) * i * plus; return v; } //獲取當前的 index int GetCurrentPositionIndex() { float item = GetOffset(); if (eAxis.Horizontal == mAxis && 0 < item) return 0; if (eAxis.Vertical == mAxis && 0 > item) return 0; //int value = Mathf.RoundToInt(item); float abs_item = Mathf.Abs(item); int value = 0; float deci = abs_item % 1; if (targetIndex < abs_item) { value = Mathf.FloorToInt(abs_item); if (deci > 0.2) value++; } else { value = Mathf.CeilToInt(abs_item); if (deci < 0.6) value--; } int max = scrollTransformRect.gameObject.transform.childCount - 1; value = Mathf.Clamp(value, 0, max); return value; } //獲取offset float GetOffset() { int axis = (int)mAxis; var anchorPos = scrollTransformRect.anchoredPosition[axis]; float offset = anchorPos / (baseRectSize[axis] + spacing); return offset; } //指令碼重置 ScrollRect scrollRect; protected override void Reset() { base.Reset(); if (scrollRect == null) scrollRect = GetComponent<ScrollRect>(); scrollRect.inertia = false; if (scrollRect.movementType == ScrollRect.MovementType.Elastic) { Debug.LogError("ScrollRectController does not work with Elastic movement type, chage it to Clamped or Unrestricted"); } } }