Unity控件ScrollView使用问题记录
Posted HelloWorld
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity控件ScrollView使用问题记录相关的知识,希望对你有一定的参考价值。
Unity版本:5.6.2
控件Scroll View由4部分组成,如图:
1.含有Scroll Rect组件的根节点:Scroll View
2.含有Mask组件的节点:Viewport
3.所有内容的父节点Content,常含有布局控件
4.滚动条,包括横向和纵向
具体的节点细节使用可以参看官方文档:
https://docs.unity3d.com/560/Documentation/Manual/script-ScrollRect.html
使用时遇到的问题记录:
1.显示区域怎么控制?
节点Scroll View中的组件Rect Transform的Width和Height控制着整个区域大小,组件Scroll Rect的滚动条设置也会影响显示区域的边界位置是否完整;
节点Viewport的组件Image中的Image Type属性会影响显示的区域;
节点Content的组件Rect Transform的布局和宽高影响了显示的区域。
2.如何去掉滚动条?
节点Scroll View中的组件Scroll Rect中的属性Horizontal Scrollbar和Vertical Scrollbar设置为None,并将其子节点Scrollbar Horizontal和Scrollbar Vertical删除。
3.内容如何布局?
在节点Content中加入对应的布局组件即可。
4.出现无法滑动或者自动回弹到原地方的原因?
如果节点Content的宽度或者高度小于实际内容的宽度或者高度时,就会发生这样的情况。这时需要调整Content的宽高,或者加入组件Content Size Fitter把对应方向设置为Preferred Size来自适应宽高。
5.滑动结束后,往往不能把当前的元素的画面完整显示的情况,如何解决?
这种情况需要给节点Scroll View挂载脚本来实现,脚本:ScrollRectCenterChild.cs代码如下:
注意:Content节点的RectTransform组件中的Pivot属性必须设置为0,1
Content节点的布局方式可以是Vertical Layout Group、Horizontal Layout Group 或者 Grid Layout Group,但都只支持一个方向的滑动居中。
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityEngine.EventSystems; using System; public enum ScrollDir { Horizontal, Vertical } public class ScrollRectCenterChild : MonoBehaviour,IEndDragHandler,IDragHandler,IBeginDragHandler { public ScrollDir Dir = ScrollDir.Vertical; private bool _isCentering = false; public float MoveToCenterSpeed = 10f; private ScrollRect _scrollView; private Transform _content; //用于保存子元素的坐标值 private List<float> _childrenPos = new List<float>(); private float _targetPos; private int _curCenterChildIndex = -1; public GameObject CurCenterChildItem { get { GameObject centerChild = null; if (_content != null && 0 <= _curCenterChildIndex && _curCenterChildIndex < _content.childCount) { centerChild = _content.GetChild(_curCenterChildIndex).gameObject; } return centerChild; } } private float GetChildItemWidth(int index) { return (_content.GetChild(index) as RectTransform).sizeDelta.x; } private float GetChildItemHeight(int index) { return (_content.GetChild(index) as RectTransform).sizeDelta.y; } void Awake() { _scrollView = GetComponent<ScrollRect>(); if (null == _scrollView) { Debug.LogError("ScrollRect is null."); return; } _content = _scrollView.content; LayoutGroup layoutGroup = null; layoutGroup = _content.GetComponent<LayoutGroup>(); if (null == layoutGroup) { Debug.LogError("LayoutGroup comment is null."); return; } float spacing = 0f; switch (Dir) { case ScrollDir.Horizontal: float scrollViewRectWidth = _scrollView.GetComponent<RectTransform>().rect.width; if (layoutGroup is HorizontalLayoutGroup) { float childPosX = scrollViewRectWidth * 0.5f - GetChildItemWidth(0) * 0.5f; _childrenPos.Add(childPosX); spacing = (layoutGroup as HorizontalLayoutGroup).spacing; for (int i = 1; i < _content.childCount; i++) { childPosX -= GetChildItemWidth(i) * 0.5f + GetChildItemWidth(i - 1) * 0.5f + spacing; _childrenPos.Add(childPosX); } } else if (layoutGroup is GridLayoutGroup) { GridLayoutGroup grid = layoutGroup as GridLayoutGroup; float childPosX = scrollViewRectWidth * 0.5f - grid.cellSize.x * 0.5f; _childrenPos.Add(childPosX); for (int i = 1; i < _content.childCount; i++) { childPosX -= grid.cellSize.x + grid.spacing.x; _childrenPos.Add(childPosX); } } else { Debug.LogError("Horizontal ScrollView is using VerticalLayoutGroup."); } break; case ScrollDir.Vertical: float scrollViewRectHeight = _scrollView.GetComponent<RectTransform>().rect.height; if (layoutGroup is VerticalLayoutGroup) { float childPosY = scrollViewRectHeight * 0.5f - GetChildItemHeight(0) * 0.5f; _childrenPos.Add(childPosY); spacing = (layoutGroup as VerticalLayoutGroup).spacing; for (int i = 1; i < _content.childCount; i++) { childPosY += GetChildItemHeight(i) * 0.5f + GetChildItemHeight(i - 1) * 0.5f + spacing; _childrenPos.Add(childPosY); } } else if (layoutGroup is GridLayoutGroup) { GridLayoutGroup grid = layoutGroup as GridLayoutGroup; float childPosY = scrollViewRectHeight * 0.5f - grid.cellSize.y * 0.5f; _childrenPos.Add(childPosY); for (int i = 1; i < _content.childCount; i++) { childPosY += grid.cellSize.y + grid.spacing.y; _childrenPos.Add(childPosY); } } else { Debug.LogError("Vertical ScrollView is using HorizontalLayoutGroup."); } break; } } void Update() { if (_isCentering) { Vector3 v = _content.localPosition; switch (Dir) { case ScrollDir.Horizontal: v.x = Mathf.Lerp(_content.localPosition.x, _targetPos, MoveToCenterSpeed * Time.deltaTime); _content.localPosition = v; if (Math.Abs(_content.localPosition.x - _targetPos) < 0.01f) { _isCentering = false; } break; case ScrollDir.Vertical: v.y = Mathf.Lerp(_content.localPosition.y, _targetPos, MoveToCenterSpeed * Time.deltaTime); _content.localPosition = v; if (Math.Abs(_content.localPosition.y - _targetPos) < 0.01f) { _isCentering = false; } break; } } } public void OnDrag(PointerEventData eventData) { } public void OnEndDrag(PointerEventData eventData) { switch (Dir) { case ScrollDir.Horizontal: _targetPos = FindClosestChildPos(_content.localPosition.x, out _curCenterChildIndex); break; case ScrollDir.Vertical: _targetPos = FindClosestChildPos(_content.localPosition.y, out _curCenterChildIndex); break; } _isCentering = true; } public void OnBeginDrag(PointerEventData eventData) { _isCentering = false; _curCenterChildIndex = -1; } private float FindClosestChildPos(float currentPos, out int curCenterChildIndex) { float closest = 0; float distance = Mathf.Infinity; curCenterChildIndex = -1; for (int i = 0; i < _childrenPos.Count; i++) { float p = _childrenPos[i]; float d = Mathf.Abs(p - currentPos); if (d < distance) { distance = d; closest = p; curCenterChildIndex = i; } } return closest; } }
改完之后的效果:
-------------------------------------------------------------------
如果对您有帮助,请按下述操作:
请点击文章下方
请点击文章下方
请点击文章下方
请点击屏幕右下方
如果本文值得您分享,请点击文章下方
以上是关于Unity控件ScrollView使用问题记录的主要内容,如果未能解决你的问题,请参考以下文章
unity 如果用到ngui的scrollview控件需要特别注意啥
Unity基础控件Scroll View的使用,以及进度条不显示的问题