UGUI 列表循环使用
发布日期:2021-06-30 19:39:17 浏览次数:2 分类:技术文章

本文共 11648 字,大约阅读时间需要 38 分钟。

直接上效果

脚本UGUIWrapContent.cs

/// /// 循环利用列表子项/// Author: LXF/// using UnityEngine;using System.Collections;using UnityEngine.UI;using System.Collections.Generic;[RequireComponent(typeof(GridLayoutGroup))]public class UGUIWrapContent : MonoBehaviour{    protected void Awake()    {        m_hasInit = false;        m_realChildObjCnt = 0;        m_realIndex = -1;        m_realIndexUp = -1;        m_selfTrans = transform;        m_childsAnchoredPos = new Dictionary
(); m_childsSiblingIndex = new Dictionary
(); m_childrenRectTransList = new List
(); } IEnumerator InitChildren() { yield return 0; bool needReDraw = false; if (!m_hasInit) { FirstTimeInit(); needReDraw = true; } else { bool needReLocate = false; if (m_realChildObjCnt >= m_dataChildCnt) { needReDraw = true; needReLocate = true; } if (needReLocate) { ResetChildrenPos(); } } if (needReDraw) { ReDrawChildren(); } } private void FirstTimeInit() { //获取Grid的宽度; m_rectTrans = GetComponent
(); m_gridLayoutGroup = GetComponent
(); m_gridLayoutGroup.enabled = false; m_gridLayoutPos = m_rectTrans.anchoredPosition; m_gridLayoutSize = m_rectTrans.sizeDelta; //注册ScrollRect滚动回调; if (null != m_scrollRect) m_scrollRect.onValueChanged.AddListener((data) => { ScrollCallback(data); }); else Debug.LogError("null == ScrollRect,请给脚本的ScrollRect赋值"); m_realChildObjCnt = m_selfTrans.childCount; //获取所有child anchoredPosition 以及 SiblingIndex; for (int index = 0, cnt = m_selfTrans.childCount; index < cnt; index++) { Transform child = m_selfTrans.GetChild(index); RectTransform childRectTrans = child.GetComponent
(); m_childsAnchoredPos.Add(child, childRectTrans.anchoredPosition); m_childsSiblingIndex.Add(child, child.GetSiblingIndex()); } } private void ResetChildrenPos() { m_rectTrans.anchoredPosition = m_gridLayoutPos; m_rectTrans.sizeDelta = m_gridLayoutSize; m_childrenRectTransList.Clear(); m_realIndex = -1; m_realIndexUp = -1; //children重新设置上下顺序; foreach (var info in m_childsSiblingIndex) { info.Key.SetSiblingIndex(info.Value); } //children重新设置anchoredPosition; for (int index = 0; index < m_selfTrans.childCount; index++) { Transform child = m_selfTrans.GetChild(index); RectTransform childRectTrans = child.GetComponent
(); if (m_childsAnchoredPos.ContainsKey(child)) { childRectTrans.anchoredPosition = m_childsAnchoredPos[child]; } else { Debug.LogError("childsAnchoredPosition no contain " + child.name); } } } private void ReDrawChildren() { //获取所有child; for (int index = 0; index < m_selfTrans.childCount; index++) { Transform trans = m_selfTrans.GetChild(index); trans.gameObject.SetActive(true); m_childrenRectTransList.Add(m_selfTrans.GetChild(index).GetComponent
()); //初始化前面几个; UpdateChildrenCallback(m_childrenRectTransList.Count - 1, m_selfTrans.GetChild(index)); } m_startPos = m_rectTrans.anchoredPosition; m_realIndex = m_childrenRectTransList.Count - 1; m_hasInit = true; //如果需要显示的个数小于设定的个数; for (int index = 0; index < m_realChildObjCnt; index++) { m_childrenRectTransList[index].gameObject.SetActive(index < m_dataChildCnt); } if (m_gridLayoutGroup.constraint == GridLayoutGroup.Constraint.FixedColumnCount) { //如果小了一行,则需要把GridLayout的高度减去一行的高度; int row = m_realChildObjCnt - m_dataChildCnt; if (row > 0) { m_rectTrans.sizeDelta -= new Vector2(0, (m_gridLayoutGroup.cellSize.y + m_gridLayoutGroup.spacing.y) * row); } } else { //如果小了一列,则需要把GridLayout的宽度减去一列的宽度; int column = m_realChildObjCnt - m_dataChildCnt; if (column > 0) { m_rectTrans.sizeDelta -= new Vector2((m_gridLayoutGroup.cellSize.x + m_gridLayoutGroup.spacing.x) * column, 0); } } } void ScrollCallback(Vector2 data) { UpdateChildren(); } void UpdateChildren() { if (m_selfTrans.childCount < m_realChildObjCnt) { return; } Vector2 currentPos = m_rectTrans.anchoredPosition; if (m_gridLayoutGroup.constraint == GridLayoutGroup.Constraint.FixedColumnCount) { float offsetY = currentPos.y - m_startPos.y; if (offsetY > 0) { if (!OnMoveUp(currentPos)) return; } else { //向下拉,下面收缩; if (!OnMoveDown(currentPos)) return; } } else { float offsetX = currentPos.x - m_startPos.x; if (offsetX < 0) { //向左拉,向右扩展; if (!OnMoveLeft(currentPos)) return; } else { //向右拉,右边收缩; if (!OnMoveRight(currentPos)) return; } } m_startPos = currentPos; } private bool OnMoveUp(Vector2 currentPos) { //向上拉,向下扩展; if (m_realIndex >= m_dataChildCnt - 1) { m_startPos = currentPos; return false; } float scrollRectUp = m_scrollRect.transform.TransformPoint(Vector3.zero).y; var topChild = m_childrenRectTransList[0]; var bottomChild = m_childrenRectTransList[m_childrenRectTransList.Count - 1]; Vector3 childBottomLeft = new Vector3(topChild.anchoredPosition.x, topChild.anchoredPosition.y - m_gridLayoutGroup.cellSize.y, 0f); float childBottom = m_selfTrans.TransformPoint(childBottomLeft).y; if (childBottom >= scrollRectUp) { //移动到底部// topChild.SetAsLastSibling(); var posY = bottomChild.anchoredPosition.y - m_gridLayoutGroup.cellSize.y - m_gridLayoutGroup.spacing.y; topChild.anchoredPosition = new Vector2(topChild.anchoredPosition.x, posY); m_realIndex++; if (m_realIndex > m_dataChildCnt - 1) { topChild.gameObject.SetActive(false); } else { UpdateChildrenCallback(m_realIndex, topChild); } //GridLayoutGroup 底部加长; m_rectTrans.sizeDelta += new Vector2(0, m_gridLayoutGroup.cellSize.y + m_gridLayoutGroup.spacing.y); //更新child; RetTagChildren(); } return true; } private bool OnMoveDown(Vector2 currentPos) { if (m_realIndex + 1 <= m_childrenRectTransList.Count) { m_startPos = currentPos; return false; } RectTransform scrollRectTransform = m_scrollRect.GetComponent
(); Vector3 scrollRectAnchorBottom = new Vector3(0, -scrollRectTransform.rect.height - m_gridLayoutGroup.spacing.y, 0f); float scrollRectBottom = m_scrollRect.transform.TransformPoint(scrollRectAnchorBottom).y; var lastChild = m_childrenRectTransList[m_childrenRectTransList.Count - 1]; Vector2 childUpLeft = lastChild.anchoredPosition + new Vector2(0, m_gridLayoutGroup.cellSize.y); float childUp = m_selfTrans.TransformPoint(childUpLeft).y; if (childUp < scrollRectBottom) { //把底部的一行 移动到顶部 var childCnt = m_childrenRectTransList.Count; var bottomChild = m_childrenRectTransList[childCnt - 1]; var topChild = m_childrenRectTransList[0]; bottomChild.SetAsFirstSibling(); var posY = topChild.anchoredPosition.y + m_gridLayoutGroup.cellSize.y + m_gridLayoutGroup.spacing.y; bottomChild.anchoredPosition = new Vector2(bottomChild.anchoredPosition.x, posY); bottomChild.gameObject.SetActive(true); UpdateChildrenCallback(m_realIndex - childCnt, bottomChild); --m_realIndex; //GridLayoutGroup 底部缩短; m_rectTrans.sizeDelta -= new Vector2(0, m_gridLayoutGroup.cellSize.y + m_gridLayoutGroup.spacing.y); //更新child; RetTagChildren(); } return true; } private bool OnMoveLeft(Vector2 currentPos) { if (m_realIndex >= m_dataChildCnt - 1) { m_startPos = currentPos; return false; } float scrollRectLeft = m_scrollRect.transform.TransformPoint(Vector3.zero).x; var leftestChild = m_childrenRectTransList[0]; var leftestChildPos = leftestChild.anchoredPosition; var rightestChild = m_childrenRectTransList[m_childrenRectTransList.Count - 1]; Vector3 childBottomRight = new Vector3(leftestChildPos.x + m_gridLayoutGroup.cellSize.x, leftestChildPos.y, 0f); float childRight = m_selfTrans.TransformPoint(childBottomRight).x; if (childRight <= scrollRectLeft) { //移动到右边; leftestChild.SetAsLastSibling(); var posX = rightestChild.anchoredPosition.x + m_gridLayoutGroup.cellSize.x + m_gridLayoutGroup.spacing.x; leftestChild.anchoredPosition = new Vector2(posX, leftestChildPos.y); m_realIndex++; if (m_realIndex > m_dataChildCnt - 1) { leftestChild.gameObject.SetActive(false); } else { UpdateChildrenCallback(m_realIndex, m_childrenRectTransList[0]); } //GridLayoutGroup 右侧加长; m_rectTrans.sizeDelta += new Vector2(m_gridLayoutGroup.cellSize.x + m_gridLayoutGroup.spacing.x, 0); //更新child; RetTagChildren(); } return true; } private bool OnMoveRight(Vector2 currentPos) { if (m_realIndex + 1 <= m_childrenRectTransList.Count) { m_startPos = currentPos; return false; } var rightestChild = m_childrenRectTransList[m_childrenRectTransList.Count - 1]; var rightestChildPos = rightestChild.anchoredPosition; var leftestChild = m_childrenRectTransList[0]; RectTransform scrollRectTransform = m_scrollRect.GetComponent
(); Vector3 scrollRectAnchorRight = new Vector3(scrollRectTransform.rect.width + m_gridLayoutGroup.spacing.x, 0, 0f); float scrollRectRight = m_scrollRect.transform.TransformPoint(scrollRectAnchorRight).x; Vector2 childUpLeft = rightestChildPos - new Vector2(m_gridLayoutGroup.cellSize.x, 0); float childLeft = m_selfTrans.TransformPoint(childUpLeft).x; if (childLeft >= scrollRectRight) { //把右边的一行 移动到左边; rightestChild.SetAsFirstSibling(); var posX = leftestChild.anchoredPosition.x - m_gridLayoutGroup.cellSize.x - m_gridLayoutGroup.spacing.x; rightestChild.anchoredPosition = new Vector2(posX, rightestChildPos.y); rightestChild.gameObject.SetActive(true); UpdateChildrenCallback(m_realIndex - m_childrenRectTransList.Count, rightestChild); --m_realIndex; //GridLayoutGroup 右侧缩短; m_rectTrans.sizeDelta -= new Vector2(m_gridLayoutGroup.cellSize.x + m_gridLayoutGroup.spacing.x, 0); //更新child; RetTagChildren(); } return true; } private void RetTagChildren() { for (int index = 0, cnt = m_childrenRectTransList.Count; index < cnt; ++index) { var child = m_selfTrans.GetChild(index); m_childrenRectTransList[index] = child.GetComponent
(); } } void UpdateChildrenCallback(int index, Transform trans) { if (updateChildrenCallback != null) { updateChildrenCallback(index, trans); } } ///
/// 设置总的个数; /// ///
public void SetAmount(int count) { m_dataChildCnt = count; StartCoroutine(InitChildren()); } ///
/// 是否初始化过 /// private bool m_hasInit = false; ///
/// 实际的子项Obj数量 /// private int m_realChildObjCnt; ///
/// 数据子项数量 /// private int m_dataChildCnt; private RectTransform m_rectTrans; private Transform m_selfTrans; private GridLayoutGroup m_gridLayoutGroup; private List
m_childrenRectTransList; private Vector2 m_startPos; private int m_realIndex; private int m_realIndexUp; private Vector2 m_gridLayoutSize; private Dictionary
m_childsAnchoredPos; private Vector2 m_gridLayoutPos; private Dictionary
m_childsSiblingIndex; [SerializeField] private ScrollRect m_scrollRect; public delegate void UpdateChildrenCallbackDelegate(int index, Transform trans); public UpdateChildrenCallbackDelegate updateChildrenCallback = null;}
脚本ScrollListDrawer.cs

/// /// 列表子项画师/// Author: LXF/// using UnityEngine;using UnityEngine.UI;public class ScrollListDrawer : MonoBehaviour{    UGUIWrapContent infinityGridLayoutGroup;    int amount = 10;    void Start()    {        //初始化数据列表//        infinityGridLayoutGroup = transform.GetComponent
(); infinityGridLayoutGroup.SetAmount(amount); infinityGridLayoutGroup.updateChildrenCallback = UpdateChildrenCallback; } void OnGUI() { if (GUILayout.Button("Add one item")) { infinityGridLayoutGroup.SetAmount(++amount); } } void UpdateChildrenCallback(int index, Transform trans) { OnDraw(index, trans); } private void OnDraw(int index, Transform trans) { Text text = trans.Find("Text").GetComponent
(); text.text = index.ToString(); }}

转载地址:https://linxinfa.blog.csdn.net/article/details/70767777 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:使用命令行运行unity并执行某个静态函数(运用于命令行打包和批量打包)
下一篇:Unity 代码混淆: CodeGuard的使用

发表评论

最新留言

路过,博主的博客真漂亮。。
[***.116.15.85]2024年04月27日 14时25分26秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章