UGUI ScrollRect滑动居中CenterOnChild实现
NGUI有一个UICenterOnChild脚本,可以轻松实现ScrollView中拖动子物体后保持一个子物体位于中心位置。然而UGUI就没这么方便了,官方并没有类似功能的脚本。网上找到一些运行效果都不对,可能因为UGUI需要配置的东西太多,RectTransfrom不同设置效果就不一样。故自己实现了该功能,使用时的配置如下:
1. 仅适用于水平方向拖动的ScrollRect。
2. ScrollRect中的Grid必须使用GridLayoutGroup。
3. 由于需要知道ScrollRect的宽度以便计算中心位置,故ScrollRect的Anchors的四个小三角中的上面或者下面的一对角不得分离,不然宽度计算出错,即需要:Anchors.Min.x == Anchors.Max.x。最好四角合一。
4. 由于是通过设置ScrollRect's content的localPosition实现,故需要将ScrollRect的中心点Pivot与content的中心点均置于自身最左边(0, 0.5)。
5. 由于第一个与最后一个子物体需要停留在中间,故ScrollRect的Movement Type需要设置为Unrestricted。该项会在运行时自动设置。
代码如下:
/// <summary>
///
/// 拖动ScrollRect结束时始终让一个子物体位于中心位置。
///
/// </summary>
public class CenterOnChild : MonoBehaviour, IEndDragHandler, IDragHandler
{
//将子物体拉到中心位置时的速度
public float centerSpeed = 9f; //注册该事件获取当拖动结束时位于中心位置的子物体
public delegate void OnCenterHandler (GameObject centerChild);
public event OnCenterHandler onCenter; private ScrollRect _scrollView;
private Transform _container; private List<float> _childrenPos = new List<float> ();
private float _targetPos;
private bool _centering = false; void Awake ()
{
_scrollView = GetComponent<ScrollRect> ();
if (_scrollView == null)
{
Debug.LogError ("CenterOnChild: No ScrollRect");
return;
}
_container = _scrollView.content; GridLayoutGroup grid;
grid = _container.GetComponent<GridLayoutGroup> ();
if (grid == null)
{
Debug.LogError ("CenterOnChild: No GridLayoutGroup on the ScrollRect's content");
return;
} _scrollView.movementType = ScrollRect.MovementType.Unrestricted; //计算第一个子物体位于中心时的位置
float childPosX = _scrollView.GetComponent<RectTransform> ().rect.width * 0.5f - grid.cellSize.x * 0.5f;
_childrenPos.Add (childPosX);
//缓存所有子物体位于中心时的位置
for (int i = ; i < _container.childCount - ; i++)
{
childPosX -= grid.cellSize.x + grid.spacing.x;
_childrenPos.Add (childPosX);
}
} void Update ()
{
if (_centering)
{
Vector3 v = _container.localPosition;
v.x = Mathf.Lerp (_container.localPosition.x, _targetPos, centerSpeed * Time.deltaTime);
_container.localPosition = v;
if (Mathf.Abs (_container.localPosition.x - _targetPos) < 0.01f)
{
_centering = false;
}
}
} public void OnEndDrag (PointerEventData eventData)
{
_centering = true;
_targetPos = FindClosestPos (_container.localPosition.x);
} public void OnDrag (PointerEventData eventData)
{
_centering = false;
} private float FindClosestPos (float currentPos)
{
int childIndex = ;
float closest = ;
float distance = Mathf.Infinity; for (int i = ; i < _childrenPos.Count; i++)
{
float p = _childrenPos[i];
float d = Mathf.Abs (p - currentPos);
if (d < distance)
{
distance = d;
closest = p;
childIndex = i;
}
} GameObject centerChild = _container.GetChild (childIndex).gameObject;
if (onCenter != null)
onCenter (centerChild); return closest;
}
}
由于已缓存所有子物体的位置信息,故该代码简单修改可以扩展功能,如增加到上一项、到下一项、跳转到指定项等功能。
UGUI ScrollRect滑动居中CenterOnChild实现的更多相关文章
- UGUI ScrollRect 滑动
运行环境 Unity3D 5.3.7 p4 在我之前的博客中,写过一些Unity4.6的UGUI,现这篇是基于Unity 5.3的 推荐结构 推荐使用三层来组织,如下所示: ScrollRect :S ...
- 横向滑动页面,导航条滑动居中的 js 实现思路
最近在做新闻咨询页的项目,各个新闻频道通过横向滑动切换,顶部的导航active栏需要跟着切换到对应频道,并且active到达中部时,要一直处在中间. 类似效果就是uc浏览器<UC头条>的导 ...
- [unity]UGUI界面滑动,ScrollRect嵌套滑动
原因:老板蛋痛,让我去抄皇室战争. 思路:我大概知道ngui(后来改成UGUI的)里面有个ScrollView.于是我就想一个横着的SV加上5个竖的SV不就好了吗. 过程: 于是 但是有个问题就是UI ...
- UGUI ScrollRect 鼠标滑动灵敏度调节
- [Unity UGUI]ScrollRect效果大全
UGUI各种优化效果 本文所实现的UGUI效果需求如下: - 支持缩放滑动效果 - 支持动态缩放循环加载 - 支持大数据固定Item复用加载 - 支持不用Mask遮罩无限循环加载 - 支持Object ...
- UICollectionView 图片横向滑动居中偏移量的解决
1.在使用UICollectionView 来显示横向滑动图片的时候,cell与cell之间有间隙,每次滑动后cell都会向左偏移,在使用过这两个方法才解决每次向左偏移的部分. 2.使用方法前不要开启 ...
- UGUI ScrollRect 性能优化
测试环境 操作系统:Windows8.1 开发工具:Unity5.5.2 1.问题描述,在实际开发过程中经常会使用ScrollRect实现滚动列表,当初次加载数据比较多的情形时,Unity3D会出现比 ...
- UGUI 分页渐变居中效果
代码相当冗长,仅作自己记录 在此分页上修改的https://blog.csdn.net/qinyuanpei/article/details/49781133 using UnityEngine;us ...
- UGUI ScrollRect 各参数的代码引用以及作用
随机推荐
- 具体解释TCP协议的服务特点以及连接建立与终止的过程(俗称三次握手四次挥手)
转载请附本文的链接地址:http://blog.csdn.net/sahadev_/article/details/50780825 ,谢谢. tcp/ip技术经常会在我们面试的时候出现,非常多公司也 ...
- Android重写FragmentTabHost来实现状态保存
近期要做一个类似QQ底部有气泡的功能,试了几个方案不太好.我想非常多开发人员使用TabHost都会知道它不保存状态.每次都要又一次载入布局.为了保存状态,使用RadioGroup来实现.状态是能够保存 ...
- Memcache安装与使用
一.资源下载 安装memcached 之前必需要先安装 libevent 分别在libevent和memcached的官网下载安装包libevent-1.4.14b-stable.tar.gz和mem ...
- “volatile”这个关键字
我们经常使用“volatile”这个关键字,它是什么意思? 解析:volatile问题.当一个对象的值可能会在编译器的控制或监测之外被改变时,例如一个被系统时钟更新的变量,那么该对象应该声明成vola ...
- LA 3882 And Then There Was One[约瑟夫问题的变形]
And Then There Was One UVALive - 3882 Sample Input Sample Output //设f[i]为(原约瑟夫问题)第i次要删除的标号 #includ ...
- linux版本查看命令
uname -a显示电脑以及操作系统相关信息 cat /proc/version显示正在运行的内核版本 cat /etc/issue或cat /etc/redhat-release Linux查看版 ...
- 爬虫前戏(回顾掌握) -- HTTP和HTTPS
一.HTTP协议 1.官方概念: HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文 ...
- SQLSERVER安装记录
很多人都喜欢重装编程环境,VS,SQL是最常见的 尤其是SQL,在删除所有的SQL相关的组件之后(360),记得再次打开控制面板,查看是否有漏掉的,本人就有一个SQLXML没有删除掉 在删除之后,清理 ...
- linux中查找用户账户信息和登录信息的11中方法
摘自:开源中国 微信公众号 1. id 2. groups 3. finger 4.getent 5. grep 6. lslogins 7..users 8. who 9. w 10. last或者 ...
- 如何用命令行删除EasyBCD开机选择项?
用硬盘安装Ubuntu方法的windows双系统电脑上面,很多人都是用EasyBCD设置的开机启动选择.所以当我们不需要双系统的时候,或者已经删除双系统后,或者安装双系统失败的情况下,发现电脑的开机启 ...