unity scrollbar事件 事件有哪些

介绍实现ScrollView滑动到底部响应的两种方式。一种在onScrollChanged中, 一种在OnTouchListener中判断
最新 Android 高薪内推
点击广告支持我
我维护的 Android 经验分享的公众号
点击下面广告支持我
站内推荐文章
阿里、滴滴内推,年 40w 以上
那些著名开源库的原理分析
(155,728)(122,392)(106,793)(100,280)(99,941)(90,237)(76,864)(74,629)(74,098)(70,155)
阿里、滴滴内推,年 40w 以上
C 轮融资近 30 亿元理财推荐unity中如何解决scrollview和按钮的冲突问题? - 知乎3被浏览2215分享邀请回答01 条评论分享收藏感谢收起unity(4)
Scroll Rect
原文地址:
file:///C:/Program%20Files/Unity%205.4.0b21/Editor/Data/Documentation/en/Manual/script-ScrollRect.html
与Mask和Scrollbars结合使用。Mask使得只有在scroll rect区域内的内容可见。Scrollbars实现水平或垂直滑动。
属性: 方法:
被滑动的UI元素的Rect Transform的引用
使能水平滑动
使能竖直滑动
自由(Unrestricted), 弹性(Elastic)或夹(Clamped). 后两者强制内容滑动区域保持在Scroll Rect边界范围内。其中,弹性模式时,内容到达边界时将自动弹回。
弹性运动模式时使用的弹回量。
当一个拖拽结束时,内容仍会由于惯性继续滑动;而无惯性时,内容只在拖拽的时候滑动。
当启用惯性时,减速率决定内容有多快会停下来。0即刻停下,1永不停止。
滑动敏感度
滚轮等事件的敏感度。
视口(Viewport)
视口Rect Transform的引用,是内容Rect Transform的父物体。
水平滑块元素的引用(可选)
当不使用水平滑块时是否自动将其隐藏,同时可选的扩大视口。
水平滑块和视口的间隔
竖直滑块元素的引用(可选)
当不使用竖直滑块时是否自动将其隐藏,同时可选的扩大视口。
竖直滑块和视口的间隔
事件: 方法:
On Value Changed
当Scroll Rect的scroll位置变化后调用的Unity事件。此事件将当前的scroll位置以动态Vector2的形式发送出去。
Scroll view中需要viewport,content和可选性的一到两个scrollbars。
根Game Object下添加Scroll Rect组件。
Viewport有Mask组件。Viewport可以是根game object或者是game object的子物体。如果使用了自动隐藏scroll bars,那就必须是一个子物体。Viewport rect transform需要被scroll rect的viewport属性引用。
所有的滑动内容都必须是一个单独的内容game object的子物体,而该内容game object必须是viewport的子物体。Content rect transform需要被scroll rect的content属性引用。
如果使用滑块,它们得是根game object的子物体。
下图中viewport是根scroll view的子物体,这是使用GameObject-&UI-&Scroll View生成的默认格式。
对于scroll content,输入必须在scroll rect边界内接收而不是在content本身上。
注意:使用Unrestricted运动模式时,有可能会彻底失去对内容的控制。当使用Elastic或 Constrained运动模式时,最好是将内容放到Scroll rect边界内部,否则rect transform会总是试图将内容拽回边界内。
滑块设置(可选):
Scroll Rect可以和一个水平或垂直滑块相关联。滑块和viewport同级,并被设置到scroll rect的Horizontal Scrollbar或Vertical Scrollbar里。
注意:scrollbar的方向属性中对于水平滑块应设置为Left To Right,垂直滑块应设为Bottom To Top.
滑块可以有自动隐藏行为,如果content没有viewport所占的区域大,就会自动隐藏滑块。注意:自动隐藏只会在Play Mode生效。在Edit Mode下滑块是一直可见的。
如果1个或两个滑块都设置了Auto Hide And Expand Viewport, viewport会在滑块隐藏时自动扩展并占用滑块原先在的空间。设置了滑块的话,view的位置和尺寸以及水平滑块的宽度、垂直滑块的高度就由scroll rect决定。Viewport和滑块都得是根scroll rect game object的子物体。
内容rect transform的pivot和anchors可以决定内容在scroll view中的排列。如果内容应当和top对齐,则把anchors设置为父物体top处,并把pivot设置为top位置。
See the page Making UI elements fit the size of their content for information about how to make the content Rect Transform automatically resize to fit the content.
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:2469次
排名:千里之外
(4)(3)(1)(1)
(window.slotbydup = window.slotbydup || []).push({
id: '4740887',
container: s,
size: '250,250',
display: 'inlay-fix'当我们在Unity Editor里创建一个Scroll View的时候含有ScrollRect的对象,它下面还有三个子对象,两个含有ScrollBar组件的子对象是作为滚动条,一个Viewport用于限定显示区域。我们可以为Viewport下面的Content对象添加组件(例如Image)或者子对象。点击运行,我们就可以拖动Scroll View,并且看到里面的内容也跟着在滚动。本文就详细分析一下ScrollRect和ScrollBar的源码,了解一下它们是怎么动起来的。
按照惯例,附上。
首先介绍ScrollBar,它继承自Selectable,还继承了IBeginDragHandler,&IDragHandler,&IInitializePotentialDragHandler,&ICanvasElement四个接口。
ScrollBar重写了OnEnable和OnDisable(调用时机参见)方法。OnEnable里会找到m_HandleRect父对象的RectTransform组件作为m_ContainerRect。如果所示:
<span style="font-size:14 color:#号对应的是ScrollBar,2号对应的是m_ContainerRect,3号对应的是m_HandleRect。
然后OnEnable会重新设置当前&#20540;(value),并刷新表现,即根据当前Value设置m_HandleRect的anchorMin和anchorMax,体现出来就是滚动条的位置发生了变化。
而OnDisable只是调用DrivenRectTransformTracker类型的m_Tracker的Clear方法。(参考。)
ScrollBar还重写了Selectable的OnPointerDown方法,设置isPointerDownAndNotDragging为true,使用协程调用了ClickRepeat方法,判断点击事件是否在m_HandleRect外面(一定在Scrollbar里面),如果在外面,就将事件坐标转换到m_HandleRect的本地坐标系里,然后调整value,直到点击事件在m_HandleRect里面。
重写的OnPointerUp方法里面,设置isPointerDownAndNotDragging为false。
另外还重写了Selectable的OnMove、FindSelectableOnLeft、FindSelectableOnRight、FindSelectableOnUp和FindSelectableOnDown方法。当方向键按下并与ScrollBar的方向一致时,便不在导航到下一个Selectable,而是修改value&#20540;(加减stepSize),即移动滚动条。
OnBeginDrag是继承自IBeginDragHandler接口的方法,这个方法里记录了拖拽的起始点(m_HandleRect内相对center的坐标)。
OnDrag是继承自IDragHandler接口的方法,这个方法会调用UpdateDrag方法。
void UpdateDrag(PointerEventData eventData)
if (eventData.button != PointerEventData.InputButton.Left)
if (m_ContainerRect == null)
Vector2 localC
if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(m_ContainerRect, eventData.position, eventData.pressEventCamera, out localCursor))
Vector2 handleCenterRelativeToContainerCorner = localCursor - m_Offset - m_ContainerRect.rect.
Vector2 handleCorner = handleCenterRelativeToContainerCorner - (m_HandleRect.rect.size - m_HandleRect.sizeDelta) * 0.5f;
float parentSize = axis == 0 ? m_ContainerRect.rect.width : m_ContainerRect.rect.
float remainingSize = parentSize * (1 - size);
if (remainingSize &= 0)
switch (m_Direction)
case Direction.LeftToRight:
Set(handleCorner.x / remainingSize);
case Direction.RightToLeft:
Set(1f - (handleCorner.x / remainingSize));
case Direction.BottomToTop:
Set(handleCorner.y / remainingSize);
case Direction.TopToBottom:
Set(1f - (handleCorner.y / remainingSize));
这个方法会计算出m_HandleRect左下角的坐标,根据Direction与剩下的尺寸(就是可滑动区域的尺寸)作比,计算出value。
OnInitializePotentialDrag方法是继承自IInitializePotentialDragHandler的方法,它将拖拽事件的useDragThreshold设为true。(这个&#20540;为true之后,判断拖拽事件开始时会加入一个对于移动距离的阈&#20540;判断)
另外,ScrollBar定义了一个onValueChanged的事件,我们可以在编辑器里添加事件监听。在Set方法里,这个事件可能会被发送出去。
下面我们将ScrollRect。它继承自UIBehaviour,另外还集成了IInitializePotentialDragHandler,&IBeginDragHandler,&IEndDragHandler,&IDragHandler,&IScrollHandler,&ICanvasElement,&ILayoutElement,&ILayoutGroup这些接口。
OnEnable方法里添加了m_HorizontalScrollbar和m_VerticalScrollbar的onValueChanged事件的监听(用于监听滚动条的value变化,以调整内容的位置)。并将自己注册到CanvasUpdateRegistry的Layout序列中去(参考)。
OnDisable方法将自己从CanvasUpdateRegistry中移除,并移除了两个ScrollBar的监听。设置m_HasRebuiltLayout为false,清除m_Tracker,设置m_Velocity(横纵速度)为0(在LateUpdate中被调用,用于将超出边界的内容移动回来),并通知LayoutRebuilder需要重建Layout(参考)。
IsActive除了调用了基类的有效性判断(对象有效并组件激活),还and了m_Content(内容)不为null。
OnRectTransformDimensionsChange(当RectTransform维度改变时)调用了SetDirty方法,通知LayoutRebuilder需要重建Layout。
OnInitializePotentialDrag(IInitializePotentialDragHandler)里设置m_Velocity为0。
OnBeginDrag(IBeginDragHandler)里设置将拖拽事件点转换为viewRect坐标系内的点赋&#20540;给m_PointerStartLocalCursor。将m_Content.anchoredPosition赋&#20540;给m_ContentStartPosition。并设置m_Dragging为true。
图中,1为ScrollRect,2为viewRect,3为content。
OnEndDrag(IEndDragHandler)设置m_Dragging为false。
OnDrag(IDragHandler)会根据m_PointerStartLocalCursor和m_ContentStartPosition计算出m_Content新的anchoredPosition。
OnScroll(IScrollHandler)是用于接收鼠标滚动的方法。这个方法根据滚动距离计算出m_Content的位置。
Rebuild是继承自ICanvasElement(参考),它在重建Layout的时候被调用。在Prelayout(预布局)阶段会调用UpdateCachedData(更新缓存数据,包括m_HorizontalScrollbarRect横向滚动条、m_VerticalScrollbarRect纵向滚动条、m_HSliderExpand是否支持横向滑动展开、m_VSliderExpand是否支持纵向滑动展开、m_HSliderHeight横向滚动条高度、m_VSliderWidth纵向滚动条宽度)。在PostLayout(后布局)阶段会更新边界、重置滚动条、保存旧数据(m_PrevPosition保存content的位置、m_PrevViewBounds保存view的边界、m_PrevContentBounds保存content的边界)。
ScrollRect还继承了ILayoutGroup接口,需要实现SetLayoutHorizontal和SetLayoutVertical两个方法。
SetLayoutHorizontal里,如果m_HSliderExpand或m_VSliderExpand为true,便强制立刻重建content的布局。然后根据m_VSliderExpand、vScrollingNeeded(content的高度大于view的高度)、m_HSliderExpand和hScrollingNeeded(content的宽度大于view的宽度)计算viewRect的sizeDelta、m_ViewBounds和m_ContentBounds。(关于sizeDelta是相对于父对象的尺寸,参考)
SetLayoutVertical里调用UpdateScrollbarLayout方法并更新m_ViewBounds和m_ContentBounds。
UpdateScrollbarLayout里将横向滚动条的宽度设置为与ScrollRect同样&#20540;(如果有纵向滚动条,减掉其宽度),将纵向滚动条的高度设置为与ScrollRect同样&#20540;(如果有横向滚动条,减掉其高度)。
ScrollRect还重写了LateUpdate,这个方法是每一帧都会被调用,在所有组件Update调用完之后。在这个方法里,调用EnsureLayoutHasRebuilt确保Layout已经被重建,调用UpdateScrollbarVisibility更新ScrollBar的可见性。接着UpdateBounds更新边界。如果m_Dragging为false,且content已经超出了可滚动范围(例如:content的最小点的x大于view的最小点的x),且m_Velocity速度不为0,便根据速度逐渐将content的坐标修正为合理的&#20540;。然后如果在拖动中且m_Inertia(惯性)便根据content的当前位置和m_PrevPosition计算出一个新的惯性速度m_Velocity。然后判断m_ViewBounds、m_ContentBounds、m_Content.anchoredPosition和旧数据不同,更新ScrollBar的位置,发送OnValueChanged(编辑器中可设置)并保存当前数据为旧数据。
最后看一下更新边界的方法:
private void UpdateBounds()
m_ViewBounds = new Bounds(viewRect.rect.center, viewRect.rect.size);
m_ContentBounds = GetBounds();
if (m_Content == null)
// Make sure content bounds are at least as large as view by adding padding if not.
// One might think at first that if the content is smaller than the view, scrolling should be allowed.
// However, that&#39;s not how scroll views normally work.
// Scrolling is *only* possible when content is *larger* than view.
// We use the pivot of the content rect to decide in which directions the content bounds should be expanded.
// E.g. if pivot is at top, bounds are expanded downwards.
// This also works nicely when ContentSizeFitter is used on the content.
Vector3 contentSize = m_ContentBounds.
Vector3 contentPos = m_ContentBounds.
Vector3 excess = m_ViewBounds.size - contentS
if (excess.x & 0)
contentPos.x -= excess.x * (m_Content.pivot.x - 0.5f);
contentSize.x = m_ViewBounds.size.x;
if (excess.y & 0)
contentPos.y -= excess.y * (m_Content.pivot.y - 0.5f);
contentSize.y = m_ViewBounds.size.y;
m_ContentBounds.size = contentS
m_ContentBounds.center = contentP
private readonly Vector3[] m_Corners = new Vector3[4];
private Bounds GetBounds()
if (m_Content == null)
return new Bounds();
var vMin = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
var vMax = new Vector3(float.MinValue, float.MinValue, float.MinValue);
var toLocal = viewRect.worldToLocalM
m_Content.GetWorldCorners(m_Corners);
for (int j = 0; j & 4; j++)
Vector3 v = toLocal.MultiplyPoint3x4(m_Corners[j]);
vMin = Vector3.Min(v, vMin);
vMax = Vector3.Max(v, vMax);
var bounds = new Bounds(vMin, Vector3.zero);
bounds.Encapsulate(vMax);
}GetBounds方法是将m_Content的四个顶点的世界坐标转化为viewRect坐标,然后生成一个Bounds,其实就是m_Content相对于viewRect的位置以及尺寸(会在计算m_Content位置的时候用到)。UpdateBounds会继续调整这个&#20540;,只有在Unity官方认为不合理的时候(content宽度或高度比view小)才会执行额外的调整,将Bounds的坐标和尺寸调整成合理的&#20540;(尺寸和view相同,位置根据pivot调整)。
本文已收录于以下专栏:
相关文章推荐
1 功能描述
在做排行榜类似界面时,item非常多,可能有几百个,一次创建这么多GameObject是非常卡的。为此,使用只创建可视区一共显示的个数,加上后置准备个数。如图所示
在游戏中,我们很多地方需要用到scroll content的概念:我们需要一个容器,能够指定布局方式(比如横排排列、竖排排列、网格排列)等。然后我们向其中填充内容,这个容器应该自己能够处理所有的元素布...
最近用UGUI的时候老感觉有的参数不记得什么作用了,找这个找那个的,记性真不行,还是要写在博客上,不记得可以来看看。现在越来越觉得写博客真的非常有必要。
先创建一个UGUI整合好的Scrol...
最近忙于性能优化,深切体会到二八法则真是指导高(tou)效(lan)工作的有力武器。这个礼拜花了几天解决了一个实际问题:UGUI的ScrollRect加载太多物体的时候,第一次弹出界面会非常卡顿,而且...
一. Grid Layout Group 横竖布局
Padding &#160; —— &#160;间隔
CellSize &#160; —— &#160;子物体大小
Spacing &#160; —— &#160;子物体之间的间隔
Start Co...
暑假的时候参照NGUI的循环ScrollView的思路写的,当时给上传到了资源下载频道,因为平时自己也要在CSDN下东西,有些资源要积分才能下载,所以就挂了3分,想着供自己以后下载可以用。到现在也过了...
一、相关组件
ScrollRect Mask Grid Layout Group Scrollbar
1、创建一个Panel,命名为ScrollRect,添加 ScrollRect组件
UGUI各种优化效果本文所实现的UGUI效果需求如下:
- 支持缩放滑动效果
- 支持动态缩放循环加载
- 支持大数据固定Item复用加载
- 支持不用Mask遮罩无限循环加载
- 支持Ob...
当子控件移出可视范围后的处理及当子控件出现在可视范围的处理:
goodsScroll.setOnScrollChangeListener(new View.OnScrollChangeListe...
他的最新文章
讲师:刘文志
讲师:陈伟
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)

我要回帖

更多关于 unity scrollview控件 的文章

 

随机推荐