使用简单对象池做一个滚动界面

       之所以产生这个需求,是因为有些滚动面板里面的内容过多,会出现开始实例化的时候时间过长造成卡顿,且 DrawCall暴增。所以解决方案是只实例化出当前能显示的数目多一行, 然后动态设置内容的位置。

        

昨晚上尝试做一个Demo,但是失败了,主要是复用的内容位置的计算移动比较麻烦,感觉代价太大了。因为这样做的目的主要是为了解决初始化的时候实例对象太多,造成卡顿,和DrawCall的增加, 后面想一个折中的办法,就是界面初始化的时候只实例化当前界面所能显示的内容,其他的延迟显示。但是这方法感觉太别扭了,然后在网上找,已经有人做出来了。待会贴上来

见过很多版本,这个是最完美的版本。感谢作者:http://blog.csdn.net/mutou_222/article/details/50455729?ref=myread


暑假的时候参照NGUI的循环ScrollView的思路写的,当时给上传到了资源下载频道,因为平时自己也要在CSDN下东西,有些资源要积分才能下载,所以就挂了3分,想着供自己以后下载可以用。到现在也过了将近半年的时间了,去看了下也有近100次的下载量了。

自己平时上来CSDN比较少,写文章就更少了,再加上文笔真的是太烂了,人又懒。。。公司里一直都用的NGUI,自己也很久没有去碰过UGUI了,今天再打开这个工程,发现好多地方都不熟悉了啊,想想果然还是需要记录一下的,今天打开代码又看了几遍,理理思路。


主要就几个函数。

这个函数主要就是获取各个对象引用还有计算ScrollRect的四角坐标

设置mRTrans.pivot的目的是,如果按照默认的pivot在中心也就是(0.5,0.5)的话,当Item的项数量增多时Item的会向两段延伸,但是需要的是向一端延伸,如果有Item增加进来只需要加载末尾就好了而前面的Item不动。所以需要设置pivot在一端而不是在中心,那么在延伸尺寸的时候只会向另一端延伸。


[csharp]  view plain  copy
  1. void InitValue()  
  2. {  
  3.     if (ConstraintCount <= 0)<span style="white-space:pre">    </span>//ConstraintCount表示横纵排列的个数 若是横向排列 就表示行数 纵向排列就表示列数  
  4.         ConstraintCount = 1;  
  5.     if (minIndex > maxIndex) minIndex = maxIndex;  
  6.   
  7.     mTrans = transform;  
  8.     mRTrans = transform.GetComponent<RectTransform>();  
  9.     mScroll = transform.parent.GetComponent<ScrollRect>();  
  10.     mHorizontal = mScroll.horizontal;  
  11.       
  12.     SR_size =transform.parent.GetComponent<RectTransform>().rect.size;  
  13.   
  14.     //四角坐标  横着数  
  15.     conners[0] = new Vector3(-SR_size.x / 2f, SR_size.y / 2f,0);<span style="white-space:pre">    </span>//这里主要是计算一下ScrollRect 四个角的坐标 后面计算各个Item的坐标要用到  
  16.     conners[1] = new Vector3(SR_size.x / 2f, SR_size.y / 2f,0);  
  17.     conners[2] = new Vector3(-SR_size.x / 2f, -SR_size.y / 2f,0);  
  18.     conners[3] = new Vector3(SR_size.x / 2f, -SR_size.y / 2f,0);  
  19.     for (int i = 0; i < 4; i++)//将四角坐标转换为世界坐标  
  20.     {   
  21.         Vector3 temp = transform.parent.TransformPoint(conners[i]);  
  22.         conners[i].x = temp.x;  
  23.         conners[i].y = temp.y;  
  24.     }  
  25.   
  26.     mRTrans.pivot = new Vector2(0, 1);//设置panel的中心在左上角  
  27.       
  28.     mScroll.onValueChanged.AddListener(delegate { WrapContent(); });//添加滚动事件回调  
  29.     startPos = mTrans.localPosition;  
  30. }  

初始化的时候对Item进行一次排列

[csharp]  view plain  copy
  1. void ResetChildPosition()  
  2. {  
  3.     int rows = 1, cols = 1;  
  4.   
  5.     Vector2 startAxis = new Vector2(cell_x / 2f, -cell_y / 2f);//起始位置  按照Item尺寸计算第一个Item排列的初始位置  
  6.   
  7.   
  8.     int imax = mChild.Count;//Item元素数量  
  9.   
  10.     //初始化行列数 <span style="font-family: Arial, Helvetica, sans-serif;">根据排列方式计算行数和列数    </span>  
  11.   
  12.     if (arrangeType == ArrangeType.Vertical) //垂直排列 则适应行数    
  13.     {  
  14.         rows = ConstraintCount;  
  15.         cols = (int)Mathf.Ceil((float)imax / (float)rows);  
  16.   
  17.         extents = (float)(cols * cell_x) * 0.5f; //extents是预设置的所有Item所占的长度或高度的一半 用在循环的时候计算Item的坐标  
  18.     }  
  19.     else if (arrangeType == ArrangeType.Horizontal) //水平排列则适应列数  
  20.     {  
  21.         cols = ConstraintCount;  
  22.         rows = (int)Mathf.Ceil((float)imax / (float)cols);  
  23.         extents = (float)(rows * cell_y) * 0.5f;  
  24.     }  
  25.   
  26.     for (int i = 0; i < imax; i++)//对Item进行一次排列  
  27.     {  
  28.         Transform temp = mChild[i];  
  29.   
  30.         int x = 0, y = 0;//行列号  
  31.         if (arrangeType == ArrangeType.Horizontal) { x = i / cols; y = i % cols; }//根据Item的序号计算在排列中的行号和列号  
  32.         else if (arrangeType == ArrangeType.Vertical) { x = i % rows; y = i / rows; }  
  33.   
  34.   
  35.         temp.localPosition = new Vector2(startAxis.x + y * cell_x, startAxis.y - x * cell_y);  
  36.   
  37.         if (minIndex == maxIndex || (i >= minIndex && i <= maxIndex))  
  38.         {  
  39.             cullContent = true;  
  40.             temp.gameObject.SetActive(true);//若当前Item的序号在要显示的范围之内 则设置当前Item为可见 并更新Panel的尺寸以适应Item  
  41.   
  42.              UpdateRectsize(temp.localPosition);//更新panel的尺寸  
  43.   
  44.             UpdateItem(temp, i, i);  
  45.         }  
  46.         else            
  47.         {  
  48.             temp.gameObject.SetActive(false);  
  49.             cullContent = temp.gameObject.activeSelf;  
  50.         }//若预设值的Item的数量超过了 想要显示的Item数量 则隐藏所有超出的Item 并不再更新Panel的尺寸,设置cullContent为false,  
  51.                                             //因为 所有要显示的Item都已经包含在Panel的范围内了  
  52.   
  53.     }  
  54. }  



根据当前Item 的坐标来计算滚动到当前Item的序号
[csharp]  view plain  copy
  1. int getRealIndex(Vector2 pos)//计算realindex  
  2. {  
  3.     int x = (int)Mathf.Ceil(-pos.y / cell_y) - 1;//行号  
  4.     int y = (int)Mathf.Ceil(pos.x / cell_x) - 1;//列号  
  5.   
  6.     int realIndex;  
  7.     if (arrangeType == ArrangeType.Horizontal) realIndex = x * ConstraintCount + y;  
  8.     else realIndex = x + ConstraintCount * y;  
  9.   
  10.     return realIndex;  
  11.   
  12. }  

最主要的就是这个函数了,在ScrollRect的滚动的时候就会调用这个函数 ,每次滚动都会遍历一遍所有Item,计算它们的下标,坐标,设置是否显示等

[csharp]  view plain  copy
  1. void WrapContent()  
  2. {  
  3.   
  4.     Vector3[] conner_local = new Vector3[4];//mTrans是所有Item的父级,  
  5.     for (int i = 0; i < 4; i++)             //这里计算了ScrollRect即显示区域的中心坐标(用上面求得的四角坐标)  
  6.     {                                       //并转换为相对Item父级Panel的相对坐标  因为接下来将要计算各个Item的坐标,  
  7.          conner_local[i] = mTrans.InverseTransformPoint(conners[i]);//所以要设置坐标的参照相同  
  8.   
  9.     }  
  10.     //计算ScrollRect的中心坐标 相对于local的坐标  
  11.     Vector2 center = (conner_local[3] + conner_local[0]) / 2f;  
  12.   
  13.   
  14.     if (mHorizontal)//当排列方式是水平排列的时候  
  15.     {  
  16.   
  17.         float min = conner_local[0].x - cell_x;//显示区域用显示区域的左上角和右下角坐标计算显示区域的边界坐标   
  18.         float max = conner_local[3].x + cell_x;//考虑到会出现Item位于边界上 出现一般在区域内 一般在区域外的情况,//所以这里将显示边界向外扩展一个Item的尺寸  
  19.         for (int i = 0, imax = mChild.Count; i < imax; i++)//遍历所有Item   
  20.         {  
  21.             Transform temp = mChild[i];  
  22.             float distance = temp.localPosition.x - center.x;  
  23.             if (distance <-extents)//根据Item距离中心的距离是否超出显示范围(extents为前面求得的显示区域尺寸的一半) 判断是否应该重设Item的坐标  
  24.             {  
  25.                 Vector2 pos = temp.localPosition;  
  26.                 pos.x += extents * 2f;              //加一个显示尺寸,设置Item到列表末去   
  27.                 int realIndex = getRealIndex(pos);                  //根据更改后的坐标计算当前Item的序号   
  28.                 if (minIndex == maxIndex || (realIndex >= minIndex && realIndex < maxIndex))//若当前Item的序号在需要显示的范围内   
  29.                 {  
  30.                     UpdateRectsize(pos);                                                    //则重新设置Item的坐标和内容 并更新Panel的尺寸  
  31.                     temp.localPosition = pos; //设置Item内容  
  32.                     UpdateItem(temp, i, realIndex);  
  33.                 }  
  34.             }  
  35.             if (distance > extents)//向右滚动的情况   
  36.             {  
  37.                 Vector2 pos = temp.localPosition;  
  38.                 pos.x -= extents * 2f;  
  39.                 int realIndex = getRealIndex(pos);  
  40.                 if (minIndex == maxIndex || (realIndex >= minIndex && realIndex < maxIndex))  
  41.                 {  
  42.                     temp.localPosition = pos; //设置Item内容  
  43.                     UpdateItem(temp, i, realIndex);  
  44.                 }  
  45.             }  
  46.             if (cullContent)//设置裁剪部分是否隐藏或显示根据Item是否在显示边界内 控制是否显示或隐藏  
  47.             {  
  48.                 Vector2 pos=temp.localPosition;  
  49.                 temp.gameObject.SetActive((pos.x>min&&pos.x<max)?true:false);  
  50.             }  
  51.         }  
  52.     }  
  53.     else  
  54.     {  
  55.         float min = conner_local[3].y - cell_y;//显示区域   
  56.         float max = conner_local[0].y + cell_y;  
  57.         for (int i = 0, imax = mChild.Count; i < imax; i++)  
  58.         {  
  59.             Transform temp = mChild[i];  
  60.             float distance = temp.localPosition.y - center.y;  
  61.             if (distance < -extents)  
  62.             {  
  63.                 Vector2 pos = temp.localPosition;  
  64.                 pos.y += extents * 2f;  
  65.                 int realIndex = getRealIndex(pos);  
  66.                 if (minIndex == maxIndex || (realIndex >= minIndex && realIndex < maxIndex))  
  67.                 {  
  68.                     temp.localPosition = pos; //设置Item内容   
  69.                     UpdateItem(temp, i, realIndex);  
  70.                 }  
  71.             }  
  72.             if (distance > extents)  
  73.             {  
  74.                 Vector2 pos = temp.localPosition;  
  75.                 pos.y -= extents * 2f;  
  76.                 int x = (int)Mathf.Ceil(-pos.y / cell_y)-1;//行号   
  77.                 int y = (int)Mathf.Ceil(pos.x / cell_x)-1;//列号   
  78.                 int realIndex;  
  79.                 if (arrangeType == ArrangeType.Horizontal)  
  80.                     realIndex = x * ConstraintCount + y;  
  81.                 else realIndex = x + ConstraintCount * y;  
  82.                 if (minIndex == maxIndex || (realIndex >= minIndex && realIndex < maxIndex))  
  83.                 {  
  84.                     UpdateRectsize(pos);  
  85.                     temp.localPosition = pos; //设置Item内容  
  86.                     UpdateItem(temp, i, realIndex);  
  87.                 }  
  88.             }  
  89.             if (cullContent)//设置裁剪部分是否隐藏   
  90.             {  
  91.                 Vector2 pos = temp.localPosition;  
  92.                 temp.gameObject.SetActive((pos.y > min && pos.y < max) ? true : false);  
  93.             }  
  94.         }  
  95.     }  
  96. }  





 

完整代码

[csharp]  view plain  copy
  1. using UnityEngine;  
  2. using System.Collections;  
  3. using System.Collections.Generic;  
  4. using UnityEngine.UI;  
  5.   
  6. [ExecuteInEditMode]  
  7. public class GridAndLoop : MonoBehaviour  
  8. {  
  9.   
  10.     /// <summary>  
  11.     /// 设置Item内容的委托  
  12.     /// </summary>  
  13.     /// <param name="item">Item对象</param>  
  14.     /// <param name="wrapIndex">Item在Grid中的序号</param>  
  15.     /// <param name="realIndex">当前Item在List中的序号</param>  
  16.     public delegate void OnInitializeItem(GameObject item, int wrapIndex, int realIndex);  
  17.   
  18.     /// <summary>  
  19.     /// 排列方式枚举  
  20.     /// </summary>  
  21.     public enum ArrangeType  
  22.     {  
  23.         Horizontal=0,//水平排列  
  24.         Vertical=1,//垂直排列  
  25.     }  
  26.   
  27.   
  28.     /// <summary>  
  29.     /// Item的尺寸  
  30.     /// </summary>  
  31.     public int cell_x = 100, cell_y = 100;  
  32.   
  33.     /// <summary>  
  34.     /// 是否隐藏裁剪部分  
  35.     /// </summary>  
  36.     public bool cullContent = true;  
  37.   
  38.     /// <summary>  
  39.     /// Item最小序号  
  40.     /// </summary>  
  41.     public int minIndex = 0;  
  42.   
  43.     /// <summary>  
  44.     /// Item最大序号  
  45.     /// </summary>  
  46.     public int maxIndex = 0;  
  47.   
  48.     /// <summary>  
  49.     /// 排列方式  
  50.     /// </summary>  
  51.     public ArrangeType arrangeType=ArrangeType.Horizontal;  
  52.   
  53.     /// <summary>  
  54.     /// 行列个数 0表示1列  
  55.     /// </summary>  
  56.     public int ConstraintCount = 0;  
  57.   
  58.     /// <summary>  
  59.     /// 设置Item的委托  
  60.     /// </summary>  
  61.     public OnInitializeItem onInitializeItem;  
  62.   
  63.     /// <summary>  
  64.     ///当前对象  
  65.     /// </summary>  
  66.     Transform mTrans;  
  67.   
  68.     /// <summary>  
  69.     /// 当前RectTransform对象  
  70.     /// </summary>  
  71.     RectTransform mRTrans;  
  72.   
  73.     /// <summary>  
  74.     /// ScrollRect  
  75.     /// </summary>  
  76.     ScrollRect mScroll;  
  77.   
  78.       
  79.     /// <summary>  
  80.     /// 滚动方向  
  81.     /// </summary>  
  82.     bool mHorizontal;  
  83.     /// <summary>  
  84.     /// 元素链表  
  85.     /// </summary>  
  86.     List<Transform> mChild=new List<Transform>();  
  87.    
  88.     /// <summary>  
  89.     /// 显示区域长度或高度的一半  
  90.     /// </summary>  
  91.     float extents=0;  
  92.      
  93.     Vector2 SR_size = Vector2.zero;//SrollRect的尺寸  
  94.     Vector3[] conners = new Vector3[4];//ScrollRect四角的世界坐标   
  95.     Vector2 startPos;//ScrollRect的初始位置  
  96.     void Start()  
  97.     {  
  98.         InitList();   
  99.     }  
  100.       
  101.     int sortByName(Transform a, Transform b) { return string.Compare(a.name, b.name); }  
  102.   
  103.       
  104.     /// <summary>  
  105.     /// 初始化mChild链表  
  106.     /// </summary>  
  107.     void InitList()  
  108.     {  
  109.         int i,ChildCount;  
  110.         InitValue();  
  111.         mChild.Clear();  
  112.   
  113.         for (i = 0, ChildCount = mTrans.childCount; i < ChildCount; i++)  
  114.             mChild.Add(mTrans.GetChild(i));  
  115.   
  116.         ResetChildPosition();  
  117.    //     mChild.Sort(sortByName);//按照Item名字排序   
  118.   
  119.     }  
  120.   
  121.     void InitValue()  
  122.     {  
  123.         if (ConstraintCount <= 0)  
  124.             ConstraintCount = 1;  
  125.         if (minIndex > maxIndex) minIndex = maxIndex;  
  126.   
  127.         mTrans = transform;  
  128.         mRTrans = transform.GetComponent<RectTransform>();  
  129.         mScroll = transform.parent.GetComponent<ScrollRect>();  
  130.         mHorizontal = mScroll.horizontal;  
  131.           
  132.         SR_size =transform.parent.GetComponent<RectTransform>().rect.size;  
  133.   
  134.         //四角坐标  横着数  
  135.         conners[0] = new Vector3(-SR_size.x / 2f, SR_size.y / 2f,0);  
  136.         conners[1] = new Vector3(SR_size.x / 2f, SR_size.y / 2f,0);  
  137.         conners[2] = new Vector3(-SR_size.x / 2f, -SR_size.y / 2f,0);  
  138.         conners[3] = new Vector3(SR_size.x / 2f, -SR_size.y / 2f,0);  
  139.         for (int i = 0; i < 4; i++)  
  140.         {   
  141.             Vector3 temp = transform.parent.TransformPoint(conners[i]);  
  142.             conners[i].x = temp.x;  
  143.             conners[i].y = temp.y;  
  144.         }  
  145.   
  146.         mRTrans.pivot = new Vector2(0, 1);//设置panel的中心在左上角  
  147.           
  148.         mScroll.onValueChanged.AddListener(delegate { WrapContent(); });//添加滚动事件回调  
  149.         startPos = mTrans.localPosition;  
  150.     }  
  151.      
  152.     //初始化各Item的坐标  
  153.     [ContextMenu("RePosition")]  
  154.     public virtual void RePosition()  
  155.     {  
  156.         InitList();  
  157.     }  
  158.   
  159.       
  160.     void Update()  
  161.     {  
  162.         if (Application.isPlaying) enabled = false;  
  163.         RePosition();  
  164.           
  165.     }  
  166.   
  167.     void ResetChildPosition()  
  168.     {  
  169.         int rows=1, cols=1;  
  170.   
  171.         Vector2 startAxis = new Vector2(cell_x/2f,-cell_y/2f);//起始位置  
  172.         int i;  
  173.           
  174.         int imax = mChild.Count;//Item元素数量  
  175.           
  176.         //初始化行列数  
  177.         if (arrangeType == ArrangeType.Vertical) //垂直排列 则适应行数  
  178.         {   
  179.             rows = ConstraintCount;  
  180.             cols = (int)Mathf.Ceil((float)imax/(float)rows);  
  181.               
  182.             extents = (float)(cols  * cell_x)* 0.5f;   
  183.         }  
  184.         else if (arrangeType == ArrangeType.Horizontal) //水平排列则适应列数  
  185.         {   
  186.             cols = ConstraintCount;   
  187.             rows = (int)Mathf.Ceil((float)imax / (float)cols);   
  188.             extents = (float)(rows *  cell_y)* 0.5f;   
  189.         }  
  190.           
  191.         for (i = 0; i < imax; i++)  
  192.         {  
  193.             Transform temp = mChild[i];  
  194.   
  195.             int x=0,y=0;//行列号  
  196.             if (arrangeType == ArrangeType.Horizontal) { x = i / cols; y = i % cols; }  
  197.             else if (arrangeType == ArrangeType.Vertical) { x = i % rows; y = i / rows; }  
  198.   
  199.   
  200.             temp.localPosition = new Vector2(startAxis.x + y * cell_x, startAxis.y - x * cell_y);  
  201.   
  202.             if (minIndex == maxIndex || (i >= minIndex && i <= maxIndex))  
  203.             {  
  204.                 cullContent = true;  
  205.                 temp.gameObject.SetActive(true);  
  206.                 UpdateRectsize(temp.localPosition);//更新panel的尺寸  
  207.   
  208.                 UpdateItem(temp, i, i);  
  209.             }  
  210.             else  
  211.             {  
  212.                 temp.gameObject.SetActive(false);  
  213.                 cullContent =temp.gameObject.activeSelf;//如果预制Item数超过maxIndex则将超过部分隐藏 并 设置cullCintent为ufalse 并且不再更新 panel尺寸  
  214.             }  
  215.               
  216.               
  217.   
  218.         }  
  219.     }  
  220.   
  221.     /// <summary>  
  222.     /// ScrollRect复位  
  223.     /// </summary>  
  224.    public void ResetPosition()  
  225.    {  
  226.        mTrans.localPosition = startPos;  
  227.    }  
  228.   
  229.     /// <summary>  
  230.     /// 更新panel的尺寸  
  231.     /// </summary>  
  232.     /// <param name="pos"></param>  
  233.     void UpdateRectsize(Vector2 pos)  
  234.     {  
  235.   
  236.           
  237.         if (arrangeType == ArrangeType.Vertical)  
  238.         {  
  239.               
  240.          //   if(mRTrans.rect.width<pos.x+cell_x)  
  241.             mRTrans.sizeDelta = new Vector2(pos.x + cell_x, ConstraintCount*cell_y);  
  242.         }  
  243.         else  
  244.         {  
  245.              
  246.          //   if(mRTrans.rect.height<-pos.y+cell_y)  
  247.             mRTrans.sizeDelta = new Vector2(ConstraintCount * cell_x, -pos.y + cell_y);  
  248.         }  
  249.     }  
  250.     //Vector2 calculatePos(Vector2 world,Vector2 target,Vector2 lcal)  
  251.     //{  
  252.     //    Vector2 temp = world - target;  
  253.     //    temp.x /= (target.x/lcal.x);  
  254.     //    temp.y /= (target.y/lcal.y);  
  255.           
  256.     //    return temp;  
  257.     //}  
  258.     int getRealIndex(Vector2 pos)//计算realindex  
  259.     {  
  260.         int x = (int)Mathf.Ceil(-pos.y / cell_y) - 1;//行号  
  261.         int y = (int)Mathf.Ceil(pos.x / cell_x) - 1;//列号  
  262.   
  263.         int realIndex;  
  264.         if (arrangeType == ArrangeType.Horizontal) realIndex = x * ConstraintCount + y;  
  265.         else realIndex = x + ConstraintCount * y;  
  266.   
  267.         return realIndex;  
  268.   
  269.     }  
  270.   
  271.   
  272.     void WrapContent()  
  273.     {  
  274.   
  275.         Vector3[] conner_local = new Vector3[4];  
  276.         for (int i = 0; i < 4; i++)  
  277.         {  
  278.   
  279.             conner_local[i]=mTrans.InverseTransformPoint(conners[i]);  
  280.    
  281.         }  
  282.         //计算ScrollRect的中心坐标 相对于this的坐标  
  283.         Vector2 center = (conner_local[3] + conner_local[0]) / 2f;  
  284.        
  285.   
  286.         if (mHorizontal)  
  287.         {  
  288.               
  289.             float min = conner_local[0].x - cell_x;//显示区域  
  290.             float max = conner_local[3].x + cell_x;  
  291.             for (int i = 0, imax = mChild.Count; i < imax; i++)  
  292.             {  
  293.                 Transform temp = mChild[i];  
  294.                 float distance = temp.localPosition.x - center.x;  
  295.                   
  296.                 if (distance <-extents)  
  297.                 {  
  298.                      
  299.                     Vector2 pos = temp.localPosition;  
  300.                     pos.x += extents * 2f;  
  301.   
  302.                     int realIndex = getRealIndex(pos);  
  303.   
  304.                     if (minIndex == maxIndex || (realIndex >= minIndex && realIndex < maxIndex))  
  305.                     {      
  306.                         UpdateRectsize(pos);  
  307.                         temp.localPosition = pos;  
  308.                         //设置Item内容  
  309.                         UpdateItem(temp, i, realIndex);         
  310.                     }  
  311.                       
  312.                 }  
  313.   
  314.                 if (distance > extents)  
  315.                 {  
  316.                     Vector2 pos = temp.localPosition;  
  317.                     pos.x -= extents * 2f;  
  318.   
  319.                     int realIndex = getRealIndex(pos);  
  320.   
  321.                     if (minIndex == maxIndex || (realIndex >= minIndex && realIndex < maxIndex))  
  322.                     {        
  323.                         temp.localPosition = pos;  
  324.                         //设置Item内容  
  325.                         UpdateItem(temp, i, realIndex);                  
  326.                     }   
  327.                 }  
  328.   
  329.                 if (cullContent)//设置裁剪部分是否隐藏  
  330.                 {  
  331.                     Vector2 pos=temp.localPosition;  
  332.                     temp.gameObject.SetActive((pos.x>min&&pos.x<max)?true:false);  
  333.                 }  
  334.       
  335.             }  
  336.         }  
  337.         else   
  338.         {  
  339.             float min = conner_local[3].y - cell_y;//显示区域  
  340.             float max = conner_local[0].y + cell_y;  
  341.             for (int i = 0, imax = mChild.Count; i < imax; i++)  
  342.             {  
  343.                 Transform temp = mChild[i];  
  344.                 float distance = temp.localPosition.y - center.y;  
  345.   
  346.                 if (distance < -extents)  
  347.                 {  
  348.                      
  349.                     Vector2 pos = temp.localPosition;  
  350.                     pos.y += extents * 2f;  
  351.   
  352.                     int realIndex = getRealIndex(pos);  
  353.   
  354.                     if (minIndex == maxIndex || (realIndex >= minIndex && realIndex < maxIndex))  
  355.                     {  
  356.                          
  357.                         temp.localPosition = pos;  
  358.   
  359.                         //设置Item内容  
  360.                         UpdateItem(temp, i, realIndex);  
  361.                     }  
  362.                 }  
  363.   
  364.                 if (distance > extents)  
  365.                 {  
  366.                       
  367.                     Vector2 pos = temp.localPosition;  
  368.                     pos.y -= extents * 2f;  
  369.   
  370.                     int x = (int)Mathf.Ceil(-pos.y / cell_y)-1;//行号  
  371.                     int y = (int)Mathf.Ceil(pos.x / cell_x)-1;//列号  
  372.                      
  373.                     int realIndex;  
  374.                     if (arrangeType == ArrangeType.Horizontal) realIndex = x * ConstraintCount + y;  
  375.                     else realIndex = x + ConstraintCount * y;  
  376.                       
  377.                     if (minIndex == maxIndex || (realIndex >= minIndex && realIndex < maxIndex))  
  378.                     {  
  379.                         UpdateRectsize(pos);  
  380.   
  381.                         temp.localPosition = pos;  
  382.   
  383.                         //设置Item内容  
  384.                         UpdateItem(temp, i, realIndex);  
  385.                     }  
  386.                       
  387.                 }  
  388.                 if (cullContent)//设置裁剪部分是否隐藏  
  389.                 {  
  390.                     Vector2 pos = temp.localPosition;  
  391.                     temp.gameObject.SetActive((pos.y > min && pos.y < max) ? true : false);  
  392.                 }  
  393.   
  394.             }  
  395.         }  
  396.          
  397.     }  
  398.   
  399.     void UpdateItem(Transform item,int index,int realIndex)//跟新Item的内容  
  400.     {  
  401.         if (onInitializeItem != null)  
  402.         {  
  403.             onInitializeItem(item.gameObject, index, realIndex);  
  404.         }  
  405.     }  
  406.       
  407. }  

效果截图


我的例子的下载地址

http://download.csdn.net/detail/mutou_222/9015017


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值