免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
NGUI所見(jiàn)即所得之UIGrid & UITable

NGUI所見(jiàn)即所得之UIGrid & UITable

 

By D.S.Qiu

尊重他人的勞動(dòng),支持原創(chuàng),轉(zhuǎn)載請(qǐng)注明出處:http.dsqiu.iteye.com

 

       你是不是對(duì) UIGrid 和 UITable 定位計(jì)算方法還模糊不清,那么這篇文章就是你需要的。

       NGUI 提供了 Grid 和 Table 組件,支持的參數(shù)很少,功能也很雞肋,完全不能像 CSS 的 Box 模型那樣隨心所欲的布局,而且使用 UIGrid 和 UITable 的時(shí)候經(jīng)常會(huì)相對(duì) UIGrid 和 UITable 掛載的 Transform 出現(xiàn)偏移,之前使用的時(shí)候,都是根據(jù)經(jīng)驗(yàn)來(lái)規(guī)避的。今天打算把UIGrid 和 UITable 的排列規(guī)則看下, 才形成此文。

 

        UIGrid 和 UITable 的原理很簡(jiǎn)單,對(duì)子 Transform 的 List 進(jìn)行排序,然后更加不同的規(guī)則進(jìn)行定位排列(UIGrid 和 UITable 還是有很大不同的)。

 

排序(Sort)

        UIGrid 和 UITable 定義了5種排列方式(其實(shí)是3種,None默認(rèn)不排序即Transform的默認(rèn)排序,Custom雖然提供virtual 可以重載):

C#代碼
 
  1. public enum Sorting  
  2. {  
  3.     None,  
  4.     Alphabetic,  
  5.     Horizontal,  
  6.     Vertical,  
  7.     Custom,  
  8. }  

         對(duì)應(yīng)的三種排序方法:集 Alphabetic 按照名字字符串排序,Horizontal 和 Vertical 按照l(shuí)ocalPosition 進(jìn)行的排序

C#代碼
 
  1. static public int SortByName (Transform a, Transform b) { return string.Compare(a.name, b.name); }  
  2. static public int SortHorizontal (Transform a, Transform b) { return a.localPosition.x.CompareTo(b.localPosition.x); }  
  3. static public int SortVertical (Transform a, Transform b) { return b.localPosition.y.CompareTo(a.localPosition.y); }  

         這里說(shuō)下,雖然提供了Custom方式,第一感覺(jué)NGUI的developer考慮很周到,但是提供的確實(shí)重載 virtual 函數(shù)的方式,D.S.Qiu 覺(jué)得這種方式太不好了,為了一個(gè)方法就要寫(xiě)一個(gè) 子類(lèi)去重載,個(gè)人覺(jué)得指定一個(gè)委托,擴(kuò)展起來(lái)會(huì)更直觀,但這一要求開(kāi)發(fā)者一開(kāi)始就得指定這個(gè) Custom Sort Delegate。

 

UIGrid定位原理

        下面這段代碼是 Reposition() 的一部分,原理很簡(jiǎn)單:根據(jù)定義的cellHeight 和cellWidth 來(lái)調(diào)整子 Transform 的 localPosition。這里還是吐槽下:Reposition() 的代碼太多容易了,至少我看到了這段代碼在 Reposition 中出現(xiàn)了兩次,完全多余,其實(shí)就是處理流程就應(yīng)該是: 先獲取所有子 Transform List ,然后對(duì)List 排序,最后就是下面這段定位代碼了。

C#代碼
 
  1. for (int i = 0, imax = list.Count; i < imax; ++i)  
  2. {  
  3.     Transform t = list[i];  
  4.     if (!NGUITools.GetActive(t.gameObject) && hideInactive) continue;  
  5.     float depth = t.localPosition.z;  
  6.     Vector3 pos = (arrangement == Arrangement.Horizontal) ?  
  7.         new Vector3(cellWidth * x, -cellHeight * y, depth) :  
  8.         new Vector3(cellWidth * y, -cellHeight * x, depth);  
  9.   
  10.     if (animateSmoothly && Application.isPlaying)  
  11.     {  
  12.         SpringPosition.Begin(t.gameObject, pos, 15f).updateScrollView = true;  
  13.     }  
  14.     else t.localPosition = pos;  
  15.   
  16.     if (++x >= maxPerLine && maxPerLine > 0)  
  17.     {  
  18.         x = 0;  
  19.         ++y;  
  20.     }  
  21. }  

 

UITable 定位原理

       UITable 的定位方法在 ReositionVaribleSize 中,跟UIGrid 最大不同點(diǎn)是:UIGrid 只根據(jù)定義的cellHeight 和 cellWidth 來(lái)計(jì)算位置,UITable 根據(jù)“內(nèi)容“(UIWidget)來(lái)計(jì)算位置的。

C#代碼
 
  1. protected void RepositionVariableSize (List<Transform> children)  
  2. {  
  3.     float xOffset = 0;  
  4.     float yOffset = 0;  
  5.   
  6.     int cols = columns > 0 ? children.Count / columns + 1 : 1;  
  7.     int rows = columns > 0 ? columns : children.Count;  
  8.   
  9.     Bounds[,] bounds = new Bounds[cols, rows];  
  10.     Bounds[] boundsRows = new Bounds[rows];  
  11.     Bounds[] boundsCols = new Bounds[cols];  
  12.   
  13.     int x = 0;  
  14.     int y = 0;  
  15.         //這個(gè)循環(huán)計(jì)算每行,每列,每個(gè)cell 的內(nèi)容的編輯 Bounds  
  16.     for (int i = 0, imax = children.Count; i < imax; ++i)  
  17.     {  
  18.         Transform t = children[i];  
  19.         Bounds b = NGUIMath.CalculateRelativeWidgetBounds(t, !hideInactive);  
  20.   
  21.         Vector3 scale = t.localScale;  
  22.         b.min = Vector3.Scale(b.min, scale);  
  23.         b.max = Vector3.Scale(b.max, scale);  
  24.         bounds[y, x] = b;  
  25.   
  26.         boundsRows[x].Encapsulate(b);  
  27.         boundsCols[y].Encapsulate(b);  
  28.   
  29.         if (++x >= columns && columns > 0)  
  30.         {  
  31.             x = 0;  
  32.             ++y;  
  33.         }  
  34.     }  
  35.   
  36.     x = 0;  
  37.     y = 0;  
  38.         //計(jì)算位置  
  39.     for (int i = 0, imax = children.Count; i < imax; ++i)  
  40.     {  
  41.         Transform t = children[i];  
  42.         Bounds b = bounds[y, x];  
  43.         Bounds br = boundsRows[x];  
  44.         Bounds bc = boundsCols[y];  
  45.   
  46.         Vector3 pos = t.localPosition;  
  47.         pos.x = xOffset + b.extents.x - b.center.x;  
  48.         pos.x += b.min.x - br.min.x + padding.x;   //以每列最右邊的x值為標(biāo)準(zhǔn),即保證每列最左邊的基準(zhǔn)點(diǎn)  
  49.   
  50.         if (direction == Direction.Down)  
  51.         {  
  52.             pos.y = -yOffset - b.extents.y - b.center.y;  
  53.             pos.y += (b.max.y - b.min.y - bc.max.y + bc.min.y) * 0.5f - padding.y;  
  54.         }  
  55.         else  
  56.         {  
  57.             pos.y = yOffset + (b.extents.y - b.center.y);  
  58.             pos.y -= (b.max.y - b.min.y - bc.max.y + bc.min.y) * 0.5f - padding.y;  
  59.         }  
  60.   
  61.         xOffset += br.max.x - br.min.x + padding.x * 2f;  
  62.   
  63.         t.localPosition = pos;  
  64.   
  65.         if (++x >= columns && columns > 0)  
  66.         {  
  67.             x = 0;  
  68.             ++y;  
  69.   
  70.             xOffset = 0f;  
  71.             yOffset += bc.size.y + padding.y * 2f;  
  72.         }  
  73.     }  
  74. }  

          這里還是有吐槽:根據(jù) Bounds 的定義 b.extens.x - b.center.x + b.min.x == 0 ,也就是這部完全是沒(méi)有必要的,看來(lái)UIGrid 的 developer,不光代碼邏輯不清晰,難道連大腦都是豆腐花做的么。

C#代碼
 
  1. pos.x = xOffset + b.extents.x - b.center.x;  
  2. pos.x += b.min.x - br.min.x + padding.x;  

           類(lèi)似計(jì)算 y 的值也其他更直接方法:

C#代碼
 
  1. (b.max.y - b.min.y - bc.max.y + bc.min.y) * 0.5f  

 

使用經(jīng)驗(yàn)

      1.UIGrid 沒(méi)有考慮Bounds ,根據(jù)UIGrid 的計(jì)算公式可以知道:UIGrid 的第一個(gè)元素的 localPosition 的 x 和 y 一定都是 0 ,所以要位置,必須調(diào)整UIGrid 的localPosition ,但是實(shí)際在有可能調(diào)整的是 子對(duì)象,然后再 Scene 窗口看是沒(méi)問(wèn)題的(注意此時(shí)還沒(méi)有重排),一運(yùn)行就會(huì)出現(xiàn)位置的偏移。

      2.UITable 的子組件的 x 總是以 每列最左為 起始基準(zhǔn)點(diǎn)的, y 則是每行居中對(duì)齊 :(b.max.y - b.min.y - bc.max.y + bc.min.y) * 0.5f 這行代碼起始就是計(jì)算當(dāng)前組件和所在行中心點(diǎn)的偏移。

   下圖是將NGUI 其中一個(gè)組件的 sprite 左移了,就出現(xiàn)下面的排列:


 

       雖然 NGUI 提供了 UIGrid 和 UITable ,起始是非常之不完善,幾乎做不了什么功能。這里分享兩條經(jīng)驗(yàn):

               1.使用UIGrid時(shí),調(diào)整界面的時(shí)候讓 UIGrid 的 transform 和 其第一個(gè)子組件的 transform 相同,這樣經(jīng)過(guò)計(jì)算之后,位置就是之前調(diào)整想要的?;蛘邔?第一個(gè)子組件 transform 重置,這樣調(diào)整UIGrid 的              transform 位置看到的效果就是真實(shí)的。

               2.使用UITable 讓每列元素的左邊界都相同,即左對(duì)齊??梢钥吹?NGUI Example 的 Question Log 的 Table 的所有組件(UILable UISprite)的 pivot 都調(diào)整為 left 。

 

        總之,就是根據(jù)UIGrid 和UITable 的排列原理做相應(yīng)的調(diào)整。

 

 

小結(jié):

       這篇文章相對(duì)于NGUI所見(jiàn)即所得系列其他文章來(lái)說(shuō),簡(jiǎn)單很多。最近要做一個(gè)界面根據(jù)內(nèi)容自適應(yīng),挺復(fù)雜的,一堆莫名其妙的問(wèn)題。之前一直覺(jué)得 Unity 的 UI 沒(méi)有Window MFC 等開(kāi)發(fā)直接拖拽方式那么直觀。NGUI 雖然很龐大,但NGUI越來(lái)越容易讓我吐槽了,可能是對(duì)NGUI的家底多少掌握的緣故吧。

        很久就聽(tīng)說(shuō)Unity要出自己的 UI 了,其實(shí)D.S.Qiu 也一直有想嘗試自己寫(xiě)一點(diǎn)UI的可視化編輯工具(Visual Editor)。昨天不經(jīng)意看到 Cocos2D 的 UI 編輯器 CocoStudio 感覺(jué)很強(qiáng)大,然后順手google Unity有沒(méi)有這方面的工具,果然還是發(fā)現(xiàn)了 UIToolkit , bitverse RagePixel 和 EWS editor ,也就說(shuō) Unity其實(shí)也有些 UI 可視化工具的。尤其 bitverse 支持的組件特別豐富,很強(qiáng)大,只可惜沒(méi)有集成 Batch  DrawCall 的功能。

 

       如果您對(duì)D.S.Qiu有任何建議或意見(jiàn)可以在文章后面評(píng)論,或者發(fā)郵件(gd.s.qiu@gmail.com)交流,您的鼓勵(lì)和支持是我前進(jìn)的動(dòng)力,希望能有更多更好的分享。

       轉(zhuǎn)載請(qǐng)?jiān)谖氖鬃⒚鞒鎏帲?a style="line-height: 1.5;" >http://dsqiu.iteye.com/blog/2034883

更多精彩請(qǐng)關(guān)注D.S.Qiu的博客和微博(ID:靜水逐風(fēng))

 

 

 

 

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶(hù)發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
Unity中做一個(gè)模擬的遙感
11、防御塔的創(chuàng)建二
1、將Unity中的世界坐標(biāo)轉(zhuǎn)換成NGUI中的坐標(biāo),代碼如下所示:
Unity使用transform.Translate()移動(dòng)子物體時(shí)遇到的小問(wèn)題
Unity3D插件NGUI之Scorll View(滑動(dòng)圖標(biāo))的制作(簡(jiǎn)潔版)
【新提醒】【原創(chuàng)】Unity3D UIGrid 排序、動(dòng)態(tài)加載與銷(xiāo)毀
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服