1.标准的层级结构 ScrollRect->ViewPort->Content,Viewport负责显示区域的大小一般和Mask一起配合使用,Content使用Layout来布局,如果想使用代码来自动定位显示位置需要在Content加上Content size filter.
2.ScrollRectHelper
1 using UnityEngine; 2 using UnityEngine.UI; 3 using UnityEngine.EventSystems; 4 using System.Collections.Generic; 5 using System; 6 7 public class ScrollRectHelper : MonoBehaviour, IBeginDragHandler, IEndDragHandler 8 { 9 // 滑动速度 10 public float smooting = 5; 11 12 // 每页显示的项目 13 [SerializeField] 14 private int countPerPage = 10; 15 16 ScrollRect srect; 17 // 总页数 18 float totalPages; 19 // 是否拖拽结束 20 bool isDrag = false; 21 // 总页数索引比列 0-1 22 List<float> listPageValue = new List<float> { 0 }; 23 // 滑动的目标位置 24 public float targetPos = 0; 25 // 当前位置索引 26 float nowindex = 0; 27 28 void Awake() 29 { 30 srect = GetComponent<ScrollRect>(); 31 } 32 33 public string PageText() 34 { 35 return (nowindex + 1) + "/" + (totalPages + 1); 36 } 37 38 // 计算每页比例 39 public void CalcListPageValue<T>() where T : MonoBehaviour 40 { 41 T[] items = srect.content.GetComponentsInChildren<T>(); 42 srect.content.rect.Set(srect.content.rect.width / 2, srect.content.rect.y, srect.content.rect.width, srect.content.rect.height); 43 totalPages = (int)(Math.Ceiling((float)items.Length / countPerPage) - 1); 44 if (items.Length != 0) 45 { 46 for (float i = 1; i <= totalPages; i++) 47 { 48 //Debug.Log(i / totalPages); 49 listPageValue.Add((i / totalPages)); 50 } 51 } 52 } 53 54 void Update() 55 { 56 if (!isDrag) 57 { 58 srect.horizontalNormalizedPosition = Mathf.Lerp(srect.horizontalNormalizedPosition, targetPos, 59 Time.deltaTime * smooting); 60 } 61 62 // Debug 63 if (Input.GetKeyDown(KeyCode.LeftArrow)) PressLeft(); 64 if (Input.GetKeyDown(KeyCode.RightArrow)) PressRight(); 65 } 66 67 /// <summary> 68 /// 拖动开始 69 /// </summary> 70 /// <param name="eventData"></param> 71 public void OnBeginDrag(PointerEventData eventData) 72 { 73 isDrag = true; 74 } 75 76 /// <summary> 77 /// 拖拽结束 78 /// </summary> 79 /// <param name="eventData"></param> 80 public void OnEndDrag(PointerEventData eventData) 81 { 82 isDrag = false; 83 var tempPos = srect.horizontalNormalizedPosition; //获取拖动的值 84 var index = 0; 85 float offset = Mathf.Abs(listPageValue[index] - tempPos); //拖动的绝对值 86 for (int i = 1; i < listPageValue.Count; i++) 87 { 88 float temp = Mathf.Abs(tempPos - listPageValue[i]); 89 if (temp < offset) 90 { 91 index = i; 92 offset = temp; 93 } 94 } 95 targetPos = listPageValue[index]; 96 nowindex = index; 97 } 98 99 public void PressLeft() 100 { 101 nowindex = Mathf.Clamp(nowindex - 1, 0, totalPages); 102 targetPos = listPageValue[Convert.ToInt32(nowindex)]; 103 } 104 105 public void PressRight() 106 { 107 nowindex = Mathf.Clamp(nowindex + 1, 0, totalPages); 108 targetPos = listPageValue[Convert.ToInt32(nowindex)]; 109 } 110 }