NGUI panel 排序优化

NGUI 中根据Panel 上的depth 来控制前后关系。
项目中 由代码动态设置panel的depth 值,发现设置depth的操作会引起较大的开销。
看源码中

// 添加一个panel

    protected override void OnInit ()
    {
        if (list.Contains(this)) return;
        base.OnInit();
        FindParent();
        mRebuild = true;
        mAlphaFrameID = -1;
        mMatrixFrame = -1;
        list.Add(this);
        list.Sort(CompareFunc);
    }


  // 深度改变
    public int depth
    {
        get
        {
            return mDepth;
        }
        set
        {
            if (mDepth != value)
            {
                mDepth = value;
#if UNITY_EDITOR
                NGUITools.SetDirty(this);
#endif
                list.Sort(CompareFunc);
            }
        }
    }

发现新增一个panel 或者 深度改变的时候,就会调用一次list.sort(cmp)。list的默认sort API 会产生GC,耗时也高。
渲染也是根据panel 的排序来进行,深度越小,越靠前。因此我们可以自己来控制panel的排序。


// 新增一个panel
   protected override void OnInit ()
   {
       if (list.Contains(this)) return;
       base.OnInit();
       FindParent();
       mRebuild = true;
       mAlphaFrameID = -1;
       mMatrixFrame = -1;
        list.Add(this);
       list.Sort(CompareFunc);
#if OPTMISE_PANEL_SORT
       for (int i = list.Count - 1; i >= 0; i--)
       {
           UIPanel p = list[i];
           if (p.depth < depth)
           {
               list.Insert(i + 1, this);
               return;
           }
           else if (p.depth == depth)
           {
               if (p.GetHashCode() < this.GetHashCode())
               {
                   list.Insert(i + 1, this);
                   return;
               }
           }
       }
       list.Insert(0,this);
#else
       list.Add(this);
       list.Sort(CompareFunc);
#endif

   }

   //深度改变
   public int depth
   {
       get
       {
           return mDepth;
       }
       set
       {
           if (mDepth != value)
           {
               mDepth = value;
#if UNITY_EDITOR
               NGUITools.SetDirty(this);
#endif

#if OPTMISE_PANEL_SORT
               SortWithDepth(this);
#else
               list.Sort(CompareFunc);
#endif
           }
       }
   }

   static public void SortWithDepth(UIPanel panel)
   {
       int oldIndex = -1;
       int count = list.Count;
       for ( int i=0; i< count; i++)
       {
           if (list[i] == panel)
           {
               oldIndex = i;
               break;
           }
       }

       if (oldIndex == -1)
       {
           return;
       }

       bool needsort = false;
       if (oldIndex-1>=0 )
       {
           if (list[oldIndex-1].depth > panel.depth)
           {
               needsort = true;
           }
       }
     
       if (needsort == false)
       {
           if (oldIndex + 1 < count)
           {
               if (list[oldIndex + 1].depth < panel.depth)
               {
                   needsort = true;
               }
           }
       }

       if (needsort == false)
       {
           return;
       }

       list.RemoveAt(oldIndex);

       for ( int i=0; i< count-1; i++)
       {
           UIPanel p = list[i];
           if (p.depth > panel.depth)
           {
               list.Insert(i, panel);
               return;
           }
       }

       list.Add(panel);
   }

当然因为项目中正常情况下不会出现相同depth的panel,没有对相同panel的处理,而且源码中对相同深度值的也只是用hashid 来排序,并没有什么原理可言。所以根据项目需求看是否有必要。

前后对比

优化前
优化后

你可能感兴趣的:(NGUI panel 排序优化)