参考链接: http://www.cnblogs.com/suoluo/p/5535420.html 实现代码:
using UnityEngine;using System.Collections;using UnityEngine.UI;using System.Collections.Generic;using UnityEngine.EventSystems;/// <summary>/// Vertical center on child./// 这里面我用的是VerticalLayoutGroup进行自动布局/// 用了ContentSizeFitter和LayoutElemen进行了自动填充的布局/// 这里面的居中计算是根据anchoredPosition3D来计算的/// </summary>public class VerticalCenterOnChild : MonoBehaviour , IDragHandler, IEndDragHandler{ //将子物体拉到中心位置时的速度 public float centerSpeed = 9f; //注册该事件获取当拖动结束时位于中心位置的子物体 public delegate void OnCenterHandler (GameObject centerChild); public event OnCenterHandler onCenter; PRivate ScrollRect _scrollView; private RectTransform _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; VerticalLayoutGroup grid; grid = _container.GetComponent<VerticalLayoutGroup> (); if (grid == null) { Debug.LogError ("CenterOnChild: No GridLayoutGroup on the ScrollRect's content"); return; } _scrollView.movementType = ScrollRect.MovementType.Unrestricted; //计算第一个子物体位于中心时anchoredPosition3D.y的值 float childPosy = _container.anchoredPosition3D.y; _childrenPos.Add (childPosy); //这里我用了LayoutElement来布局,获取item的高度(可以根据不同的布局情况来获item高度) float itemHeight = grid.GetComponentInChildren<LayoutElement>().preferredHeight; //往上移动,计算每个item居中时的pivot到anchors的距离 for (int i = 0; i < _container.childCount - 1; i++) { childPosy += itemHeight + grid.spacing; _childrenPos.Add (childPosy); } } void Update () { if (_centering) { Vector3 v = _container.anchoredPosition3D; v.y = Mathf.Lerp (_container.anchoredPosition3D.y, _targetPos, centerSpeed * Time.deltaTime); _container.anchoredPosition3D = v; if (Mathf.Abs (_container.anchoredPosition3D.y - _targetPos) < 0.01f) { _centering = false; } } } public void OnEndDrag (PointerEventData eventData) { _targetPos = FindClosestPos (_container.anchoredPosition3D.y); _centering = true; } public void OnDrag (PointerEventData eventData) { _centering = false; } //找到最近的点 private float FindClosestPos (float currentPos) { int childIndex = 0; float closest = 0; float distance = Mathf.Infinity; //与记录的四个位置对比 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; childIndex = i; } } GameObject centerChild = _container.GetChild (childIndex).gameObject; if (onCenter != null) onCenter (centerChild); return closest; }}同样的,如果要改成谁水方向的话,只需要改成水平布局,获取item的宽度,以及改变 _container.anchoredPosition3D.x就行,其他不变
新闻热点
疑难解答