平时需要做一些排行榜或者背包之类的功能时,就需要考虑生成物体的数量,因此普遍会用到对象池
这个组件就是生成一定数量的克隆体放入对象池中,使其循环利用,从而达到无限下拉的功能。
主要函数:
public virtual void Init(Action<GameObject, int> callBack, Action<GameObject, int> onClickCallBack)
{
DisposeAll();
m_FuncCallBackFunc = callBack;
if (onClickCallBack != null)
{
m_FuncOnClickCallBack = onClickCallBack;
}
if (m_isInited)
return;
m_Content = this.GetComponent<ScrollRect>().content.gameObject;
if (m_CellGameObject == null)
{
m_CellGameObject = m_Content.transform.GetChild(0).gameObject;
}
/* Cell 处理 */
//m_CellGameObject.transform.SetParent(m_Content.transform.parent, false);
SetPoolsObj(m_CellGameObject);
RectTransform cellRectTrans = m_CellGameObject.GetComponent<RectTransform>();
cellRectTrans.pivot = new Vector2(0f, 1f);
CheckAnchor(cellRectTrans);
cellRectTrans.anchoredPosition = Vector2.zero;
cellRectTrans.localPosition = new Vector3(0, 0, 0);
//记录 Cell 信息
m_CellObjectHeight = cellRectTrans.rect.height;
m_CellObjectWidth = cellRectTrans.rect.width;
//记录 Plane 信息
rectTrans = GetComponent<RectTransform>();
Rect planeRect = rectTrans.rect;
m_PlaneHeight = planeRect.height;
m_PlaneWidth = planeRect.width;
//记录 Content 信息
m_ContentRectTrans = m_Content.GetComponent<RectTransform>();
Rect contentRect = m_ContentRectTrans.rect;
m_ContentHeight = contentRect.height;
m_ContentWidth = contentRect.width;
m_ContentRectTrans.pivot = new Vector2(0f, 1f);
//m_ContentRectTrans.sizeDelta = new Vector2 (planeRect.width, planeRect.height);
//m_ContentRectTrans.anchoredPosition = Vector2.zero;
CheckAnchor(m_ContentRectTrans);
m_ScrollRect = this.GetComponent<ScrollRect>();
m_ScrollRect.onValueChanged.RemoveAllListeners();
//添加滑动事件
m_ScrollRect.onValueChanged.AddListener(delegate (Vector2 value) { ScrollRectListener(value); });
if (m_PointingFirstArrow != null || m_PointingEndArrow != null)
{
m_ScrollRect.onValueChanged.AddListener(delegate (Vector2 value) { OnDragListener(value); });
OnDragListener(Vector2.zero);
}
//InitScrollBarGameObject(); // 废弃
m_isInited = true;
}
public virtual void ShowList(int num)
{
m_MinIndex = -1;
m_MaxIndex = -1;
//-> 计算 Content 尺寸
if(m_Direction == e_Direction.Vertical)
{
float contentSize = (m_Spacing + m_CellObjectHeight) * Mathf.CeilToInt((float)num / m_Row);
m_ContentHeight = contentSize;
m_ContentWidth = m_ContentRectTrans.sizeDelta.x;
contentSize = contentSize < rectTrans.rect.height ? rectTrans.rect.height : contentSize;
m_ContentRectTrans.sizeDelta = new Vector2(m_ContentWidth, contentSize);
if (num != m_MaxCount)
{
m_ContentRectTrans.anchoredPosition = new Vector2(m_ContentRectTrans.anchoredPosition.x, 0);
}
}
else
{
float contentSize = (m_Spacing + m_CellObjectWidth) * Mathf.CeilToInt((float)num / m_Row);
m_ContentWidth = contentSize;
m_ContentHeight = m_ContentRectTrans.sizeDelta.x;
contentSize = contentSize < rectTrans.rect.width ? rectTrans.rect.width : contentSize;
m_ContentRectTrans.sizeDelta = new Vector2(contentSize, m_ContentHeight);
if (num != m_MaxCount)
{
m_ContentRectTrans.anchoredPosition = new Vector2(0, m_ContentRectTrans.anchoredPosition.y);
}
}
//-> 计算 开始索引
int lastEndIndex = 0;
//-> 过多的物体 扔到对象池 ( 首次调 ShowList函数时 则无效 )
if (m_IsInited)
{
lastEndIndex = num - m_MaxCount > 0 ? m_MaxCount : num;
lastEndIndex = m_IsClearList ? 0 : lastEndIndex;
int count = m_IsClearList ? m_CellInfos.Length : m_MaxCount;
for (int i = lastEndIndex; i < count; i++)
{
if (m_CellInfos[i].obj != null)
{
SetPoolsObj(m_CellInfos[i].obj);
m_CellInfos[i].obj = null;
}
}
}
//-> 以下四行代码 在for循环所用
CellInfo[] tempCellInfos = m_CellInfos;
m_CellInfos = new CellInfo[num];
//-> 1: 计算 每个Cell坐标并存储 2: 显示范围内的 Cell
for (int i = 0; i < num; i++)
{
// * -> 存储 已有的数据 ( 首次调 ShowList函数时 则无效 )
if (m_MaxCount != -1 && i < lastEndIndex)
{
CellInfo tempCellInfo = tempCellInfos[i];
//-> 计算是否超出范围
float rPos = m_Direction == e_Direction.Vertical ? tempCellInfo.pos.y : tempCellInfo.pos.x;
if (!IsOutRange(rPos))
{
//-> 记录显示范围中的 首位index 和 末尾index
m_MinIndex = m_MinIndex == -1 ? i : m_MinIndex; //首位index
m_MaxIndex = i; // 末尾index
if (tempCellInfo.obj == null)
{
tempCellInfo.obj = GetPoolsObj();
}
tempCellInfo.obj.transform.GetComponent<RectTransform>().anchoredPosition = tempCellInfo.pos;
tempCellInfo.obj.name = i.ToString();
tempCellInfo.obj.SetActive(true);
Func(m_FuncCallBackFunc, tempCellInfo.obj);
}
else
{
SetPoolsObj(tempCellInfo.obj);
tempCellInfo.obj = null;
}
m_CellInfos[i] = tempCellInfo;
continue;
}
CellInfo cellInfo = new CellInfo();
float pos = 0; //坐标( isVertical ? 记录Y : 记录X )
float rowPos = 0; //计算每排里面的cell 坐标
// * -> 计算每个Cell坐标
if(m_Direction == e_Direction.Vertical)
{
pos = m_CellObjectHeight * Mathf.FloorToInt(i / m_Row) + m_Spacing * Mathf.FloorToInt(i / m_Row);
rowPos = m_CellObjectWidth * (i % m_Row) + m_Spacing * (i % m_Row);
cellInfo.pos = new Vector3(rowPos, -pos, 0);
}
else
{
pos = m_CellObjectWidth * Mathf.FloorToInt(i / m_Row) + m_Spacing * Mathf.FloorToInt(i / m_Row);
rowPos = m_CellObjectHeight * (i % m_Row) + m_Spacing * (i % m_Row);
cellInfo.pos = new Vector3(pos, -rowPos, 0);
}
//-> 计算是否超出范围
float cellPos = m_Direction == e_Direction.Vertical ? cellInfo.pos.y : cellInfo.pos.x;
if (IsOutRange(cellPos))
{
cellInfo.obj = null;
m_CellInfos[i] = cellInfo;
continue;
}
//-> 记录显示范围中的 首位index 和 末尾index
m_MinIndex = m_MinIndex == -1 ? i : m_MinIndex; //首位index
m_MaxIndex = i; // 末尾index
//-> 取或创建 Cell
GameObject cell = GetPoolsObj();
cell.transform.GetComponent<RectTransform>().anchoredPosition = cellInfo.pos;
cell.gameObject.name = i.ToString();
//-> 存数据
cellInfo.obj = cell;
m_CellInfos[i] = cellInfo;
//-> 回调 函数
Func(m_FuncCallBackFunc, cell);
}
m_MaxCount = num;
m_IsInited = true;
OnDragListener(Vector2.zero);
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using CircularScrollView;
using UnityEngine.UI;
public class ScrollViewTestDemo : MonoBehaviour
{
public UICircularScrollView m_ScrollViewVer;
void Start()
{
InitScrollView();
}
//初始化
private void InitScrollView()
{
//注册事件
m_ScrollViewVer.Init(RegisterScrollView);
//初始化数量
m_ScrollViewVer.ShowList(100);
}
///
///
///
/// 注册的对象,游戏对象
/// 物体在列表序号
private void RegisterScrollView(GameObject go,int index)
{
go.transform.Find("Text").GetComponent<Text>().text = index.ToString();
}
}
下载链接:链接