又回来写博客了,这回已经开始上班了,所以就发一发工作中解决的难题吧。

单个展示Panel(苹果式)

以前对UI的滑动组件很烦心,不是很会用,这回项目要求写一个类似于苹果的文件滑动效果,但是苹果就展示一个文件,而我这边展示数目不定,头疼!

下面就直接来干货吧~,这里附送一个苹果式滑动解决方式 : 点这里

多个展示Panel(改写)

而我追求的效果呢,稍微改动一下,如下:(中间显示很多个,旁边的在叠起来的效果)

这里我们采用比例的方式,这样好控制一些。

几个比较重要的点:

  • 每个Panel之间的比例差值
_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     }

  • 获取Panel的滑动偏移位置
    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 }

转载于:https://www.cnblogs.com/SHOR/p/7581142.html

Unity NGUI ScrollView 苹果式滑动相关推荐

  1. Unity NGUI 插件 简介

    文章目录 Unity NGUI 一. NGUI基础 1.1 导入NGUI插件 1.2 基本UI资源 1.3 制作UI图集 1.4 制作UI字体 1.5 UIRoot.UIPanel 和 UICamer ...

  2. Unity NGUI 3.0.4版本 制作网络版斗地主

    Unity NGUI 3.0.4版本 @by 灰太龙  开发环境 Win7旗舰版 Unity 4.2.1f4 本文就写个开门篇,告诉大家怎么用NGUI,第一步导入NGUI 3.0.4版本! 1.启动U ...

  3. Android之 如何解决ScrollView 和ListView滑动冲突的问题如何解决ScrollView can host only one direct child

    android 采用ScrollView布局时出现异常:ScrollView can host only one direct child. 解决办法:主要是ScrollView内部只能有一个子元素, ...

  4. 响应式滑动菜单_如何创建响应式滑动菜单

    响应式滑动菜单 by Prashant Yadav 通过Prashant Yadav 如何创建响应式滑动菜单 (How to create a responsive sliding menu) I r ...

  5. ios7中使用scrollview来横向滑动图片,自动产生偏移竖向的偏移 问题

    ios7中使用scrollview来横向滑动图片,自动产生偏移竖向的偏移 问题   如图红色为scrollview的背景色,在scrollview上加了图片之后,总会有向下的偏移 设置contentO ...

  6. scrollview嵌套listview 滑动事件冲突的解决方法

    scrollview嵌套listview 滑动事件冲突的解决方法 参考文章: (1)scrollview嵌套listview 滑动事件冲突的解决方法 (2)https://www.cnblogs.co ...

  7. Unity NGUI 网络斗地主 -界面制作

    Unity NGUI 网络斗地主 -界面制作 源文件在群(63438968群共享!) @灰太龙 这一节说一下NGUI的界面摆放,并且教会大家使用NGUI的自适应功能! 在这里感谢@Gamer,是他给我 ...

  8. unity webgl打包 苹果12以上机型打开连接后模型黑屏卡帧问题

    unity webgl打包 苹果12以上打开模型卡帧问题 查找到问题大概是跟场景灯光阴影相关, 如果关闭阴影 在苹果12以上的机型上打开就会出现卡帧问题 解决方案: 灯光这样设置就可以解决卡帧问题

  9. Android取消RecyclerView、ListView、ScrollView、HorizontalScrollView滑动到边缘闪现灰白色水波纹动画

    Android取消RecyclerView.ListView.ScrollView.HorizontalScrollView滑动到边缘闪现灰白色水波纹动画 标准的Android RecyclerVie ...

最新文章

  1. C#中Invoke的用法
  2. 8月最新阿里技术栈架构资料
  3. 阿里云企业服务器配置选择教程!
  4. 一步一步教你写带图片注释的淡入淡出插件(三)
  5. SQL语言之DQL语言学习(十一)分页查询
  6. 安卓学习之路之如何显示一个listview列表视图
  7. leetcode —— 数组(1. Two Sum)
  8. c++ 调用python_闲话python 48: C/C++扩展Python与Swig工具
  9. 【网络】趣谈网络协议总结
  10. cad快速选择命令快捷键_CAD图层快捷键命令应用讲解
  11. jsp遍历List map
  12. 2500个常用汉字及繁体对应
  13. JavaSE第04篇:Java基础语法之循环结构
  14. 新书推荐 | 数据流机器学习:MOA实例
  15. 姜维拥兵10万 为何守不住刘备的半壁江山
  16. linux 7 realm,系统运维|Samba 系列(十五):用 SSSD 和 Realm 集成 Ubuntu 到 Samba4 AD DC...
  17. 博客园自定义背景图片
  18. 数字地与模拟地的区别——为何要分开
  19. Deep learning based segmentation for automated training of apple trees on trellis wires
  20. 2021阳城一中高考成绩查询,2017阳城一中录取分数线(附2017高考成绩喜报)

热门文章

  1. 基于SSM实现医院疫情管理系统
  2. MapTask的工作机制
  3. Linux-Shell 快捷键
  4. What is Gensim?
  5. pandas中DataFrame的apply()方法和applymap()方法,以及python内置函数map()
  6. RabbitMQ-1
  7. 软工作业——四则运算生成器(scala 实现)
  8. String Manipulation
  9. [jobdu]调整数组顺序使奇数位于偶数前面
  10. Flex使用cookie保存登状态