2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > UGUI 使用Scroll View滑动降content下的子UI排到中间位置

UGUI 使用Scroll View滑动降content下的子UI排到中间位置

时间:2023-02-28 05:07:39

相关推荐

UGUI 使用Scroll View滑动降content下的子UI排到中间位置

头一次写博客,希望大家多多关照

今天是头一次接触到UGUI,之前一直用的NGUI,发现ScrollView和Ngui的稍微有点不一样

简单的摆了一下,第一次用发现一个问题就是拖拽的时候有一些问题,于是在网上找了好久发现也没有这方面的问题,就是Scroll View下的Content不自动更新长度,

一定要记得content要和grid的下的全部的子UI长度一致,否则拖拽会有问题

下面这个脚本给大家分享一下是两个功能一个是自动适配content的长度,还有一个是滑动自动排到view中间位置

using UnityEngine;

using System.Collections;

using UnityEngine.UI;

using System.Collections.Generic;

using UnityEngine.EventSystems;

public enum Direction

{

Horizontal,

Vertical

}

public class ScrolContentSize : MonoBehaviour, IEndDragHandler, IDragHandler

{

#region 自动适配scrollview中的content

private RectTransform m_content;

private float m_interval = 10;

private GridLayoutGroup m_grid;

private int m_childcount;

private float m_onesizeX;

private float m_onesizeY;

float m_scrollviewRect;

#endregion

#region 滑动子UI到scrollview中间

private float m_contentSpeed = 15.0f;

private ScrollRect m_scrollview;

private List<float> m_childrenPos = new List<float>();

private float m_targetPos;

private bool m_centering = false;

#endregion

[SerializeField]

Direction m_direction;

private void Awake()

{

m_content = this.transform.Find("Viewport/Content").GetComponent<RectTransform>();

m_grid = this.transform.FindChild("Viewport/Content/Grid").GetComponent<GridLayoutGroup>();

m_scrollview = GetComponent<ScrollRect>();

}

private void OnEnable()

{

SetContentSize();

AddTotalGridChildrenPox();

}

void AddTotalGridChildrenPox()

{

m_childrenPos.Clear();

if (m_direction == Direction.Horizontal)

{

float childPosX = 0;

//减去child2个代表content要到达最后的坐标

for (int i = 0; i < m_grid.gameObject.transform.childCount-2; i++)

{

m_childrenPos.Add(childPosX);

childPosX -= m_grid.cellSize.x+ m_interval;

}

}

else

{

float childPosY = 0;

//减去child2个代表content要到达最后的坐标

for (int i = 0; i < m_grid.gameObject.transform.childCount - 2; i++)

{

m_childrenPos.Add(childPosY);

childPosY += m_grid.cellSize.y + m_interval;

}

}

}

void SetContentSize()

{

m_childcount = m_grid.gameObject.transform.childCount;

if (m_content != null && m_grid != null)

{

m_onesizeY = m_grid.cellSize.y;

m_onesizeX = m_grid.cellSize.x;

if (m_direction == Direction.Horizontal)

{

m_scrollviewRect = this.transform.GetComponent<RectTransform>().rect.width;

m_content.sizeDelta = new Vector2((m_onesizeX+ m_interval)* m_childcount- m_scrollviewRect, m_onesizeY);

}

else

{

m_scrollviewRect = this.transform.GetComponent<RectTransform>().rect.height;

m_content.sizeDelta = new Vector2(m_onesizeX- m_scrollviewRect, (m_onesizeY+ m_interval)*m_childcount);

}

}

}

public void OnEndDrag(PointerEventData eventData)

{

m_centering = true;

SetTargetPos();

}

public void OnDrag(PointerEventData eventData)

{

m_centering = false;

}

private void Update()

{

if (m_centering)

{

if (m_direction == Direction.Horizontal)

{

MoveHorizontal();

}

else

{

MoveVertical();

}

}

}

void MoveHorizontal()

{

Vector3 v = m_content.localPosition;

v.x = Mathf.Lerp(m_content.localPosition.x, m_targetPos, m_contentSpeed * Time.deltaTime);

m_content.localPosition = v;

if (Mathf.Abs(m_content.localPosition.x - m_targetPos) < 0.01f)

{

m_centering = false;

}

}

void MoveVertical()

{

Vector3 v = m_content.localPosition;

v.y = Mathf.Lerp(m_content.localPosition.y, m_targetPos, m_contentSpeed * Time.deltaTime);

m_content.localPosition = v;

if (Mathf.Abs(m_content.localPosition.y - m_targetPos) < 0.01f)

{

m_centering = false;

}

}

void SetTargetPos()

{

float contentPox = 0;

if (m_direction == Direction.Horizontal)

{

contentPox = m_content.localPosition.x;

for (int i = 0; i < m_childrenPos.Count; i++)

{

if (contentPox > 0)

{

m_targetPos = m_childrenPos[i];

return;

}

m_targetPos = m_childrenPos[i];

if (m_childrenPos.Count<=i+1)

{

return;

}

if (contentPox < m_targetPos&& contentPox > m_childrenPos[i+1])

{

float leftPos = m_targetPos;

float rightPos = m_childrenPos[i + 1];

//主要算法(判断拖拽contentPox坐标大于或小于left和right的中间,)

m_targetPos = leftPos-(m_grid.cellSize.x+m_interval)/2< contentPox?leftPos: rightPos;

//targetPos = rightPos;//轻轻拖一下就去到另一边

return;

}

}

}

else

{

contentPox = m_content.localPosition.y;

for (int i = 0; i < m_childrenPos.Count; i++)

{

if (contentPox<0)

{

m_targetPos = m_childrenPos[i];

Debug.Log(1);

return;

}

m_targetPos = m_childrenPos[i];

if (m_childrenPos.Count <= i + 1)

{

return;

}

if (contentPox > m_targetPos && contentPox < m_childrenPos[i + 1])

{

float leftPos = m_targetPos;

float rightPos = m_childrenPos[i + 1];

//主要算法(判断拖拽contentPox坐标大于或小于left和right的中间)

m_targetPos = leftPos + (m_grid.cellSize.y - m_interval) / 2 > contentPox ? leftPos : rightPos;

Debug.Log(m_targetPos);

return;

}

}

}

}

}

脚本主要用法

脚本的大致思路是记录位置,然后去寻找前后最近的那个位置,脚本改的位置已经写在脚本的注释里了

大家如果感觉有用欢迎大家点赞

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。