【NGUI】循环Scroll View

2015年03月19日 14:05 1 点赞 0 评论 更新于 2025-11-21 17:45

NGUI版本

本文使用的NGUI版本为3.0.9 f4。

脚本作用

此脚本的主要作用是使用10个甚至更少的item来模拟成百上千的item数据。在滑动过程中,当滑到Scroll View的最后面时,会将第一个item拿过来补位,此时需要正确设置补位item的数据;同理,当滑到最前面时,会用最后面的那个item过来补位。

实现方法

1. 脚本放置位置

将脚本放置在Scroll View下面的UIGrid的物体上。

2. UIScrollView设置

取消勾选UIScrollView的Restrict Within Panel选项。

3. UIPanel设置

勾选Scroll View上面的UIPanel的Cull选项。

4. Item设置

为每一个Item都添加一个UIWidget组件,并使用其Visiable属性将其调整到合适的大小。

5. 内容更新

本文仅提供实现循环Scroll View的思路,具体每个Item的内容更新等细节需要开发者自行研究。

6. 问题反馈

如果在实现过程中遇到问题,可以加群进行询问。

附代码

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

[RequireComponent(typeof(UIGrid))]
public class SZUILoopScrollView : MonoBehaviour {
// 前缀字符串,用于命名Item
public string perfix = string.Empty;

// 存储所有Item的UIWidget组件
private List<UIWidget> itemList = new List<UIWidget>();
// 位置参数,包含单元格宽度、高度以及排列方向信息
private Vector4 posParam;
// 缓存当前物体的Transform组件
private Transform cachedTransform;

void Awake() {
// 缓存当前物体的Transform组件
cachedTransform = this.transform;
// 获取UIGrid组件
UIGrid grid = this.GetComponent<UIGrid>();
// 获取单元格的宽度
float cellWidth = grid.cellWidth;
// 获取单元格的高度
float cellHeight = grid.cellHeight;

// 根据UIGrid的排列方式设置位置参数
posParam = new Vector4(cellWidth, cellHeight,
grid.arrangement == UIGrid.Arrangement.Horizontal ? 1 : 0,
grid.arrangement == UIGrid.Arrangement.Vertical ? 1 : 0);
}

void Start() {
// 遍历所有子物体
for (int i = 0; i < cachedTransform.childCount; ++i) {
// 获取子物体的Transform组件
Transform t = cachedTransform.GetChild(i);
// 获取子物体的UIWidget组件
UIWidget uiw = t.GetComponent<UIWidget>();
// 为UIWidget组件命名
uiw.name = string.Format("{0}_{1:D3}", perfix, itemList.Count);
// 将UIWidget组件添加到列表中
itemList.Add(uiw);
}
}

void LateUpdate() {
// 确保至少有两个Item
if (itemList.Count > 1) {
int sourceIndex = -1;
int targetIndex = -1;
int sign = 0;

// 判断第一个Item是否可见
bool firstVislable = itemList[0].isVisible;
// 判断最后一个Item是否可见
bool lastVislable = itemList[itemList.Count - 1].isVisible;

// 如果第一个和最后一个Item的可见性相同,则不进行处理
if (firstVislable == lastVislable) {
return;
}

if (firstVislable) {
// 如果第一个Item可见,将最后一个Item移动到第一个位置
sourceIndex = itemList.Count - 1;
targetIndex = 0;
sign = -1;
} else if (lastVislable) {
// 如果最后一个Item可见,将第一个Item移动到最后一个位置
sourceIndex = 0;
targetIndex = itemList.Count - 1;
sign = 1;
}

// 如果需要移动Item
if (sourceIndex > -1) {
// 获取需要移动的UIWidget组件
UIWidget movedWidget = itemList[sourceIndex];
// 计算移动的偏移量
Vector3 offset = new Vector3(sign * posParam.x * posParam.z, sign * posParam.y * posParam.w, 0);
// 设置移动后的位置
movedWidget.cachedTransform.localPosition = itemList[targetIndex].cachedTransform.localPosition + offset;
// 从列表中移除需要移动的Item
itemList.RemoveAt(sourceIndex);
// 将移动的Item插入到目标位置
itemList.Insert(targetIndex, movedWidget);
}
}
}
}

作者信息

menghao

menghao

共发布了 3994 篇文章