Unity之ScrollRect滑动居中
来源:互联网 发布:美国iea数据 编辑:程序博客网 时间:2024/05/17 00:09
先上效果图
这里同时支持水平方向和垂直方向,同时ScrollRect支持使用GridLayoutGroup、HorizontalLayoutGroup、VerticalLayoutGroup三种LayoutGroup,不过水平方向的ScrollRect不支持VerticalLayoutGroup,垂直方向的ScrollRect不支持HorizontalLayoutGroup,当然也不存在这两种情况。
由于这里是通过对ScrollRect的content的localPosition做了插值移动,因此ScrollRect的中心点设置必须跟我这保持一致。
下面直接上代码:
using System;using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.EventSystems;using UnityEngine.UI;public enum ScrollDir{ Horizontal, Vertical}public class ScrollRectCenter : MonoBehaviour , IEndDragHandler,IDragHandler,IBeginDragHandler{ public ScrollDir Dir = ScrollDir.Horizontal; /// <summary> /// 是否正在居中 /// </summary> private bool _isCentering = false; /// <summary> /// 居中过程移动速度 /// </summary> public float MoveToCenterSpeed = 10f; private ScrollRect _scrollView; private Transform _content; private List<float> _childrenPos = new List<float>(); private float _targetPos; /// <summary> /// 当前中心child索引 /// </summary> private int _curCenterChildIndex = -1; /// <summary> /// 当前中心ChildItem /// </summary> public GameObject CurCenterChildItem { get { GameObject centerChild = null; if (_content != null && _curCenterChildIndex >= 0 && _curCenterChildIndex < _content.childCount) { centerChild = _content.GetChild(_curCenterChildIndex).gameObject; } return centerChild; } } void Awake() { _scrollView = GetComponent<ScrollRect>(); if (_scrollView == null) { Debug.LogError("ScrollRect is null"); return; } _content = _scrollView.content; LayoutGroup layoutGroup = null; layoutGroup = _content.GetComponent<LayoutGroup>(); if (layoutGroup == null) { Debug.LogError("LayoutGroup component is null"); } _scrollView.movementType = ScrollRect.MovementType.Unrestricted; float spacing = 0f; //根据dir计算坐标,Horizontal:存x,Vertical:存y switch (Dir) { case ScrollDir.Horizontal: if (layoutGroup is HorizontalLayoutGroup) { float childPosX = _scrollView.GetComponent<RectTransform>().rect.width * 0.5f - GetChildItemWidth(0) * 0.5f; spacing = (layoutGroup as HorizontalLayoutGroup).spacing; _childrenPos.Add(childPosX); 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 = _scrollView.GetComponent<RectTransform>().rect.width * 0.5f - grid.cellSize.x * 0.5f; _childrenPos.Add(childPosX); for (int i = 0; i < _content.childCount - 1; i++) { childPosX -= grid.cellSize.x + grid.spacing.x; _childrenPos.Add(childPosX); } } else { Debug.LogError("Horizontal ScrollView is using VerticalLayoutGroup"); } break; case ScrollDir.Vertical: if (layoutGroup is VerticalLayoutGroup) { float childPosY = -_scrollView.GetComponent<RectTransform>().rect.height * 0.5f + GetChildItemHeight(0) * 0.5f; spacing = (layoutGroup as VerticalLayoutGroup).spacing; _childrenPos.Add(childPosY); 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 = -_scrollView.GetComponent<RectTransform>().rect.height * 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; } } 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 Start () { } 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; }}
最后附上Demo下载链接:
链接:http://pan.baidu.com/s/1pLoJcjL 密码:js7g
链接如果失效,请及时评论,及时更新
以上知识分享,如有错误,欢迎指出,共同学习,共同进步
阅读全文
0 0
- Unity之ScrollRect滑动居中
- Unity优化之ScrollRect
- UGUI ScrollRect滑动居中CenterOnChild实现(修改)
- UGUI之ScrollRect添加响应事件后不能滑动
- ScrollRect滑动优化(一)
- UGUI ScrollRect滑动定位优化
- UGUI ScrollRect滑动定位优化
- [Unity UGUI]ScrollRect效果大全
- UGUI之ScrollRect
- scrollRect
- Unity中ScrollRect锁定元素详述(一)
- Unity中ScrollRect锁定元素详述(二)
- Unity ScrollRect 实现垂直滚动文字
- unity UGUI scrollRect拖拽处理
- ScrollRect滑动优化(二)--动态创建Item列表
- Unity UGUI-ScrollRect的Mask 对动态字体无效
- unity中ScrollRect拖拽子物体无法拖拽
- 【Unity】优化UGUI 滚动条ScrollRect(高效复用)
- JavaScript进行Form表单验证
- 实例学习STL之队列
- 在windows2008上搭建Seafile开源网盘系统
- hdu1542线段树+离散化+扫描线详解
- LeetCode50 pow(x, n)
- Unity之ScrollRect滑动居中
- 系统学习java高并发系列二
- 1648: [Usaco2006 Dec]Cow Picnic 奶牛野餐
- 网络编程中对TCP协议和UDP协议的理解
- 深入分析 Java 方法反射的实现原理
- 学习Linux-4.12内核网路协议栈(1.8)——网络设备驱动模块的加载
- 你必须理解的计算机核心概念
- MYSQL之存储过程
- ArcGIS Engine 9.2 打开多波段栅格数据