素材巴巴 > 程序开发 >

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

程序开发 2023-09-15 13:13:30

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

今天是头一次接触到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 m_childrenPos = new List();
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();
m_grid = this.transform.FindChild("Viewport/Content/Grid").GetComponent();
m_scrollview = GetComponent();
}
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().rect.width;
m_content.sizeDelta = new Vector2((m_onesizeX+ m_interval)* m_childcount- m_scrollviewRect, m_onesizeY);
}
else
{
m_scrollviewRect = this.transform.GetComponent().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;
}
}
}
}
}

 脚本主要用法

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

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

 

转载于:https://www.cnblogs.com/zhanghebk/p/6720376.html


标签:

素材巴巴 Copyright © 2013-2021 http://www.sucaibaba.com/. Some Rights Reserved. 备案号:备案中。