标签:分享 获取 pos lamp summary 解决 拖动 es2017 tool
又回来写博客了,这回已经开始上班了,所以就发一发工作中解决的难题吧。
以前对UI的滑动组件很烦心,不是很会用,这回项目要求写一个类似于苹果的文件滑动效果,但是苹果就展示一个文件,而我这边展示数目不定,头疼!
下面就直接来干货吧~,这里附送一个苹果式滑动解决方式 : 点这里
而我追求的效果呢,稍微改动一下,如下:(中间显示很多个,旁边的在叠起来的效果)
这里我们采用比例的方式,这样好控制一些。
几个比较重要的点:
_offset = 1f / (totalPanelCount - showPanelCount); // 1f / (总共Panel - 展示Panel)
private float GetTarget() { return Mathf.Clamp01(Mathf.RoundToInt(_scrollValue / _offset) * _offset); // 取得最近的整数位 }
1 private void AnimationCore(int index) 2 { 3 float sourcePos = index * _offset; 4 // 左边区域 5 if (sourcePos < _scrollValue) 6 { 7 float dif = _scrollValue - sourcePos; 8 int depth = _currentIndex - index; 9 _panelPool[index].transform.SetSiblingIndex(totalPanelCount - depth - 2); 10 _panelPool[index].transform.localPosition = Vector3.Lerp(_panelPool[index].transform.localPosition, GetTargetPos(index, dif, true), 100 * Time.deltaTime); 11 } 12 // 右边区域 13 else if (sourcePos > _scrollValue + _offset * (showPanelCount - 1)) 14 { 15 float dif = sourcePos - _scrollValue - _offset * (showPanelCount - 1); 16 int depth = index - _currentIndex - showPanelCount + 1; 17 _panelPool[index].transform.SetSiblingIndex(totalPanelCount - depth - 2); 18 _panelPool[index].transform.localPosition = Vector3.Lerp(_panelPool[index].transform.localPosition, GetTargetPos(index, dif, false), 100 * Time.deltaTime); 19 } 20 // 中间区域 21 else 22 { 23 _panelPool[index].transform.SetAsLastSibling(); 24 _panelPool[index].transform.localPosition = Vector3.Lerp(_panelPool[index].transform.localPosition, _panelPoolPos[index], 100 * Time.deltaTime); 25 } 26 }
private Vector3 GetTargetPos(int index, float dif, bool isLeft) { float offSetDif = 60 / _offset * dif; if (isLeft) { return _panelPoolPos[index] + Vector3.right * offSetDif; // 左区域 } else { return _panelPoolPos[index] - Vector3.right * offSetDif; // 右区域 } }
1 private float _scrollValue 2 { 3 get 4 { 5 return _scrollRect.horizontal ? 6 _scrollRect.horizontalNormalizedPosition : 7 _scrollRect.verticalNormalizedPosition; 8 } 9 10 set 11 { 12 if (_scrollRect.horizontal) 13 { 14 _scrollRect.horizontalNormalizedPosition = value; 15 } 16 else 17 { 18 _scrollRect.verticalNormalizedPosition = value; 19 } 20 } 21 }
需要继承NGUI的EventSystem的时间来触发管理拖动 PS:用DOTween做最后的回滑效果
完整代码如下:
1 using System; 2 using UnityEngine; 3 using UnityEngine.EventSystems; 4 using UnityEngine.UI; 5 using DG.Tweening; 6 7 [RequireComponent(typeof(ScrollRect))] 8 public class ScrollController : MonoBehaviour, IBeginDragHandler, IEndDragHandler, IDragHandler 9 { 10 [Tooltip("创建出来的对象")] 11 public GameObject imageObject; 12 [Tooltip("展示页面数量")] 13 public int showPanelCount = 8; 14 [Tooltip("总计页面数量")] 15 public int totalPanelCount = 20; 16 [Tooltip("拖动结束制动弹回制动时间")] 17 public float endDragMoveTime = 1f; 18 public Ease doTweenEase = Ease.OutExpo; 19 20 private int _currentIndex; 21 private ScrollRect _scrollRect; 22 private Tweener _tweener; 23 private GameObject[] _panelPool = new GameObject[20]; 24 private Vector3[] _panelPoolPos = new Vector3[20]; 25 private float _offset; 26 27 void Start() 28 { 29 _currentIndex = 1; 30 _scrollRect = GetComponent<ScrollRect>(); 31 _scrollRect.inertia = false; 32 33 for (int i = 0; i < totalPanelCount; i++) 34 { 35 GameObject go = Instantiate(imageObject) as GameObject; 36 go.transform.SetParent(_scrollRect.content.transform); 37 go.GetComponent<RectTransform>().sizeDelta = new Vector2(100, 200); 38 go.GetComponent<RectTransform>().anchorMax = new Vector2(0, 0.5f); 39 go.GetComponent<RectTransform>().anchorMin = new Vector2(0, 0.5f); 40 go.GetComponent<RectTransform>().pivot = new Vector2(0, 0.5f); 41 go.GetComponent<RectTransform>().anchoredPosition = new Vector2(100 + 100 * i, 0); 42 go.transform.localScale = Vector3.one; 43 _panelPool[i] = go; 44 _panelPoolPos[i] = go.transform.localPosition; 45 } 46 47 _scrollRect.content.GetComponent<RectTransform>().sizeDelta = new Vector2(totalPanelCount * 100 + 200, 200); 48 49 _offset = 1f / (totalPanelCount - showPanelCount); 50 51 for (int i = 0; i < totalPanelCount; i++) 52 { 53 AnimationCore(i); 54 } 55 } 56 57 public void OnBeginDrag(PointerEventData eventData) 58 { 59 if (_tweener != null && _tweener.IsActive()) 60 { 61 _tweener.Kill(); 62 } 63 } 64 65 public void OnDrag(PointerEventData eventData) 66 { 67 _currentIndex = Mathf.RoundToInt(GetTarget() * (totalPanelCount - showPanelCount)); 68 69 OnDragAnimation(); 70 } 71 72 public void OnEndDrag(PointerEventData eventData) 73 { 74 _tweener = DOTween.To(() => _scrollValue, (v) => _scrollValue = v, GetTarget(), endDragMoveTime).SetEase(doTweenEase); 75 _tweener.onUpdate = () => 76 { 77 OnDragAnimation(); 78 }; 79 } 80 81 private void OnDragAnimation() 82 { 83 //向左拉动(解决层级问题) 84 if (_scrollValue > 0) 85 { 86 for (int i = 0; i < totalPanelCount; i++) 87 { 88 AnimationCore(i); 89 } 90 } 91 else 92 { 93 for (int i = totalPanelCount - 1; i >= 0; i--) 94 { 95 AnimationCore(i); 96 } 97 } 98 } 99 100 private void AnimationCore(int index) 101 { 102 float sourcePos = index * _offset; 103 // 左边区域 104 if (sourcePos < _scrollValue) 105 { 106 float dif = _scrollValue - sourcePos; 107 int depth = _currentIndex - index; 108 _panelPool[index].transform.SetSiblingIndex(totalPanelCount - depth - 2); 109 _panelPool[index].transform.localPosition = Vector3.Lerp(_panelPool[index].transform.localPosition, GetTargetPos(index, dif, true), 100 * Time.deltaTime); 110 } 111 // 右边区域 112 else if (sourcePos > _scrollValue + _offset * (showPanelCount - 1)) 113 { 114 float dif = sourcePos - _scrollValue - _offset * (showPanelCount - 1); 115 int depth = index - _currentIndex - showPanelCount + 1; 116 _panelPool[index].transform.SetSiblingIndex(totalPanelCount - depth - 2); 117 _panelPool[index].transform.localPosition = Vector3.Lerp(_panelPool[index].transform.localPosition, GetTargetPos(index, dif, false), 100 * Time.deltaTime); 118 } 119 // 中间区域 120 else 121 { 122 _panelPool[index].transform.SetAsLastSibling(); 123 _panelPool[index].transform.localPosition = Vector3.Lerp(_panelPool[index].transform.localPosition, _panelPoolPos[index], 100 * Time.deltaTime); 124 } 125 } 126 127 /// <summary> 128 /// 获取到页面的偏移后位置 129 /// </summary> 130 /// <returns></returns> 131 private Vector3 GetTargetPos(int index, float dif, bool isLeft) 132 { 133 float offSetDif = 60 / _offset * dif; 134 if (isLeft) 135 { 136 return _panelPoolPos[index] + Vector3.right * offSetDif; 137 } 138 else 139 { 140 return _panelPoolPos[index] - Vector3.right * offSetDif; 141 } 142 } 143 144 /// <summary> 145 /// 获得偏转目标位置 146 /// </summary> 147 /// <returns></returns> 148 private float GetTarget() 149 { 150 return Mathf.Clamp01(Mathf.RoundToInt(_scrollValue / _offset) * _offset); 151 } 152 153 /// <summary> 154 /// 当前滑动位置 155 /// </summary> 156 /// <returns></returns> 157 private float _scrollValue 158 { 159 get 160 { 161 return _scrollRect.horizontal ? 162 _scrollRect.horizontalNormalizedPosition : 163 _scrollRect.verticalNormalizedPosition; 164 } 165 166 set 167 { 168 if (_scrollRect.horizontal) 169 { 170 _scrollRect.horizontalNormalizedPosition = value; 171 } 172 else 173 { 174 _scrollRect.verticalNormalizedPosition = value; 175 } 176 } 177 } 178 }
标签:分享 获取 pos lamp summary 解决 拖动 es2017 tool
原文地址:http://www.cnblogs.com/SHOR/p/7581142.html