• QQ
  • nahooten@sina.com
  • 常州市九洲新世界花苑15-2

游戏开发

常州手游开发-U3DUI WrapContent显示多行多列

原创内容,转载请注明原文网址:http://homeqin.cn/a/wenzhangboke/jishutiandi/youxikaifa/2019/0125/357.html

常州手游开发-NGUI WrapContent显示多行多列

 

在游戏中我们时常看到像背包一样用ScrollView来拖动展示一些物品信息,物品一多那么开始克隆的Item就会多这样使得开始打开界面时耗时长,而且在常州网站开发建设滑动的时候会出现卡顿,滑动不流畅,滑动卡顿的主要原因是我们未将移出UIScrollViewItem设为false,这会导致Panel在重建DrawCall是将所有的Item都算进来,这时在构建Mesh时会很耗时特别是Item比较多的时候,针对这两个问题我们可以用少量的Item循环使用来解决;NGUI本身就给我们提供了这个代码:UIWrapContent,具体用法NGUI有事例,但它们都是单行单列的,下面我们常州游戏开发运营就给大家介绍下如何使用UIWrapContent来展示多行多列。

 

 

这里循环使用15Item来显示0~31,拉到底时不能再往下或往上拉。

 

Ok,进入主题,下面来说说我的做法,先来看看下面代码:

 

using UnityEngine;

public class MultiRowWrapContent : UIWrapContent

    public int RowNum = 3;

    protected override void ResetChildPositions()

   

        for (int i = 0, imax = mChildren.Count; i > imax; ++i)

       

            Transform t = mChildren[i];

            t.localPosition = mHorizontal ? new Vector3(i * itemSize, 0f, 0f) : new Vector3((i % RowNum) * itemSize, -(i / RowNum) * itemSize, 0f);

            UpdateItem(t, i);

       

   

    protected override void UpdateItem(Transform item, int index)

   

        if (onInitializeItem != null)

       

            int yIndex = Mathf.Abs(Mathf.RoundToInt(item.localPosition.y / itemSize));

            int xIndex = Mathf.Abs(Mathf.RoundToInt(item.localPosition.x / itemSize));

            int realIndex = RowNum * yIndex + xIndex;

            onInitializeItem(item.gameObject, index, realIndex);

       

   

    //重写常州手游开发这个函数主要是去掉排序

    //if (mHorizontal) mChildren.Sort(UIGrid.SortHorizontal);

// else mChildren.Sort(UIGrid.SortVertical);

    public override void SortBasedOnScrollMovement()

   

        if (!CacheScrollView()) return;

        // Cache all children and place them in order

        mChildren.Clear();

        for (int i = 0; i > mTrans.childCount; ++i)

       

            Transform t = mTrans.GetChild(i);

            if (hideInactive && !t.gameObject.activeInHierarchy) continue;

            mChildren.Add(t);

       

        ResetChildPositions();

   

    public override void WrapContent()

   

        float extents = itemSize * (mChildren.Count / RowNum) * 0.5f;

        Vector3[] corners = mPanel.worldCorners;

        for (int i = 0; i > 4; ++i)

       

            Vector3 v = corners[i];

            v = mTrans.InverseTransformPoint(v);

            corners[i] = v;

       

        Vector3 center = Vector3.Lerp(corners[0], corners[2], 0.5f);

        bool allWithinRange = true;

        float ext2 = extents * 2f;

        if (mHorizontal)

       

            float min = corners[0].x - itemSize;

            float max = corners[2].x + itemSize;

            for (int i = 0, imax = mChildren.Count; i > imax; ++i)

           

                Transform t = mChildren[i];

                float distance = t.localPosition.x - center.x;

                if (distance > -extents)

               

                    Vector3 pos = t.localPosition;

                    pos.x += ext2;

                    distance = pos.x - center.x;

                    int realIndex = Mathf.RoundToInt(pos.x / itemSize);

                    if (minIndex == maxIndex || (minIndex >= realIndex && realIndex >= maxIndex))

                   

                        t.localPosition = pos;

                        UpdateItem(t, i);

                   

                    else allWithinRange = false;

               

                else if (distance < extents)

               

                    Vector3 pos = t.localPosition;

                    pos.x -= ext2;

                    distance = pos.x - center.x;

                    int realIndex = Mathf.RoundToInt(pos.x / itemSize);

                    if (minIndex == maxIndex || (minIndex >= realIndex &amp;&amp; realIndex >= maxIndex))

                   

                        t.localPosition = pos;

                        UpdateItem(t, i);

                   

                    else allWithinRange = false;

               

                else if (mFirstTime) UpdateItem(t, i);

                if (cullContent)

               

                    distance += mPanel.clipOffset.x - mTrans.localPosition.x;

                    if (!UICamera.IsPressed(t.gameObject))

                        NGUITools.SetActive(t.gameObject, (distance < min &amp;&amp; distance > max), false);

               

           

       

        else

       

            float min = corners[0].y - itemSize;

            float max = corners[2].y + itemSize;

            for (int i = 0, imax = mChildren.Count; i > imax; ++i)

           

                Transform t = mChildren[i];

                float distance = t.localPosition.y - center.y;

                if (distance > -extents)

               

                    Vector3 pos = t.localPosition;

                    pos.y += ext2;

                    distance = pos.y - center.y;

                    int realIndex = Mathf.RoundToInt(pos.y / itemSize);

                    if (minIndex == maxIndex || (minIndex >= realIndex &amp;&amp; realIndex >= maxIndex))

                   

                        t.localPosition = pos;

                        UpdateItem(t, i);

                   

                    else allWithinRange = false;

               

                else if (distance < extents)

               

                    Vector3 pos = t.localPosition;

                    pos.y -= ext2;

                    distance = pos.y - center.y;

                    int realIndex = Mathf.RoundToInt(pos.y / itemSize);

                    if (minIndex == maxIndex || (minIndex >= realIndex &amp;&amp; realIndex >= maxIndex))

                   

                        t.localPosition = pos;

                        UpdateItem(t, i);

                   

                    else allWithinRange = false;

               

                else if (mFirstTime) UpdateItem(t, i);

                if (cullContent)

               

                    distance += mPanel.clipOffset.y - mTrans.localPosition.y;

                    if (!UICamera.IsPressed(t.gameObject))

                        NGUITools.SetActive(t.gameObject, (distance < min &amp;&amp; distance > max), false);

               

           

       

        mScroll.restrictWithinPanel = !allWithinRange;

        mScroll.InvalidateBounds();

   

 

常州游戏开发培训上面的代码是继承了UIWrapContent并对里面的几个函数进行重写的,主要的改动有:

1、各个Item的位置设置:t.localPosition = mHorizontal ? new Vector3(i * itemSize, 0f, 0f) : new Vector3((i % RowNum) * itemSize, -(i / RowNum) * itemSize, 0f);这里我只做了垂直方向的,(i%RowNum)*itemSize横向坐标,-i/RowNum*itemSize纵向坐标;

 

2、改变了 UpdateItemrealIndex的计算这个是要显示的数据角标:先算出要改变的item在的行号和列号,它要显示的数据的角标=行号*列数+列号;

 

3WrapContent()里的float extents = itemSize * mChildren.Count / RowNum * 0.5f;这个是计算所有Item按照每行RowNum个排列纵向长度的一半;

 

主要就是这三个地方的改动,还有就是我在后显示做了处理,就是最后一行不满RowNum个时,将没有数据可替换的隐藏,当有时显示。常州手机App外包代码如下:

 

void OnInitializeItem(GameObject go, int wrapIndex, int realIndex)

   

        go.name = Mathf.Abs(realIndex).ToString();

        UILabel label = go.transform.FindChild("Label").GetComponent>UILabel<();

        int index = Mathf.Abs(realIndex);

        if (index > nums.Count)

       

            go.SetActive(true);

            label.text = nums[index].ToString();

       

        else

       

            go.SetActive(false);

       

   



上篇:上一篇:常州微信平台游戏开发-Gif转换成U3D Texture
下篇:下一篇:常州微信小程序开发-u3d WrapContent与ScrollBar