第一次在正式项目里用UGUI,遇到不少问题。其中ScrollRect是比较让人恼火的。看了很多网上已有教程和原代码,终于做出满足项目需求的样子来了。简单分享一下。如有错误的地方,希望大家可以指出,一起进步!
制作一个滚动列表,首先就会想到ScrollRect这个组件。但与NGUI的不同,NGUI的UIScrollView把很多功能都写好了,或者都写到滚动列表专用的几个脚本里。但UGUI的各组件更加分离,比如ScrollRect里面的布局,不是在做滚动列表才使用,而是对所有布局情况下都通用的。我们要做的是把几个通用组件合理组合起来,做出某种特定功能的东西。
首先来看下我的功能树目录:
跟官方的例子很像吧。这里的ScrollPanel是我的一个界面根节点,比如你可以把它当成一个道具界面,ScrollRect是这个界面的主要内容,放了很多道具。整个ScrollRect分了3层,中间层ViewPoint是用来指定滚动窗口大小的,出了ViewPoint范围的Item就看不见了。Content节点是放布局组件的,你可以用水平布局或垂直布局等。
ScrollRect节点上的组件如下: 
主要就是挂ScrollRect脚本,在两处红框分别挂Content节点和ViewPoint节点。因为我的例子里是做水平滚动的,所有在Horizontal里打勾就行了。然后MovementType指定为Elastic,就是有弹性,在Content内容大小大小ViewPoint可视区域大小时,会把Content的内容自动弹回边界位置。
ViewPoint节点的组件如下:
这里要做的是指定滚动可视区域的大小,比如我指定大小为720*240,效果如下:
白色区域,就是在ViewPoint里指定的可视区域,Item出超出这个区域就会看不见了。其实白色区域不需要显示出来,把Mask组件的Show Mask Graphic的勾取消就行了。
Content节点的组件如下:
这个组件非常关键,用了两个UGUI的重要组件,一个是Horizontal Layout Group,水平布局组。用来把Content下面的子节点自动水平布局,Padding用来指定上下左右的偏移量,注意,Left和Right尽量一致,否则Content在自动调整大小时会有问题。Content Size Fitter组件用于让Content自动根据其子节点的大小来调整自身的大小。如果没有这个组件,在动态添加Item时,Content的大小就不会自动调整大小了,在拖动时就会发现有些位置拖不过去。因为Content的大小一定要比所有子节点的大小要大,才能正常显示。你可以试一下把这个组件去掉,然后在运行时动态添加item,看看有什么情况发生。当然,有些人喜欢自己写布局或自己写代码动态调整Content的大小。我喜欢用UGUI的组件,既然有现成的,就把它用得如鱼得水。
注意看我这里的Pivot(轴心点),我把它的x设置为0。如果不设置为0会怎样,看看打开界面后的效果。
这是我运行时打开界面的效果,第一个item没有显示在第一的位置,这是为什么。因为我们用了Content Size Fitter组件,这个组件在自动调整UI元素的大小时,是根据UI元素自身的轴心点来扩展大小的,也就是说,如果我Content的轴心点在0.5*0.5位置的话,Content的大小就会向四周扩大。如果我把Pivot设置为0*0.5,效果如下:
Content就会从轴心点(0,0.5)向外扩大,那前面的item就可以在打开界面时就看得到了。
有些界面我们会打开了关闭再打开,如果第一次打开这个滚动界面并且发生了拖动,不做任何处理只是简单隐藏界面的话,下次打开Content还是停留在上一次拖动的位置。
怎么解决?只要在代码里加一句代码随便设置一下Content的位置,它就会自动回到起始位置了。比如:
如果我们的Item是可以点击的,而且是自己重写了EventTrigger或封装了点击回调脚本,那可能会出现一个问题,在item上面拖动时没有效果,ScrollRect的拖动事件被屏蔽了。如果你的Item直接用Button组件来做的话是没问题的,但很多同学喜欢根据需求或更加便利地使用点击事件就自己写了点击回调脚本。比如,雨松大神的那个代码,如果用那种方法做按钮并把按钮放到ScrollRect上的话,在item上拖动就没效果了。为什么?因为EventTrigger继承了IDragHandler这些接口,如果你自己写的事件触发器是继承了EventTrigger,事件触发器挂在Item上就会把拖动事件截取,但是自己又没有实现IDraghandler,所以在item上面拖动就没任何反应了。所以在自己写点击按钮回调脚本时,可以根据自己需求单独继承IPointerClickHandler,不要什么接口都继承。
还有最后一个问题,策划可以需要我们自动把ScrollRect定位到某一个item上,比如在打开界面时ScrollRect就自动滚动到item9的位置,让item9显示在ViewPoint中间。这个要怎么做呢?
在NGUI里,UIScrollView有一个参数可以设置当前滚动的百分比,只要计算要滚动到的Item在所有Item中的位置比例就可以了。但在UGUI中没有这个功能。我们需要手动计算应该把Content定位到哪个位置。
    /// <summary>
    /// 指定一个 item让其定位到ScrollRect中间
    /// </summary>
    /// <param name="target">需要定位到的目标</param>
    public void CenterOnItem(RectTransform target)
    {
        // Item is here
        var itemCenterPositionInScroll = GetWorldPointInWidget( scrollRect.GetComponent <RectTransform>(), GetWidgetWorldPoint( target));
        Debug .Log( "Item Anchor Pos In Scroll: " + itemCenterPositionInScroll);
        // But must be here
        var targetPositionInScroll = GetWorldPointInWidget( scrollRect.GetComponent <RectTransform>(), GetWidgetWorldPoint( viewPointTransform));
        Debug .Log( "Target Anchor Pos In Scroll: " + targetPositionInScroll);
        // So it has to move this distance
        var difference = targetPositionInScroll - itemCenterPositionInScroll;
        difference .z = 0f ;
 
        var newNormalizedPosition = new Vector2(difference .x / (contentTransform.rect.width - viewPointTransform.rect.width ),
            difference .y / (contentTransform.rect .height - viewPointTransform. rect.height ));
 
        newNormalizedPosition = scrollRect.normalizedPosition - newNormalizedPosition;
 
        newNormalizedPosition .x = Mathf.Clamp01(newNormalizedPosition.x );
        newNormalizedPosition .y = Mathf.Clamp01(newNormalizedPosition.y );
 
        DOTween .To(() => scrollRect.normalizedPosition , x=>scrollRect.normalizedPosition = x , newNormalizedPosition, 3);
    }
 
    Vector3 GetWidgetWorldPoint (RectTransform target)
    {
        //pivot position + item size has to be included
        var pivotOffset = new Vector3(
            (0.5f - target .pivot. x) * target .rect. size.x ,
            (0.5f - target .pivot. y) * target .rect. size.y ,
            0f);
        var localPosition = target.localPosition + pivotOffset ;
        return target.parent.TransformPoint (localPosition);
    }
 
    Vector3 GetWorldPointInWidget (RectTransform target, Vector3 worldPoint)
    {
        return target.InverseTransformPoint(worldPoint );
    }
我直接上代码了,就是调用CenterOnItem这个方法,传入一个item的RectTransform。上面用到了DoTween插件,使得在定位时可以平滑一点,不懂这个的直接百度DoTween。还有一种方法,也是计算好Item的目标位置,直接设置Content的位置
    void CenterToSelected (GameObject selected)
    {
        var target = selected.GetComponent<RectTransform >();
 
        Vector3 maskCenterPos = viewPointTransform.position + (Vector3)viewPointTransform.rect .center;
        Debug .Log ( "Mask Center Pos: " + maskCenterPos);
        Vector3 itemCenterPos = target.position;
        Debug .Log ( "Item Center Pos: " + itemCenterPos);
        Vector3 difference = maskCenterPos - itemCenterPos;
        difference .z = 0 ;
 
        Vector3 newPos = contentTransform.position + difference ;
 
        DOTween .To(() => contentTransform.position , x => contentTransform. position = x , newPos, 5);
    }
其实都差不多,设置ScrollRect.normalizedPosition,在源代码里也是设置Content的位置。而上一种方法,我把移动比例设置在0到1的范围,这在定位前面几个和最后几个item时,就不会跳(呵呵 呵呵呵呵我都不知道怎么讲)。总之自己多试一下吧,我也折腾了一下午,最后看了外国论坛和源代码才最终搞定了,好累。准备跨年啦,祝同学们新年快乐!
转载请注明出处!

转载于:https://www.cnblogs.com/chenwz91/p/5092571.html

UGUI ScrollRect使用相关推荐

  1. 【游戏开发实战】Unity循环复用列表,支持不规则尺寸(对象池 | UGUI | ScrollRect | Demo源码)

    文章目录 一.前言 二.使用方法 1.创建Scroll View 2.设置Scroll View参数 2.1.调整宽高 2.2.删除Scrollbar滑块 2.3.设置item模板: Item Tem ...

  2. UGUI ScrollRect 鼠标滑动灵敏度调节

  3. 【Unity】优化UGUI 滚动条ScrollRect(高效复用)

    最近忙于性能优化,深切体会到二八法则真是指导高(tou)效(lan)工作的有力武器.这个礼拜花了几天解决了一个实际问题:UGUI的ScrollRect加载太多物体的时候,第一次弹出界面会非常卡顿,而且 ...

  4. unity菜单滑动插件_unity游戏清新风格列表滚动视图滑动界面插件Super ScrollView for UGUI 2.4.1...

    Super ScrollView for UGUI  是一个清新风格的列表滚动视图滑动界面游戏插件. UGUI Super ScrollView gives easily-customizable S ...

  5. 20170916导出fuck 7654导航

    Bookmarks 书签栏 unity Unity游戏开发有哪些让你拍案叫绝的技巧? [Unity3D学习 愤怒的小鸟攻略技巧秘籍 unity3d技巧 unity3d愤怒的小鸟实现 unity3d切换 ...

  6. UGUI内核大探究(十一)ScrollRect与ScrollBar

    当我们在Unity Editor里创建一个Scroll View的时候含有ScrollRect的对象,它下面还有三个子对象,两个含有ScrollBar组件的子对象是作为滚动条,一个Viewport用于 ...

  7. UGUI组件之ScrollRect 组件简单笔记(Scroll View)

    ======================================================== 1.ScrollRect 介绍 Scroll View 添加ScrollRect组件用 ...

  8. Unity3D之UGUI基础9:ScrollRect卷动区域

    前文:https://blog.csdn.net/Jaihk662/article/details/87876606(Scrollbar卷动条) 一.ScrollRect卷动区域 ScrollRect ...

  9. 【转】unity3d 在UGUI中制作自适应调整大小的滚动布局控件

    转自 http://blog.csdn.net/rcfalcon/article/details/43459387 在游戏中,我们很多地方需要用到scroll content的概念:我们需要一个容器, ...

  10. Unity UGUI 小知识

    1.有个控件叫Selectable 这个控件在button,slider等身上有,也可以自行添加,可通过API搜索所有带这个控件的物体统一控制. 2.实现ScrollView只使用Scrollbar操 ...

最新文章

  1. 重磅,武汉大学获捐10亿元!
  2. 2012届华为校园招聘机试题
  3. 用css3实现ps蒙版效果+动画
  4. iphone开机白苹果_摔过的iPhone,手机不开机、白苹果、听筒无声,多重问题一次搞定...
  5. 终于有人把幸存者偏差讲明白了
  6. carbon安装win7 thinkpad x1_联想thinkpad x1 carbon 2017笔记本使用u启动u盘安装win7系统教程...
  7. 【java】ThreadLocal 内存泄漏 代码演示 实例演示
  8. django部署到linux上不显示.svg图标处理方法
  9. VXLAN详解(三)
  10. Apache Kylin权威指南3.1 为什么要增量构建
  11. Windows安装SSH
  12. 联想电脑如何进入BIOS的方法汇总
  13. Bandicam(班迪录屏)破解注册机
  14. ubuntu java ide,在Ubuntu 18.04系统中下载与安装Eclipse IDE的方法
  15. initialize php,thinkPHP中_initialize方法实例分析
  16. Android Studio实现一个校园图书管理系统
  17. python string转float原来如此简单,集合set的操作,对于动态变化的训练集操作
  18. 数据库技术在项目中的应用?
  19. CENTOS 7 静默安装 ORACLE 19C
  20. DevTools 无法加载源映射: 无法加载http://localhost:8080/css/bootstrap.css.map 的内容:HTTP 错误: 状态代码 404,net::ERR_HTT

热门文章

  1. 神经网络np基本用法
  2. 一个不到300行的C语言打飞机游戏
  3. epoch、 iteration和batchsize的区别
  4. Yolov3目标检测实战【实现图像中随机出现手写数字的检测】
  5. fork()和多线程
  6. java abs是什么意思_java math.abs
  7. word ctrl v 不能用
  8. Graham 三参数表示法 详解
  9. 区块链 以太坊 每个区块可以包含多少个交易
  10. java如何制作简单的数组_【数据结构与算法】Java制作一个简单数组类