1. 程式人生 > >關於NGUI中一些控制元件的說明

關於NGUI中一些控制元件的說明

我開始學Unity的時候,NGUI就已經是3.6.8版本了,對於有一些NGUI的外掛,我至今都不太清楚它的用處

現在我整理了網上搜來的一些控制元件說明,希望對大家有用:



UIRoot總是放在NGUI UI層級的最上層。

它用來使UI的縮放變得更容易。widget通常使用的是以畫素為單位的座標,但是一個800*400(dimensions的值)的widget會佔用800*400個單位(Unity中的單位),這相當大。UIRoot通過螢幕高度的反比來進行縮放,因此widgets都會很小,並且操作起來更容易。



UIRoot有幾種縮放方式。最常見的就是PixelPerfect。這種方式下,你的UI一直都是以畫素為基礎,一個300*200的widget在螢幕上永遠佔用300*200畫素。這就意味著,你的UI在低解析度的機器上會顯得非常大,在高解析度的機器上就會顯得很小。這個設定就是一直保持你的UI清晰。



FixedSize是一個和它功能正好相反的設定。當UIRoot用了這個選項,你的螢幕永遠都會保持NGUI所關心的尺寸,不管你的實際螢幕是多大。就是說一個300*200的widget佔用了你1920*1080的25%的螢幕,那麼當解析度降低到1280*720的時候,它同樣佔用25%的螢幕。如果你不介意你的UI看起來像是不同的尺寸,也不關心是否清晰(就是可能一個小的UI被拉伸很大),那麼選擇這個選項。選擇它的時候,不要忘記設定Manual Height

FixedSizeOnMobile是前兩種的組合。選擇這個選項後,會在pc或者mac等桌面裝置上用“PixelPerfect”,在移動裝置上用“FixedSize”。


如果你沒有選擇Fixed Size選項,那就要設定MinimumMaximum Height的值。這些值讓你的虛擬螢幕看起來在合理範圍。比如選擇了Pixel Perfect方式,Minimum Height設定為720,那麼當有玩家把你的程式執行在800*600(高度是600,小於Minimun Height)的裝置上時,你UI的行為就和設定了“Fixed Size”模式、Manual Height值設為720的時候一樣。

UIWidget是NGUI的基礎元件。簡單來說,就是一個你可以放在螢幕任意位置的矩形框。widget會有一定的面積(如下圖的白色框範圍),但是在執行的時候(Game View)是完全不可見的,所以非常適合當做其他元件的容器(讓所有的sprite或者label等以它進行各種對齊)。





UIWidget 也被用來當做所有NGUI元素的基類——所有你建立的sprites和labels。UILabel,UISprite,UITexture和UI2DSprite(Unity3D 4.3版本)都繼承自UIWidget。.

  • 把滑鼠放到矩形框裡面來移動它的位置。
  • 拖動藍色圓點進行縮放
  • 滑鼠放在藍色原點外面一些,就可以旋轉widget。按住shift可以微調(windows上是ctrl)。
  • 加入collider就可以讓這個區域接受事件。可以在這個widget上定位其他widgets,具體檢視UIAnchor。
  • 在給widget加了box collider之後,widget的inspector上會有一個新的選項:Box Collider。預設是勾選的,它會自動調整使得collider的size和widget的尺寸一樣(dimensions)。
  • 增加UIWidget的快捷鍵是alt+shift+w
widget的position在程式碼裡面通過Transform元件獲取——和其他的場景中物體一樣。widget的位置與它的Pivot有關。pivot可以理解為這個widget的旋轉中心。

Widgets也有Depth屬性,控制他們被點選時的響應順序(在Sprite和Label中也用來控制渲染順序,值越大,顯示的時候越靠前)。在Scene View中右鍵widget可以看到depth的排序。右鍵後會看見一個列表(如下圖),所有在滑鼠位置的widget都會列出來。最上面的就是顯示在最前面的,也會最先接收事件。 



這個選單也提供增加兄弟或者子節點的widget(包括sprite、label等)。



UIPanel用來收集和管理它下面所有widget的元件。通過widget的geometry建立實際的draw call。沒有panel所有東西都不能夠被渲染出來。如果你對Unity熟悉,你可以把UIPanel當做Renderer。



所有panel都有一個Depth值,會影響所有它包含的widget。如果你的UI有很多視窗,那麼最好每個視窗有一個panel。Panel上的depth權重會遠遠高於每一個widget的depth權重,所以保證panel不要使用同樣的depth。如果使用同樣的depth在panel上,那麼draw call會被自動拆分來保證渲染順序,所以會增加更多的draw call。

  • Alpha屬性影響所有在panel下面的widget。所以可以用它來淡出整個視窗。
  • 如果你的UI需要被燈光影響,需要勾選上Normals
  • 如果建立了一個有很多geometry的scrollable panel,你需要勾選Cull選項來減少三角形的數目。這樣也可能降低效能,因為widget的可視性需要每次update都檢驗一次。
  • 勾選Static選項來告訴NGUI這個panel下面的widget不會被移動,這樣可以提高效能。NGUI會忽略所有的position/rotation/scale改變。所以在執行時移動widget不會有效——所以小心使用。
  • 如果要除錯由panel建立的draw calls,Show All選項可能幫助到你。你會看到由panel建立的所有draw call,以渲染順序排序。每個draw call會包括它使用到material的詳細資訊,那個widget用的這個material,甚至可以讓你關閉某些draw call來讓你查詢某些問題。
Panel會根據dimensions自動Clip所有它的子節點。使用這個功能需要選擇Clipping下拉列表中的任意選項,之後調整Scene View中紫色矩形的尺寸,就像調整widget的尺寸一樣。通過這樣做你可以把一個panel放到Scroll View中,讓他輕鬆的拖拽。

注意clipping的panel不能巢狀。每個panel只能clip自己管理的widget,如果一個panel在另外一個panel裡面,只有一個會影響到裡面的widget。這個限制以後會去掉。

預設NGUI中panel的Render Queues從3000開始往上增加。你可以通過Render Q來修改。如果你想在兩個panel中間增加粒子,只要修改兩個panel的render queue一個高於粒子,一個低於粒子即可。如果想要讓所有的draw call使用和NGUI 2.x版本的渲染方式一樣,使用z軸而不是depth。那麼給panel的Render Q指定為Explicit。(NGUI 2.x用的是3000)。

如果你找和Anchors相關的文件,可以看基類——UIRect。

UIAnchor讓你可以固定game objects在螢幕或者其他widgets的某一邊或者某一個角。這是一個關鍵的元件,用來在NGUI中建立模組化的UI。 



是否想讓你的一部分UI粘在螢幕的角落或者邊緣上?比如魔獸世界。在這個遊戲中,遊戲地圖永遠在螢幕的右上角,熱鍵一直在螢幕的下方,不管你用的是多大的螢幕解析度。你如何做到類似的東西呢?用anchors。

NGUI的預設UI佈局會給你提供一個anchor——一個居中的anchor。以魔獸世界的UI為例子,你需要增加額外的兩個anchor。一個設定成TopRight,另一個則為Bottom。之後你給這兩個anchor增加一些子節點,然後修改螢幕的尺寸,你會發現UI會一直在你想要的地方(右上方或者下面)。

通過設定anchor的Container讓一個UI附著在另一個UI上。如果Container是UIWidget,那麼會用widget的dimesions來代替螢幕矩形(就是TopRight將將是相對與這個widget,而不是螢幕)。如果是game object,那麼這個矩形就是game object下的所有節點widget的bounds。因為這個原因,當你用父節點當做Container的時候一定要注意,因為父節點的Container大小會包含這個你要anchor的widget,這可能不是你要的效果(比如你要放在父節點的左上角,但是當這個widget到了左上角後,父節點的左上角由於這個widget的到來可能就變了,之後再次移動widget,周而復始……)。

調整Relative Offset來用相對值來改變位置。 如果X是1就是100%的container寬度. Y是1就是100%的container高度。 0.5 = 50%,等等。也可以是負數。

上面的調整也可以通過用Pixel Offset來實現。就和你想的差不多……通過給定的X、Y的值來以畫素為單位調整anchor的偏移。

預設情況下anchor只會執行一次。如果要在每個update裡面都執行,那勾選掉Run Only Once選項。



這個元件在NGUI的3.0.7及以後版本中不建議使用. .

UIStretch用來讓widget相對於其他widget或者相機視窗的矩形進行縮放。用它和UIAnchor來在NGUI的3.0.6及以前的版本中建立模組化的UI。



你是否有個一個讓widget根據其他的widget的大小來進行大小調整的需求?比如在button裡面的label,現在你可以這麼做了!

還是以button為例子,你有一個button,背景是sliced sprite,子節點是label,你可以把UIStretch掛到label上,選擇背景當做Container,之後設定Style為“Both”。加入一些Border Padding,就實現了這個功能。現在你調整背景的大小,這個label也會隨之改變。



UIPlayAnimation通過你選擇的事件條件去觸發其他的動畫。它和UIPlayTween的區別就是它處理的是動畫。



給widget增加動畫的最好好發就是點選ctrl+6來開啟Animation視窗。

如果你只是試驗一下,你可以直接用NGUI提供的Checkmark動畫。無論用哪種方法,你需要勾選掉Play Automatically選項,否則在你點選Play的時候,這個動畫就會被執行。

為了觸發其他動畫,掛一個UIPlayAnimation元件(Attach -> Play Animation)。你會很樂意看到有這麼多可以選擇的選項。

先選擇Clip Name,就是動畫裡面會播放的clip的名字。如果你的動畫裡面只有一個動畫,那麼這裡可以為空。

Trigger Condition讓你選擇動畫的觸發方式,Play Direction可以控制動畫播放的方向。還可以控制Selected Object。這個是考慮到當開發一個基於控制器的遊戲,一些東西需要一直被選中,但是當用動畫隱藏一個視窗,彈出了另外的一個,你可能更像讓當前的選擇變到另外的按鍵上。 

如果target是disabled狀態,你可以選擇activate它或者讓它保持disabled。一個動畫是淡出一個視窗和淡入一個視窗,你需要為淡出視窗的When finished指定為Disable,為淡入的指定為Enable then play。這會保證在淡出的時候被disabled但在淡入的時候又被enabled。

動畫已經開始的話,可以選擇restart讓動畫從頭開始播放。

最後如果想要在動畫完成後執行一些函式,你可以把目標game object拖拽到Notify屬性裡並且選擇合適的函式在下拉列表裡面。函式的宣告需要是“public void FuncName (void)”這樣的。比如:

[AppleScript] 純文字檢視 複製程式碼 ?
1 2 3 4 public void MyNotification ()  {  Debug.Log(ActiveAnimation.current.name+" has finished playing!") }

小貼士

  • 可以通過程式碼直接播放動畫,使用函式ActiveAnimation.Play():

[C#] 純文字檢視 複製程式碼 ?
1 ActiveAnimation.Play(targetAnimation, AnimationOrTween.Direction.Forward);



UICamera這個名字不是很合適,保留的原因僅僅是為了相容以前的版本。

UICamera真正做的事情是傳送NGUI事件給所有被當前camera渲染的object,camera是UICamera指令碼所在的那個。 其實這個指令碼做的事情和UI無關。事實上如果你想讓遊戲裡面的object接收OnPress、OnClick、OnDrag等這類事件,你需要把UICamera掛在你的主相機上。

遊戲場景裡面可以有多個UICamera。大多數遊戲一個掛在渲染widget的相機上,一個掛在渲染遊戲的相機上。



UICamera的選項Event Type用來決定指令碼如何排序mouse或者touch觸發的事件。如果是UI模式,這些事件順序基於widget的depth——和渲染順序一樣。如果UICamera掛到了Main Camera上,那麼就需要把這個選項修改成World模式。這樣就會根據與相機的距離來排序點選到的object。

Event Mask用來決定哪些層會接收事件。大多數情況下你需要的就是“Everything”,這個值會與UnityEngine.Camera's Culling Mask進行邏輯與運算,有需要的話你可以微調這個值。如果你修改了UI的game object的Layer記得調整Event Mask,否則你可能會發現UI不響應事件。

Debug選項用來顯示當前在滑鼠下面的是什麼。如果你不知道是什麼東西接收了滑鼠事件,勾選上這個選項你就可以在右上角看到了。

Allow Multi-Touch選項用來控制是否支援多點觸碰。如果勾選掉,多點觸碰也會當做單點觸碰。

Sticky Tooltip選項用來微調tooltip的行為。如果關掉,當滑鼠再次移動的時候就會立即關掉tooltip。如果開啟,只要滑鼠一直在這個game object上,tooltip就會移至顯示。

Tooltip Delay用來控制當滑鼠停在某個object上時,經過多長時間OnTooltip訊息會被髮送到這個object上。以秒為單位。

Raycast Range控制raycast的長度,大多數情況下這個值可以被忽略。這個值是世界座標系的值,所以如果你的攝像機的near clip是0.3、far clipping是 1000,比較遠的物體可能不會響應click事件,比如可以把這個值設定為2000(比far和near clipping大的值。)



Event Sources用來確定哪些事件型別會被處理。被勾選掉的事件就不會被處理。有些平臺會強制關閉一些事件。比如使用手柄時會自動關掉滑鼠和touch時事件。



Thresholds可以調整click、drag和tap事件的閾值來微調滑鼠和touch事件的行為。以畫素為單位。



Axes和Keys部分用來控制哪個軸控制哪個方向的移動。這些名字需要和Input Manager裡面的一致。

小貼士

UICamera傳送以下事件給collider:

  • OnHover (isOver) 傳送時機為滑鼠懸停(只觸發一次)或者離開collider。
  • OnPress (isDown) 傳送時機為滑鼠在collider上按下。
  • OnSelect (selected)傳送時機為滑鼠點選和鬆開的時候都在同一個object上。
  • OnClick ()傳送時機和OnSelect一樣,但是要求滑鼠沒有移動特別多。UICamera.currentTouchID表示按下的滑鼠哪個鍵。
  • OnDoubleClick ()傳送時機為當在四分之一秒內click兩次的時候。UICamera.currentTouchID表示按下的滑鼠哪個鍵。
  • OnDragStart ()傳送時機為OnDrag()事件之前。
  • OnDrag (delta) 傳送時機為一個object被拖拽。
  • OnDragOver (draggedObject)傳送時機為其他的object拖拽到他的上面。
  • OnDragOut (draggedObject)傳送時機為其他的object拖拽出他的上面。
  • OnDragEnd ()傳送時機為drag事件結束。傳送給被拖拽的object。
  • OnInput (text)傳送時機為輸入的時候(在點選選擇了一個collider之後)。
  • OnTooltip (show) 傳送時機為滑鼠懸停在一個collider上一段時間沒有移動。
  • OnScroll (float delta)傳送時機為滑鼠滾輪滾動。
  • OnKey (KeyCode key)傳送時機為鍵盤或者輸入控制器被使用的時候。

用他們到自己的腳本里面,只要實現相應的函式即可:
[C#] 純文字檢視 複製程式碼 ?
1 2 3 4 5 voidOnPress (boolisPressed)

相關推薦

關於NGUI一些控制元件的說明

我開始學Unity的時候,NGUI就已經是3.6.8版本了,對於有一些NGUI的外掛,我至今都不太清楚它的用處 現在我整理了網上搜來的一些控制元件說明,希望對大家有用: UIRoot總是放在NGUI UI層級的最上層。它用來使UI的縮放變得更容易。widget通常使用的

swift as、as!、as? 這三種類型轉換操作符的異同 及一些控制元件用法

轉自:http://www.111cn.net/sj/iOS/104115.htm 應網友要求,我這裡總結了下 as、as!、as? 這三種類型轉換操作符的異同,以及各自的使用場景。 1,as使用場合 (1)從派生類轉換為基類,向上轉型(upcasts) cla

vb.netserialport控制元件一些使用經驗

一些需要注意的地方 Serialport 的datareceived事件是串列埠接收到不大於SerialPort1.ReceivedBytesThreshold個位元組的時候觸發,但是具體多少個不確定(實驗發現,當第一個位元組與下一個位元組傳送間隔很短的時候幾乎就是等於Se

C#Form.SplitContainer清除控制元件textbox值(窗體.容器.控制元件

文章目錄 問題背景 問題程式碼 問題解決 正確清除程式碼 問題延申 問題背景 早上在完善不確定度計算器時,想要清空實驗資料輸入時所有textbox控制元件值。 問題程式碼

[Swift]ViewControllerxib控制元件為空

在ViewController的xib中定義了一些控制元件,然後在使用的時候會因為這個控制元件為空而崩潰,報錯為: Swift Error fatal error: unexpectedly found nil while unwrapping an Optional value

EXT各個控制元件隱藏不可編輯等操作以及一些控制元件操作

//FieldSet2 $get(‘FieldSet’).hide(); //TextField設定 不可編輯 Ext.getCmp(“TextField”).readOnly = true; //帶文字框 $get(‘TextField’).setDisabled(true);//不帶

IE8select控制元件的option顯示不全解決方案

 select控制元件,若option的內容過長,則IE8中顯示不全,導致其內容無法顯示出來。  目前測試IE9、IE11 select控制元件都沒有問題。 其中select,可以只針對個別的select,只要替換相應的class即可。  解決方案:

初學,Linux下gtk+,glade,一些控制元件的使用函式

連線glade gtk_init (&argc, &argv); GtkBuilder *builder; builder = gtk_builder_new (); gtk_builder_add_from_file (builder, "(路徑)檔名.glade"

在Activity引用控制元件以及控制元件的點選事件

今天我們要講的是在Activity中使用控制元件,我們在AndroidStudio中建立好了專案,會有一個Mainactivity,對了這裡推薦大家在使用AndroidStudio寫程式碼的時候,選擇project如下圖: 選擇這種結構呢,大家可以很清楚的看到專案目錄結構 良好的

WPF動態載入XAML控制元件

原文: WPF中動態載入XAML中的控制元件 using System; using System.Collections.Generic; using System.Linq; using System.Text;

MFCEdit控制元件垂直滾動條時,當文字超出時再顯示垂直滾動條

現在我需要實現這樣一個功能:      想要用edit控制元件本身的滾動條,並且設定該屬性,但是該滾動條會一直存在。效果如下圖,很是難看,當沒有輸入資訊時,也會出現垂直滾動條 其實,只有在文字超過設定的區域內才會顯示(在這我不知道如何上傳動態效果圖片,

WindowsXamlHost:在 WPF 使用 UWP 控制元件控制元件

原文 WindowsXamlHost:在 WPF 中使用 UWP 控制元件庫中的控制元件 在 WindowsXamlHost:在 WPF 中使用 UWP 的控制元件(Windows Community Toolkit) 一文中,我們說到了在 WPF 中引入簡單的 UWP 控制元件以及相關

vbMSHFlexgrid控制元件小總結

MSHFlexgrid控制元件的屬性有很多,現在我就簡單寫一些關於現在咱們正需要用到的屬性,希望這些解釋可以加深大家的理解。 row :指表格的行        rows:  表格的總行數 rowsel:選中行數,可以為一個範圍多行

layuicheched控制元件

<form class="layui-form" > <div class="layui-form-item"> <label class="layui-form-label">複選框</label> <div class="layui-input-b

ASP.NET驗證控制元件的使用

目錄 1.RequireFiledValidation  2.RangeValidation  3.CompareValidator  4.RegularExpressionValidator(正則表示式線上編輯器:http://tools.jb51.n

android學習筆記:在actionBar增加控制元件

1.在AndroidManifest.xml中新增配置activity屬性 <activity android:name=".killProcess" android:label="殺殺殺" android:theme="@styl

Qt QTreeWidget 加入控制元件——以QPushButton為例

QPushButton *topLevelButton = new QPushButton("Top Level Button"); ui->treeWidget->addTopLevelItem(topLevelItem); ui->tre

iOS開發學習-自定義控制元件賦值問題--在model的set方法控制元件賦值

在自定義控制元件的過程中,剛開始的時候碰到問題是如何給各控制元件動態賦值,最初的想法是把各控制元件屬性放在.h檔案中定義.然後在控制器內獲取資料一一賦值(可行),但是這樣就增加了控制器中的程式碼,比如給定一個場景: collectionViewCell中,有10個控制元件,需要顯示10個數據,這

Android在程式碼修改控制元件的位置

//這裡我用FrameLayout佈局為列,其他佈局設定方法一樣,只需改變佈局名就行 FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) photoView.getLayoutParams(); //

MFCpicture控制元件顯示圖片

1.開啟BMP圖片 CBitmap* m_pBitmap = new CBitmap; m_pBitmap->LoadBitmap(IDB_BITMAP1);   2.第一種方式,用CDC顯示 CDC *pDC = GetDlgItem(IDC_AAAA)->Ge