1. 程式人生 > >Unity UGUI開發設計及案例講解

Unity UGUI開發設計及案例講解

Unity——UGUI開發設計及案例講解
1.Unity4.6跟以前的版本的最大區別首先在於在層級檢視中點滑鼠右鍵時出現的彈出選單上,它把以前許多的選單項進行了歸類,比如cube sphere capsule….等整合到“3D Object”子選單中,而且多出一個UI子選單,它就是UI元件了。
    當我們點選UI->Canvas時,就會在場景視圖裡建立一個畫布,不過檢視預設是3D顯示方式,在Unity4.3以後,增加了一個2D與3D轉換按鈕,單擊此按鈕可在3D與2D顯示樣式之間轉換。 
    UI是2D,為何還要3D呢,在做一些比較複雜的專案時,給使用者看時是2D,但我們編輯時,有時還是要用到3D模式的。
2.Canvas是畫布,所有的UI元件就是繪製在這個畫布裡的,脫離畫布,UI元件就不能用。
    建立畫布有兩方式。一是通過選單直接建立,二是直接建立一個UI元件時,會在建立這個元件的同時自動建立一個容納該元件的畫布出來。
    不管那種方式創建出畫布時,系統都會自動創建出一個EventSystem元件,這是UI的事件系統。
一.Canvas元件
1Canvas元件的三種渲染模式
在Canvas中有一Render Mode屬性,它有3個選項,分別對應Canvas的三種渲染模式:Screen Space – Overlay、Screen Space – Camera、World Space

2Screen Space – Overlay:


 
此模式不需要UI攝像機,UI將永遠出現在所有攝像機的最前面(即在某個UI的前面是不能再新增其他元件的),就好像是給攝像機貼上了一層膜。它的最大好處是不需要攝像機,不需要燈光。

3Screen Space – Camera:


 
此模式需要提供一個UICamera,它支援在UI前方顯示3D模型與粒子系統等內容。
    不過此模式下,就需在 中給它掛一個攝像機。

    當掛上攝像機並選擇3D顯示模式時,我們選中這個攝像機,並移動它,可發現畫布會跟隨攝像機的移動而移動,且Game檢視顯示的UI其位置與大小均保持不變,如下圖所示:

     
    這種模式,雖然UI的顯示效果與第一種模式沒有什麼兩樣,然而,因在畫布與攝像機之間可放置三維物體或粒子系統,那麼就可做出許多絢麗的特效。
     
這一項是設定Canvas與攝像機之間的距離,其值越大,可在畫布與攝像機之間放很多的三維物體,預設是100,建議設定為100與200之間即可。
4World Space:
 
這個就是完全3D的UI,也就是把UI也當成3D物件,如攝像機離UI遠了,其顯示就會變小,近了就會變大。
5其它一些屬性:
 當有多個畫布時,決定誰在前,誰先顯示。
二.Canvas Scaler畫布的大小
 
Ui Scale Mode(大小模式)
當我們把Canvas中的Render Mode設為Screen Space – Overlay 或Screen Space – Camera時,此Canvas Scale中的Ui Scale Mode(大小模式)就可用,且其中有3個選項:
1Constan Pixel Size:固定畫素尺寸
 
2Scale With Screen Size:以寬度為標準縮放(螢幕自適應特性)
 
2.1  Reference Resolution:參考解析度
    在不同解析度下,控制元件顯示的大小有所不同,這要根據實際情況綜合考慮。
2.2  Screen Match Mode:螢幕匹配模式
Match Width Or Heigt:匹配寬度或高度
    此模式下會出現Match調節滑桿,調節其控塊位置,也會影響UI元素顯示的大小。
Expand:擴充套件
Shrink:收縮


3Constant Physical Size:固定物理尺寸
 
三.Panel 面板
當我們初次建立Panel後,它會充滿整個畫布,如下左圖:
   
此時通過拖動該面板控制元件的4個角點或四條邊可調節面板的大小,如上右圖
面板實際上就是一個容器,在其上可放置其他UI控制元件,當移動面板時,放在其中的UI元件就會跟隨移動,這樣我們可以更加合理與方便的移動與處理一組控制元件。也就是通過面板,我們可以把控制元件分組。一個功能完備的UI介面,往往會使用多個Panel容器控制元件。而且一個面板裡還可套用其他面板。
當我們建立一個面板後,此面板會預設包含一個Image(Script)元件:
 
該元件中的Source Image是設定面板的影象。
Color,可改變面板的顏色。
四.EventSystem事件處理系統
當我們建立一個畫布時,Unity系統會自動為我們建立一個EventSystem,
 
該事件處理器中有3個元件:
1.Event System:事件系統元件(事件)
2.Standalone Input Module:獨立輸入模組 (輸入)
3.Touch Input Module:觸控輸入模組 (觸控)
如果我們將Event System (Script) 前的勾去掉,則管理整個場景的事件系統則不起作用了,此時執行程式,如果有Button,單擊它時就不會有反應了。
五.Text控制元件
在UGUI中,我們所建立的所有UI控制元件,它們都有一個UI控制元件特有的Rect Transform元件:
 
我們所建立的三維物體,是Transform,而UI控制元件是Rect Transform,它是UI控制元件的矩形方位,其中的 指的是UI控制元件在相應軸上的偏移量。
UI控制元件除了上面Rect Transform控制元件外,每個UI控制元件都還一個 元件,它是畫布渲染,一般不用管它,因它不能點開的。
Text控制元件的相關屬性:
Character:(字元)
Font:字型
Font Style:字型樣式
Font Size:字型大小
Line Spacing:行間距(多行)
Rich Text:“富”文字。例如:U<b>G</b>U</i>I<volor=”yellow”>學</color>習
Color:字型顏色
Paragraph:(段落)
 :設定文字在Text框中的水平以及垂直方向上的對齊方式。
 :水平方向上溢位時的處理方式。它有兩種:Wrap隱藏;Overflow溢位。
 :垂直方向上溢位時的處理方式。它有兩種:Truncate截斷;Overflow溢位。
隱藏了或截斷了,資訊顯示不全當然不好,但如果溢位又會破壞版面,想兩全齊美的話,就可選中: ,如果文字多時,它會自動縮小以適應文字框的大小,當選中該項後,在其下邊會出現Min Size與Max Size兩輸入框,可設定字型變化時的最小與最大值。
六.Image控制元件
Image控制元件除了兩個公共的元件Rect Transform與Canvas Renderer外,預設的情況下就只有一個Image(Script)元件:
 
Source Image是要顯示的源影象,但如果我們把一個普通的影象往裡拖放時,卻不能成功放入,認真研究一下不難發現,放影象的框中,除了None表示還沒有影象外,還有一個括號註釋的Sprite,它的意思是精靈,可理解為它是貼圖的一種特殊形式,它不具備其他功能,只給UI做顯示圖片用,故我們給它取了一個特殊的名字:精靈Sprite,所以在Unity4.6中,要想把一個圖片賦給Image,則需要把該圖片轉換成精靈格式,轉換方法為,在Project中選中要轉換在圖片,然後在Inspector檢檢視中,單擊Texture Type(紋理型別)右邊的下拉框,在彈出的選單中,第三項Editor GUI and Legacy GUI是Unity4.6以前版本所用的,選中它時,圖片不會被拉伸,現在幾乎不用,是為了相容,而第四項Sprite(2D and UI),就是4.6版本所用的,它雖然比前一項適用的範圍更窄,但其效率更高。我們選中該選項Sprite(2D and UI)並點選下方的Apply(應用)按鈕就可把此圖片轉換成精靈格式,隨後就可拖放到Image的Source Imag中了,如下圖所示:
 
另:當我們把一個普通的圖片轉換成精靈格式後,在Project中,將發現該圖片將包含一個子物件如圖: ,以後可以把一個圖片劃分為多個圖片。
當我們把精靈圖片賦給了Image後,其元件樣式如下圖:
 
Color:可改變圖片的顏色;
Material:材質,這是針對一些複雜的貼圖使用。
Image Type:貼圖的型別,這是最重要的屬性。
   
1)Simple:簡單
 
Preserve Aspect:翻譯過來是:維持外貌,選中該項後,該精靈圖片的長寬比將保持原狀,當調節圖片的大小時,它將在保持原長寬比的前提下儘量鋪展到圖片框中,即不會拉伸或壓縮以適應圖片框而鋪滿。
Set Native Size:本來的大小。如果調整後大小變亂了,單擊此按鈕,可將此圖片設定成本來的大小
2)Sliced:片
應用該種類型時,應先將貼圖進行“九宮格”處理後才可以應用。否則其下會出現黃色的警告  This Image doesn’t have a border:這個圖片沒有邊框,如下圖:
 
            怎樣進行九宮格的處理呢?
            先在Project中選中該圖片精靈,然後在其Inspector檢檢視中單擊“Sprite Editor”按鈕即可進入九宮格處理Sprinte Editor視窗中,如下兩個圖所示:
   
在這個Sprinte Editor視窗中,我們可以拖動影象四條邊上的綠色線,調節九宮格的佈局大小,調好後單擊頂端的Apply按鈕應用即可,回到Image的檢檢視中,我們將發現原來的警告消失了:
 
在Image Type為Sliced時,當對影象進行大小調節時,其中心會縮放以適合矩形,但邊界會保持不變,這樣當你顯示不同尺度影象時,不用擔心擴大與縮小時其輪廓會發生變化。如果你只想要邊界,不要中心,可以禁用Fill Center(填充中心)屬性。
3)Tiled:平鋪
 
影象保持其原始大小,重複多次填補空白。這往往用於做背景。
4)Filled:填充
影象填充滿整個Image矩形區域,再結合Fill Amount屬性,可做一些特效。


 
當圖片型別為Filled時,其Image元件的屬性檢視如上圖所示,其Fill Method(填充方法)選擇框中有5種:
Horizontal:水平填充,如果我們手動拖動Fill Amount(填充數量)滑塊,就可看到圖片在水平方向上的填充變化(動畫),如下圖列所示:
     
Vertical:垂直填充,同理當我們手動拖動Fill Amount滑塊,就可看到圖片在垂直方向上的填充變化(動畫),如下圖列所示:
     
Radial 90:徑向90度填充,同理當我們手動拖動Fill Amount滑塊,就可看到圖片在90度方向上的填充變化(動畫),如下圖列所示,預設是以左下角為圓心,順時針90度填充。
     
Radial 180:徑向180度填充,同理當我們手動拖動Fill Amount滑塊,就可看到圖片在180度方向上的填充變化(動畫),如下圖列所示,預設是以底邊中點為圓心,順時針180度填充。
     
Radial 300:徑向180度填充,同理當我們手動拖動Fill Amount滑塊,就可看到圖片在360度方向上的填充變化(動畫),如下圖列所示,預設是以圖片的中心點為圓心,順時針360度填充。
     


如果我們使用指令碼來控制Fill Amount的值,就可製造出這五種動畫來,為特效的製作增加了一些有效的手段。


七.Button控制元件
當我們建立一個Button後,其Inspector檢視如下:
 
除了公共的Rect Transform與Canvas Renderer兩個UI元件外,Button還預設擁有Image(Script)與Button(Script)兩個元件。
元件Image(Script)裡的屬性與前面所講的Image控制元件的Image(Script)元件裡的屬性是一樣的,例如Source Image的影象型別仍為一個Sprite(精靈),通過為此賦值,就可改變此Button的外觀了,如果你為屬性賦值了圖片精靈,那麼此Button的外觀就與此精靈一致了。
Button是一個複合控制元件,它中還包含一個Text子控制元件: ,通過此子控制元件可設定Button上顯示的文字的內容、字型、樣式、字大小、顏色等,與前面所講的Text控制元件是一樣的。
Button(Script)元件裡的屬性:
 
1Interactable:是否啟用(互動性)
如果你把其後的對勾 去掉,此Button在執行時將點不動,即失去互動性了。
2Transition:過渡方式
它有四個選項 ,預設為Color Tint(顏色色彩)
1)None:沒有過渡方式。
2)Color Tint:顏色過渡    
Target Graphic:目標影象
Normal Color:正常顏色
Highlighted Color:經過高亮色
Pressed Color:點選色
Disabled Color:禁用色
Color Multiplier:顏色倍數
Fade Duration:變化過程時間
3)Sprite Swap:精靈交換。需要使用相同功能不同狀態的貼圖。
 
Target Graphic:目標影象
Highlighted Sprite:滑鼠經過時的貼圖
Pressed Sprite:點選時的貼圖
Disabled Sprite:禁用時的貼圖


4)Animation:動畫。最複雜,效果最絢麗。
 
其中的Normal Trigger、Highlighted Trigger、Pressed Trigger、Disabled Trigger等屬性是不能賦值的,它們是自動生成的。
當單擊“Auto Generate Animation”(自動生成動畫)按鈕時,系統會為你開啟一個New Animation Contoller(新建動畫控制器)視窗,要求你選擇動畫存放的路徑,所以我們要先在Project中新建一個資料夾,專門用來存放動畫,比如此資料夾取名為_Animator,此時就可選中此資料夾,並給此動畫取名(動畫的名預設為該Button的名字,當然其副檔名為controller),建立成功後,會在Project中的_Animator資料夾中可看到剛才建立的動畫檔案(動畫的名預設為該Button的名字),且在這個Button的Inspector檢檢視中可看到會為此Button增加一個Animator元件:
 
此元件的Controller的屬性值就為剛才建立的動畫,雙擊它即可開啟該動畫的Animator視窗,其中記錄的有四個動畫:Normal、Highlighted、Pressed、Disabled(通常狀態、滑鼠經過狀態、按下狀態、失效狀態),如下圖所示:
 
其實這個動畫還沒有,要做出這個動畫,需先選中這個Button,然後點選系統選單Window->Animation(注意不是Animator),就會開啟一個Animation動畫編輯視窗:
 
我們以此工具先來做一個簡單的幀動畫,在幀數框上單擊一下,原來的0便會選中,此時輸入數字1,表示對第1幀做動畫,此時的錄製按鈕 以及系統的播放按鈕 和動畫編輯窗中的幀數線均會變紅,表示現在處於記錄模式,你所做的操作會記錄成動畫的動作,如下圖所示:
 
假設我們想使它在第一幀時,該按鈕變大一點,我們就在Inspector中的Rect Transformr的Scale中操作,比如在x與y軸向上均增大到原來的1.05倍(因UI是在x-y平面上顯示,故不需設定Z值),如下圖所示:
 
同理,當第一幀設定完後,我們在幀數框中直接輸入數字2,就可編輯第2幀的動畫了,比如在x與y軸向上均增大到原來的1.1倍,再繼續設定第3幀在x與y軸向上均增大到原來的1.15倍,假設我們現在就只做這3幀動畫,已經完成了,那麼我們點選一下那個處於紅色暈光狀態下的錄製按鈕 ,結束錄製,再儲存一下場景,就會發現在Project檢視中_Animator/Button1下會增加4個動畫檔案Disabled、Highlighted、Normal、Pressed(如果不儲存將看不到這4個動畫檔案),這四個動畫剪輯就是源於我們剛才的錄製,雖然剛才我們只錄制了一次,而系統會為我們自動產生這四個動畫檔案。
動畫成功製作出來了,可執行起來看看效果了,但當我們執行起來時,就會發現那個按鈕會自動無限次地播放那個動畫,看起來就是不斷地顫動,那麼是什麼原因呢?
我們在Project檢視中,選中任意的一個動畫剪輯比如Disabled,在其Inspector檢視中可看到它的Loop Time屬性是處於選中狀態,意思是迴圈播放,那麼我們把它去掉即可。
 
而這裡,如果我們只去掉Disabled的Loop Time還是不行的,當然把這4個動畫剪輯的Loop Time全去掉是能成功的,那麼到底是那個剪輯在起作用呢?實際上是Normal,所以我們只需去掉Normal的Loop Time即可。其原因請看下列敘述。
我們先在Hierarchy檢視中選中那個做了動畫的Button,再單擊系統選單Window->Animation(注意不是Animator),就會開啟剛才的動畫編輯視窗:
 
單擊其中的Normal框,會出現下拉選擇:
 
    從這下拉選擇列表中可看出Normal前邊有個勾,這說明我們剛才所做的動畫是Normal。那麼根據此原理,我們可分別做出滑鼠經過該Button的Highlighted、該Button按下的Pressed、以及該Button失效的Disabled動畫了。
3Navigation
 
None:沒有
Horizontal:水平
Vertical:垂直
Automatic:自動
Explicit:明確的
4Visualize:顯現
5On Click()
在Button元件的下方有一個OnClick()選項,這就是Button控制元件處理事件的重要機制。
OnClick()意思為當該按鈕被點選時所發生的事件,而此事件在UI中是委託機制,要理解這個機制,我們先做一些準備工作。
1)建立指令碼檔案
假設此指令碼檔案被命名為ButtonEvent
using UnityEngine;
using System.Collections;
public class ButtonEvent : MonoBehaviour {
// Use this for initialization
void Start () {
}

// Update is called once per frame
void Update () {
}
}
這是系統預設的檔案內容,現在我們要把它應用於UI,故必須引入UI的名稱空間,即指令碼的首部增加一行:using UnityEngine.UI;。
假設我們單擊一個按鈕後,讓系統在後臺顯示一句話:點選了Button!,那麼我們可以在此指令碼中增加一個方法,該方法為公共的public,假設方法名為DisplayInfo:
Public void DisplayInfo(){
   Print(“點選了Button!”);
}
此時整個指令碼檔案的內容如下:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class ButtonEvent : MonoBehaviour {
// Use this for initialization
void Start () {
}


Public void DisplayInfo(){
   Print(“點選了Button!”);
}


// Update is called once per frame
void Update () {
}
}


2)在Hierarchy檢視的Canvas中建立一個空物件,並假設命名為Event,並把上面的指令碼作為元件掛到這個空物件上,那麼這個物件是具有事件處理能力的object了。
3)為某個按鈕新增其事件處理的委託物件
我們在層級面板中選中要產生單擊事件的按鈕比如Button1,然後拖動其Inspector面板右邊的滾動條,使其Button(Script)元件下的OnClick()顯現出來:
 
此時其事件列表為空:List is Empty,我們單擊其下的“+”按鈕為其新增一個事件:
 
此時事件雖被添加了,但其委託的事件處理物件為空:None(Object),當然連事件處理物件都沒有,其事件處理方法自然也就為空:No Function。(Runtime Only此項我們可先不管它,以後用到時再講)
那麼怎樣委託事件處理物件與選擇事件處理方法呢?
很簡單,我們把層級面板中剛才建好的並已掛上了事件處理指令碼的Event物件拖放到None(Object)框中即可,此時此框中顯示的內容即為委託的此事件處理物件的名稱了:Event,有了事件處理物件了,然後使用該物件的什麼方法來處理事件呢?這還需我們給它指定,其方法是單擊顯示內容為No Function的那個事件方法框,會彈出選單列表:
 
當我們的滑鼠指向最後一項ButtonEvent時會繼續展開,其中就有我們在指令碼中編寫的事件處理方法:DiaplayInfo(),選中它即可,這樣就完成了事件的委託,當我們執行時,單擊那個Button,就會在後臺裡打印出“點選了Button!”。
一個按鈕可以有多個處理事件。
下面我們採用另一種顯示資訊的方式。
我們先在場景中的畫布上增加一個Text控制元件,同時設定好相關的顯示樣式,然後在那個指令碼中增加一個公共變數:public Text Txt_Info,回到場景檢視中,在層級面板中選中掛有該指令碼的物件Event,在其Inspector檢視的ButtonEvent指令碼元件裡就會出現剛才增設的公共變數名:Txt_Info(指令碼需儲存且介面需重新整理),我們可把增加的那個Text拖到此處即可為此變數賦值了,接下來我們就可通過指令碼修改這個文字框控制元件的Text屬性,讓列印在後臺的資訊顯示在這個文字框上了。其指令碼檔案內容如下:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;


public class ButtonEvent : MonoBehaviour {
public Text Txt_Info;
// Use this for initialization
void Start () {
}

// Update is called once per frame
void Update () {
}


public void DisplayInfo(){
    print ("點選了Button!");
}
public void DisplayInfoText (){
    Txt_Info.text="Button被點選!";
}
}
然後再給那個Button增加一個單擊事件(委託的事件物件仍為Event,方法則設為DisplayInfoText ()):
 
再次執行程式,單擊按鈕時,後臺輸出“點選了Button!”的同時,場景中的Text文字框的內容內變為:Button被點選了!。
八 Anchor錨點與螢幕自適應
每個控制元件都有下Anchor的屬性,其作用是當改變螢幕解析度的時候,當前控制元件做如何的位置變換。即控制元件的螢幕自適應。
當我們建立一個Canvas後,在層級檢視中選中它後,我們將發現這個Canvas在場景檢視中的樣式如下圖所示:
 
這個Canvas除四邊、四個角點外,其中心還有一個藍色的小圓圈,這個小圓圈即為這個Canvas的中心點。
如果此時我們在此Canvas上建立一個Button,如下圖所示:
 
Button同理也有四條邊、四個角點、一箇中心點,此時我們選中Button,在Canvas中心點位置會出現一個小雪花圖案 ,這就是Button在Canvas上的錨點,可用滑鼠拖動它,且拖動的過程中會實時顯示此錨點距上、下、左、右的百分比,如下圖所示:
 
而且在Button的Inspector面板中,單擊Rect Transform中 按鈕,會開啟一個Anchor presets錨點調整窗,如下圖所示:
 
如果我們單擊  時,其錨點就會跑到Canvas的右上角,如下圖所示:
 
同理單擊其他位置時,也就把錨點調整到相應的位置上,即可把此錨點調整到畫布的中心點上、四個角上、四條邊的中點上。
以上是錨點整體移位。實際上,我們還可以拖動小雪花中的任意一個花瓣,使其分散成四個錨點,如下圖所示:
 
當我們單擊 這個窗中的最右邊或最下邊中一些按鈕可將錨點分散在兩邊或上下或四個角點上。
原來這個雪花狀的錨點是由四個錨點組成的複合體。
說了這麼多,那它到底有什麼用途呢?
兩個字,定位。
如圖: ,當螢幕大小發生改變時,Button的四個角點與對應的4個錨點的距離會保持不變,從而保證佈局不會隨著螢幕大小或者解析度的改變而改變,可相對有效地保證佈局不會混亂,以達到螢幕自適應的目的。
但要注意,控制元件的錨點總是相對於自己的上一級來定義的。例如,我們再在這個Canmas中建立一個Panel並調小它的大小,在Panel中建立一個Text,我們去調節這個Text的錨點時我們將會發現這個錨點總是相對於Text的上一級Panel來定義與變換位置的。
九、應用:登入介面
在畫布上:
1、兩個Text控制元件,分別命名為:Tex_UserName與txt_Password,其Text值分別為“使用者名稱稱:”與“登入密碼:”
2、兩個InputField控制元件,分別命名為:Inp_UserName與Inp_Password。
這兩個輸入域控制元件是前面還沒有介紹的新控制元件,在其層級Hierarchy檢視將其展開 ,可發現它也為一個複合控制元件,在主控制元件上還包含兩個子控制元件,一個為Placeholder與Text,其Text就是前面所介紹的文字控制元件,程式執行時使用者所輸入的內容就儲存在這個Text中,而Placeholder是佔位符,它表示程式執行時在使用者還沒有輸入內容時顯示給使用者的提示資訊,在這裡我們把它設定為“請輸入…”,設定方法是在層級檢視中展開這個InputField控制元件,選中其子控制元件Placeholder,在Inspecter檢視中可發現其Text(Sript)元件,修改其值為“請輸入…”即可,如下圖所示:
 
InputField控制元件與其他控制元件一樣,也有Image(Script)元件,自身元件InputField(script)中也有變換Transition屬性,其預設值也為顏色變換,除此之外,它有一個重要的屬性:ContentType(內容型別),有10個選項,如下圖:
 
1)Standard:標準的
2)Autocorrected:自動修正
3)Integer Number:整數
4)Decimal Number:十進位制小數
5)Alphanumeric:字母數字
6)Name:人名
7)Email Address:郵箱
8)Password:密碼
9)Pin:
10)Custom:定製的
據此,我們把第一個InputField的內容型別設為第5個Alphanumeric:字母數字,第二個InputField的內容型別設為第8個Password:密碼,這樣程式就可啟用其自動驗證功能,例如在使用者名稱稱輸入框中如果你輸入的不是字母或數字則不能輸入進去,第二個密碼框中輸入密碼時它會預設以*號佔位輸入的密碼。
    3、建立一個Text,用於顯示登入是否成功等提示資訊用,在其Inspector檢視中,去掉其預設顯示的內容,即讓其才開始執行時不顯示任何內容,並把其Best Fit勾選上,讓其提示資訊自適應文字框的大小:
 
4、最後建立一個提交按鈕,其整個介面如下圖所示:
 
5、建立指令碼(紅色部分為新增內容):
using UnityEngine;
using System.Collections;
using UnityEngine.UI;


public class LogonSystem : MonoBehaviour {
public Text Txt_DisplayInfo;
public InputField Inp_Username;
public InputField Inp_Password;


// Use this for initialization
void Start () {

}



public void DisplayInfo(){
string strUserName = Inp_Username.text;
string strPW = Inp_Password.text;
if(CheckLogonInfo(strUserName,strPW)){
   Txt_DisplayInfo.text="登入成功!";
}else{
   Txt_DisplayInfo.text="使用者名稱稱或登入密碼錯誤 請重新輸入!";
}
}


private bool CheckLogonInfo(string strUserName,string strPW){
bool ReturnFlag = false;
if (strUserName != null && strPW != null) {
if(strUserName.Trim().Equals("Admin") && strPW.Trim().Equals("123456")){//兩個輸入框中的內容去掉前後空格,如果使用者名稱稱為Admin、登入密碼為123456時,則表示登入,將ReturnFlag標記為真true。
    ReturnFlag=true;
   }
}
return ReturnFlag;
}
}
指令碼建立好了後,我們在Hierarchy中建立一個空物件,命名為_LogonSystemEvent,對把這個指令碼掛在它身上,而且在其Inspector檢視中,為其3個公共變數賦值(把相應控制元件拖放到對應變數的值框中):
 
執行程式,如果使用者名稱稱或密碼錯誤,提示資訊框中會顯示:使用者名稱稱或登入密碼錯誤 請重新輸入!,否則顯示:登入成功!,如下圖所示:
   
十、Toggle控制元件動態事件
Toggle:開關,當我們建立它後 ,可發現它也為一個複合型控制元件 ,它有Background與Label兩個子控制元件,而Background控制元件中還有一個Checkmark子子控制元件,如果我們將其拖散 可清楚地看見,Background 是一個影象控制元件,而其子控制元件Checkmark 也是一個影象控制元件,其Label控制元件 是一個文字框,它們與我們所講的控制元件是一致的,我們通過改變它們所擁有的屬性值,即可改變Toggle的外觀,如顏色、字型等等。下面來看看Toggle的一些重要屬性。
1Is On:目前是處於開還是關。
    當我們執行起來,用滑鼠點選那個Toggle按鈕,將發現其中的對勾符號會在出現與不出現之間切換,同時與之相對應的,在其Inspector面板中,屬性In On後面的對勾也在勾選 與不勾選 之間切換。
2Graphic:影象
實際上,用滑鼠點選那個Toggle按鈕,其對勾符號會在出現與不出現之間切換,它的原理就是控制那個對勾影象出現與不出現而實現的,這個Graphic就是設定這個屬性值的,你可點選 最後那個設定按鈕 ,在出現的窗體中 選擇另外的影象如Background,同時將 中的Target Graphic的值設為Checkmark,即將它們兩者的值互換,將發現,當我們點選Toggle按鈕時,其對勾不會消失與出現,而是背景消失 與出現 。這樣做雖然沒有多大實用價值,但說明Unity可以方便地控制這個按鈕的外觀。
3Group:組(單選框功能)
在Hierarchy面板中,選中我們剛才建立的Toggle,然後按鍵盤Ctrl+D兩次,就可複製出兩個Toggle了,並在場景檢視中拖動它們的位置,使它們都可見,執行,我們將發現這個三個都可選中,即它們是複選框。
那麼怎樣做出單選的效果呢?
前面所建立的按鈕是獨立的,互不關聯,當然就可獨自地選與不選。如果我們把這三個組成一個組,讓它們關聯,就可做成單選了。
 
從Group屬性可看出它需要一個ToggleGroup。
我們先在畫布上建立一個空物件,並命名為_ToggleGroup,在其Inspector中單擊 這個按鈕,為其新增元件,在彈出的選單中選擇UI,在後續彈出選單中
   
選擇“Toggle Group”,這樣我們就為此物件添加了ToggleGroup元件了。
在Hierarchy中同時選中要成組的那3個Toggle,把已添加了ToggleGroup元件的_ToggleGroup拖到Inspector的 中即可,這樣我們便把這3個Toggle成組了,於是它們3個就只能單選其中一個了。
為了更完美,首先調整空物件_ToggleGroup的位置與大小,讓其包含那3個Toggle控制元件,然後在Hierarchy中,把3個Toggle選中並拖到_ToggleGroup中成為子物體 ,這樣在邏輯上與外觀上均完備,且移動父物體時子物體也會跟著移動。


4Toggle控制元件動態事件On Value Changed(Boolean)
 這是Toggle的事件處理,它與Button的事件有所不同,下面來看看怎樣給Toggle新增事件。
我們把Toggle的標籤改成裝備名稱,再在場景中增加一個顯示選取的裝備名的文字框:
 
編寫指令碼:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;


public class _ToggleEvent : MonoBehaviour {
public Text Display;
private string info;
// Use this for initialization
void Start () {

}

public void Toggle1(bool isclik){
if (isclik) {
  info="屠龍寶刀";
  Display.text=info;
 }
}
public void Toggle2(bool isclik){
if (isclik) {
  info="倚天劍";
  Display.text=info;
 }
}
public void Toggle3(bool isclik){
if (isclik) {
  info="降龍十八掌";
  Display.text=info;
 }
}
}
在Canvas中建立一個空物件,把此指令碼掛接到此物件上,並把場景中的Text賦給public Text Display這個變數,然後分別選中那3個Toggle,在其檢檢視中單擊事件下的“+”號: ,單擊後就為該控制元件添加了事件,如下圖:
 
然而,事件要委託給一物件,現在還沒有,顯示的是 ,此時把已經掛接上了指令碼的那個空物件拖放到此處,便委託事件處理物件了,如下圖所示:
 
有了事件處理物件,但還沒有指定方法,此時單擊 會出現下圖所示的選單:
 
滑鼠指向我們為此物件所掛的指令碼名_ToggleEvent時就會繼續展開一個選單,其中就有我們在此指令碼中編寫的方法Toggle1(bool)、Toggle2(bool)、Toggle3(bool)。這個選單與Button的有所不同了,Button的如下圖所示:
 
比較這兩個選單可發現Toggle多了上面的那部分:
 
下面的 是靜態方法,上面的 是動態事件,是系統自動生成,其bool型引數已被封裝在其中了,此時我們不能象Button那樣去選擇其靜態方法了,而要選擇與之對應的動態事件才可正常運行了。
Toggle與Button在事件處理上的的區別不只是上面所談到的那一點,還有其他區別,如:
Button事件元件面板的上部顯示的是 
Toggle事件元件面板的上部顯示的是 
Button是當Button被單擊時發生,Toggle是當Toggle選中與不選中(即其值發生改變)時發生,且還有一個布林型引數,選中時傳進給引數的值為真,反之為假,所以在前面指令碼編寫中,其方法裡我們要設定對應的布林型引數來接受這個值:
public void Toggle1(bool isclik){
if (isclik) {
  info="屠龍寶刀";
  Display.text=info;
 }
}
根據上面的分析可知,Toggle選中與取消選中時都會產生事件,那麼在一組單選按鈕組中,當我們點選另一個按鈕同時會取消前一個按鈕的選擇,那麼這兩個按鈕就都會產生事件,為了證明這一點,我們將前面的指令碼稍作改變:
public void Toggle1(bool isclik){
print("屠龍寶刀");
if (isclik) {
  info="屠龍寶刀";
  Display.text=info;
 }
}
public void Toggle2(bool isclik){
print(倚天劍");
if (isclik) {
  info="倚天劍";
  Display.text=info;
 }
}
public void Toggle3(bool isclik){
print(“降龍十八掌");
if (isclik) {
  info="降龍十八掌";
  Display.text=info;
 }
}
以前的程式碼是當選中即isclik為真時才顯示相關資訊,而取消選中,雖然事件也產生,但因isclik為假,所以不會顯示資訊,所以我們便覺察不出來,而現在加上了一個print語句,這樣只要事件發生了,就都會在後臺裡打印出相關資訊來,如下圖所示:
 
這是首次執行選中“屠龍寶刀”時的情況。
 
接著我們選中“倚天劍”時,“屠龍寶刀”也被取消,“倚天劍”與“屠龍寶刀”都產生了事件,所以會打印出各自的資訊。
 
再在這基礎上選中“降龍十八掌”,“倚天劍”被取消,同時“倚天劍”與“降龍十八掌”均產生了事件,所以倚天劍與降龍十八掌相關資訊都會打印出來。
以上就是Toggle的事件處理機制,如果我們Toggle不是單選而是複選,那麼我們又怎樣在那個文字框中顯示出多選資訊呢?
這個問題看似很難,實際上很簡單,程式碼如下:
public void Toggle1(bool isclik){
if (isclik) {
  info += "屠龍寶刀";
  Display.text=info;
 }
}
public void Toggle2(bool isclik){
if (isclik) {
  info += "倚天劍";
  Display.text=info;
 }
}
public void Toggle3(bool isclik){
if (isclik) {
  info += "降龍十八掌";
  Display.text=info;
 }
}
把info的賦值符號=變成+=,這樣就把info的值累加起來了,也就記錄下了多選值了。這雖然簡單,但不完善,如果先選中,然後又去掉,但先新增進去的值卻不會去掉,這需要進一步地處理才行。
5事件執行模式
在事件元件面板中,第一個選項框中的值我們在Button時就是一直使用的是其預設值:Runtime Only,如下圖所示:
 
當我們單擊該選項時,出現的下拉選單如下:
 
Off:關閉事件處理功能;
Editor And Runtime:編輯與執行時,其事件處理功能均起作用;
Runtime Only:僅在執行時,其事件處理功能才起作用。


我們假設把Toggle1方法改成如下所示:
public void Toggle1(bool isclik){
print ("屠龍寶刀");
info = "屠龍寶刀";
Display.text=info;
}
然後把第一個Toggle的事件處理物件及方法置空,並把事件執行模式變為Editor And Runtime,此時再為它新增事件物件及方法,我們將發現在新增結束後,其事件便立即發揮作用了,如下圖所示,當然程式執行時也能發揮其功效的,這就是“編輯與執行時,其事件處理功能均起作用”的意思。
 
    此功能可以為我們程式設計師提供預覽、事前先知的功能,方便我們編輯。
十一、Slider控制元件(滑動條)
1、Slider也是一個複合控制元件 ,Background是背景,預設顏色是白色,我們保持不變;Fill Area是填充區域,其子控制元件Fill中只有一個Image(Script)專有元件,假設我們將其顏色改為紅色;Handle Slice Area中的子控制元件Handle(手柄)中也只有一個Image(Script)專有元件,假設我們將其顏色改為黃色,那麼Slider的外觀為: 
2、當我們在Hierarchy中選中Slider控制元件,其Inspector中的Slider(Script)屬性面板如下圖所示:
 
上部的Interactable、Transition與前面介紹的控制元件是差不多的,下面談談它特有的一些屬性:
Fill Rect:填充矩形區域
Handle Rect:手柄矩形區域
Direction:Slider的擺放方向,可以從左到右、從右到左、從上到下、從下到上
Min Value:最小數值
Max Value:最大數值
Whole Numbers:整數數值。假設我們將Min Value設為1,Max Value設為100,那麼調節手柄時,對應的值在1到100之間,而且是一個小數,如55.67,有時我們希望它是整數,那麼選中該項即可。
上面的後4項Direction、Min Value、Max Value、Whole Numbers都比較好理解,而前2項Fill Rect與Handle Rect較困難,下面我們做一個實驗便可知其意義了。
我們再建立一個Slider控制元件並命名為Slider2,並把其所有子控制元件的名字改成在其預設名後加2的名字,再把先前的那個Slider改名為Slider1,也把其所有子控制元件的名字改成在其預設名後加1的名字,如下圖:
 
此時我們先選中Slider2,然後把Slider1的子子控制元件Fill1拖到Slider2的Fill Rect中,如圖:
 
執行程式,當我們調節Slider2的手柄時,我們將發現Slider1的填充區域在發生變化,為什麼呢?因為預設情況下Slider2的Fill Rect是它自己的Fill2,而我們現在把Slider1的Fill1賦給了它,作為它現在的Fill Rect物件,所以就會出現此種情況,這就是Fill Rect的功效。
在上面的實驗中,我們把Slider1用來做顯示,Slider2用來控制,如果能把Slider1中黃色手柄隱藏起來就更好了:
 
這也是能做到的,我們選中Slider1的子子控制元件Handle1,在其Inspector檢視中,將其Image(Script)前面的對勾去掉 ,這樣就不會顯示那個手柄了:
 
3、Slider的動態事件
假設我們想在拖動手柄的時候,讓其值顯示在右邊的一個文字框中,如下圖所示:
 
這就要用到Slider的動態事件了 
 指的是Slider的滑塊滑動其值發生改變時而產生的動態事件,它有一個引數Single:單精度,實際上這裡指的是float,整個事件的機理是,當滑動滑塊時,其值發生改變,事件產生,而且會實時將滑塊所對應的值傳給此事件,儲存在這個引數中,供程式使用。
根據此原理,我們建立下列指令碼SliderDemo:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;


public class SliderDemo : MonoBehaviour {
public Text Txt_diaplayValues;
// Use this for initialization
void Start () {

}

public void DisplaySliderNumber(float floValues){
Txt_diaplayValues.text = floValues.ToString ();
}
}
然後在場景中建立一個空物件,把此指令碼作為元件掛在這個空物件上,再在場景中建立一個文字框,並賦給 public Text Txt_diaplayValues變數。
最後一步就是註冊事件了,單擊 中的“+”按鈕,為其新增事件 ,把前面建立的並已掛上指令碼的那個空物件拖到 中為其委託事件處理物件 ,再指定事件方法,單擊 :
 
選擇指令碼名SliderDemo中的方法DisplaySliderNumber,不過這裡不能選擇DisplaySliderNumber(float),而要選上面的DisplaySliderNumber動態事件(其原因請見前一節的敘述)。
執行程式就可達到要求了。
十二、ScrollBar控制元件(滾動條)
 
其屬性: 與前面的Slider差不多,動態事件也是一樣的,這裡就只談其特有的屬性:
Value:當拖支滑塊時,其值是在0到1之間變化的
Size:是滑塊的大小,如果把它改成0.5,滑塊就會大到佔滑條的一半大。
Number Of Steps:數值的步驟。假設設定為5,那麼就會把Value分成5個值,調節滑塊時其值就在這5個值中變化。
十三、一個簡單的遊戲主介面
 
右邊藍底色中的“生化危機”為Text;開始、設定、結束為Button,並加上簡單的幀動畫Highlighted(見前面的動畫過渡)
左邊淡黃底色區域為面板panel,它為父控制元件,其中所包含的所有控制元件均為它的子控制元件,遊戲難度下的三個選擇鈕為單選按鈕組,其設定方法請參見前面Group。
這個面板,通常情況下是不可見的,當單擊“設定”按鈕時面板從左外側滑入而可見,進行設定後單擊面板中的“確定”按鈕後,面板又滑出到左外側處於不可見狀態。這是一個動畫,其設定方法與Button動畫相似,但它不是利用Button那種自動生成動畫的方法而建立的。
下面我們先來建立面板的動畫過程:
首先,在Hierarchy面板中選中要建立動畫的Panel,單擊主選單Window中的Animation(注意不是Animator)出現Animation視窗:
 
此時單擊頂端最左側紅色按鈕,它為動畫錄製按鈕,會彈出一個對話方塊,要求為將要錄製的動畫選擇儲存位置與動畫的名稱,如下圖:
 
假設我們將此動畫儲存在Assets下的_Animation資料夾中,並取名為ShowPanel.anim,單擊儲存後,其介面如下:
 
錄製的動畫是面板從不可見到可見的顯示動畫,那麼在第0幀時面板是不見的,所以此時把面板水平向左拖動到畫布的左外側,如下圖所示:
 動畫錄製機會記錄下此時物件的位置,其Inspector面板中的RectTransform引數會發生改變:
 ,即在第0幀時,面板在X:-140,Y:-1.3751e-05處。
接下來我們把幀數框中的幀數改為60幀,即設定第60幀時面板的位置(設為60幀的原因是,面板從第0幀的位置變化到第60幀的位置時其動畫時間大約為1秒鐘),此時錄製面板中的那條紅色豎線將移動到1:00處,如下圖:
 
根據動畫設計要求,此時面板應該是完全可見的,所以我們把面板水平向右拖到畫布中,動畫錄製機同樣會記錄下此時面板的位置 ,其設定視窗如下圖:
 
我們還可發現,在現在位置的紅線處會出現象0幀處的關鍵幀圖示: 。
我們在 上單擊一下,其展開圖如下:
 展開的那兩項分別表示在此過程中,物件在X軸上位移了131,Y軸上為0。
從底部的 處可見,現在的檢視是Dope Sheet(關鍵幀清單),當點選Curves(曲線)時,會轉換為曲線檢視,如下圖
 
如果曲線過大顯示不全或過小看不清時,可調節滑鼠中鍵滑輪,縮放曲線到適當大小。
圖中水平綠色線 所包含的區域即為動畫區域,曲線上的紅色點為關鍵幀點,可看出此動畫只有兩個關鍵幀,用滑鼠單擊關鍵幀時,Scene檢視中的面板就會移動到所設定的位置上。
設定好後,單擊紅色的錄製按鈕一下,即可停止錄製且儲存動畫。
這是顯示面板的動畫,下面我們來設計隱藏面板的動畫。
單擊已經顯示出剛才錄製的動畫名為ShowPanel這個框右邊的按鈕,彈出:
 
單擊[Create New Clip],建立一個新的動畫剪輯,此時會同樣彈出一個要求你為新動畫取名以及選擇儲存路徑的對話窗,假設我們為此動畫取名為HidePanel.anim,路徑與前一個動畫相同,其後的動畫設計與前邊一樣,只不過第0幀時,面板在畫布上,第60幀時,面板在畫布外。
動畫建立結束後,即可直接關閉錄製窗體,系統會自動儲存動畫檔案。回到系統介面下,在Project檢視中的我們事先設定的儲存動畫的_Animator資料夾下將會新增三個檔案: ,而且在Hierarchy檢視中選中已設定了動畫的控制元件Panel,在其Inspector檢視中將發現系統會為其自動增加動畫元件Animator。
好了,萬事具備,執行程式,但發現那個面板的顯示動畫會不斷地重複播放,其原因是其Loop Time的屬性值為True,如果設為False即可去掉其預設的自動播放特性。方法為,在Project檢視中選中 動畫,然後在其Inspector檢視中,把 後的鉤去掉即可(同理,其HidePanel動畫也做這樣的處理),但程式執行時,面板雖不會重複播放顯示動畫了,但它會播放一次,這與我們的設計初衷不符,我們的初衷是程式執行時不顯示面板,當我們點選設定按鈕後才會顯示面板,點選面板中的確定按鈕後,隱藏面板。要達到這種功能,就要設定動畫狀態機中的一些屬性以及配合使用指令碼才能完成。
首先,讓動畫不自動播放。
在Hierarchy檢視中選中設定了動畫的控制元件Panel,可發現其Inspector檢視中Animator元件中的第一個屬性Controller(控制器,也稱動畫狀態機)的值為前邊錄製的 動畫:Panel,如圖: ,單擊其後的設定按鈕 可更改為其他動畫,不過這裡是不需更改的,我們雙擊動畫框中的已有的動畫Panel,會開啟Animator視窗:
 
其中有兩個按鈕代表的就是按鈕文字所指示的動畫剪輯:ShowPane、HidePanel,即現在這個Panel動畫裡有兩個動畫剪輯。我們在面板的空白地方單擊滑鼠右鍵: ,選擇第一項Create State中的Empty,建立一個空動畫,其預設名為New State,如圖:
 
在New State上點右鍵,在彈出的 中選第二項Set As Default,即設定這個空動畫為預設播放的動畫,既然為空動畫,自然就不會播放動畫,經此設定後的視窗如下圖所示:
 
比較設定前後兩圖可發現,代表預設動畫的按鈕的顏色為黃紅色。即哪個按鈕為黃紅色,那個動畫剪輯就是當前動畫播放時的狀態位置,動畫狀態機的命名來源也許就是這個原因。
經此設定後,再次執行程式,就不會有動畫播放了。但也許你會發現那個面板仍然顯示出來了,出現這種情況,不是動畫造成的,因現在雖然沒有動畫,但那個面板本來是存在的,當然要顯示出來,如果想要它一開始就不顯示,我們只需在場景編輯檢視中將其位置拖到畫布之外即可達到目的,如下圖:
 
通常情況下,一個動畫裡有許多的動畫剪輯,到底播放哪個動畫,是動畫狀態機來決定的。 這個介面就是動畫狀態機介面,它表示現在的動畫播放的是它中的哪個動畫剪輯。那麼,我們有什麼辦法來控制動畫狀態,或者說讓動畫在不同的剪輯中交替轉換呢?
我們在“New State”上單擊滑鼠右鍵,選擇第一項Make Transition(設定轉換),然後直接移動滑鼠,將會出現一個帶前頭的連線,再在”ShowPanel”上單擊滑鼠左鍵,即可在這兩個動畫剪輯上建立轉換聯接: ,這個連線表示,當滿足某個條件時,就可由播放剪輯New State變成播放剪輯ShowPanel,即使ShowPanel處於播放狀態。這個條件又在哪裡設定呢?單擊 右邊的“+”按鈕,在彈出的 中選Bool,即設定一個布林型引數,並把此引數假設命名為IsDiaplay,如圖 。
設定好引數後,用滑鼠單擊那根連線線,它將變成藍色,表示選中,如圖:
 
接下來,在其Inspector檢視中的Conditions設定條件變數為剛才建立的IsDiaplay,條件值為true,如下圖:
 
其意思為,當IsDiaplay為真true時,動畫播放狀態由New State轉變為ShowPanel。
同理,可設定由HidePanel到ShowPanel轉變條件也為當IsDiaplay為真true時。
 
這兩步設定的結果我們可以這樣理解,當IsDiaplay為真true時,動畫播放狀態處於New State或HidePanel時,都將轉到去播放ShowPanel。
依此類推,當IsDiaplay為假false時,動畫播放狀態如果處於ShowPanel時,將轉到去播放HidePanel。這樣其動畫狀態我們就設定完了,如下圖:
 
接下來我們利用指令碼去改變那個變數的值,就可實時控制動畫的播放了。
指令碼內容如下(紅色部分為增加的指令碼內容):
using UnityEngine;
using System.Collections;
public class SettingPanelDisplay : MonoBehaviour {
public Animator Ani_SetPanel;
void Start () {
}
public void ShowPanel(){
Ani_SetPanel.SetBool ("IsDiaplay",true);
}
public void HidePanel(){
Ani_SetPanel.SetBool ("IsDiaplay",false);
}
}
在場景中建立一個空物件,把指令碼掛在它身上,並在Inspector檢視中把Hierarchy中的Panel賦給Ani_SetPanel,如圖: 。
指令碼中Ani_SetPanel變數是Animator型別,為何可以把控制元件Panel賦值給它呢?道理是Panel控制元件已經有了Animator元件,程式會自動抽取其中的Animator出來賦值給變數Ani_SetPanel。
Ani_SetPanel.SetBool ("IsDiaplay",true);其中的IsDiaplay就是在狀態機中增設的引數,其拼寫必須與狀態機中的完全一致,否則不能執行。
最後設定“設定”與“確定”兩個按鈕的委託事件,具體設定過程請參見前面的Button事件。
至此,這個簡單的遊戲主介面便建立完工,可執行程式檢視效果了。
十三、高階控制元件 滑動區域ScrollRect
滑動區域控制元件ScrollRect是在一個較小區域顯示較多內部控制元件的一種機制。在UI系統中,這種控制元件的原型是沒有的,它是我們開發者利用UI系統裡已有的基本控制元件組合而成的。不過在UI系統裡有ScrollRect這個類,即它是一個元件,不是控制元件。控制元件與元件有什麼區別呢?簡單地說,在一個控制元件裡可以新增元件,如在Button上可新增Animator元件。有些控制元件在建立時,它會預設自帶一些元件,如Panel會自帶Image元件,如圖: ,其帶括號的Script就表示這個Image是元件,因在UI系統裡有Image這個基本控制元件的,故加上一個帶括號的Script來區別控制元件與元件,說明此處的Image是元件而不是控制元件。同理,當我們建立一個Button控制元件時,預設情況下我們可以在其Inspector視圖裡發現它帶有Image與Button兩個元件的,如下圖:
 
因在UI系統裡有Image、Button這些基本控制元件,這裡加上(Script)說明這個Image、Button不是控制元件而是元件。
這好像有點混,怎麼Button控制元件裡含有Button元件呢?
實際上我們可以這樣理解,元件是一個指令碼,是一個類,控制元件是這個類的例項化物件,是一個具體實現,所以Button控制元件裡含有Button元件就好理解了。再一個,類之間可以繼承,所以一個控制元件可以包含多個不同型別的元件。
根據上面的敘述,ScrollRect是待開發者自己去建立的控制元件,我們姑且把它稱作隱形控制元件。下面我們來建立這個控制元件。
1、建立一個畫布Canvas,在畫布上建立兩個空物件,其中一個命名為ScrollRect,另一個命名為Content,再建立一個Scrollbar。調整它們的大小與位置,大致如下:
 
2、在Content上建立幾個子物件,這裡我們建立4個Button,並調整它們的位置,使它們平鋪在Content中,同時設定Button的Image的SourceImage的值(掛上圖片,普通影象掛不上,應轉換成精靈,請參見前面的Image)。
 
3、組裝ScrollRect:3個元件2個屬性
新增ScrollRect元件:選中空物件ScrollRect,在其Inspector檢視中單擊“AddComponent”按鈕,選擇UI中的Scroll Rect,這樣便為這個空物件新增上了ScrollRect元件。此元件裡有2個重要屬性Content、Horezontal Scrollbar,其功能簡單說是用滑動條的滑動去控制內容區域的移動。根據此原理我們把Hierarchy檢視中的Content與Scrollbar分別拖掛到這兩屬性值框中即完成了物件的指定工作。試執行程式並拖動滑動條,發現Content中4個按鈕圖片確實能隨著滑動條的移動而移動了,如圖:
 
    但這還不完美,如果能隱藏多餘的內容,只顯示特定區域的內容,就象網頁中的滾動條那樣就好了,如下圖所示:
 
要達到此功能,還要為已添加了ScrollRect元件的物件增添Image、Mask(遮罩)兩個元件,其新增方法與上一致。
至此,組裝ScrollRect的3個元件ScrollRect、Image、Mask ,2個屬性:ScrollRect中的Content、ScrollRect中的Horezontal Scrollbar已完備,但當我們執行時,其效果仍然與前面相同,不能隱藏多餘部分。如果在Hierarchy檢視中我們把Content拖到ScrollRect上,使Content成為ScrollRect的子物件,就可達到我們想要的效果了。
 
其原因是,我們所新增的Image與Mask是在ScrollRect上,那麼用影象去遮罩的物件是ScrollRect,所以我們要把Content作為ScrollRect的子物件才能達到此效果。
十四、高階控制元件 標籤頁面TabPage
          
如圖,當我們點選頂部不同的標籤時,下部的內容區域會顯示對應的內容版面。
1、在畫布上建立一個空物件,命名為Lable,建立一個Image,佈局上Lable在上面,Image在下面,如下圖:
 
2、在Lable中建立三個子控制元件,它們均為Toggle,命名為Toggle1、Toggle2、Toggle3,並調整它們的Background與Checkmark,使其看起來像按鈕:
 
調整方法:
 
Background是背景,是未被選中時表現出來的圖景。首先在場景檢視中將其大小調大,使其與整個按鈕形狀一樣大,然後在其Inspector檢視中的Image元件裡設定Source Image或Color屬性值,這裡為了簡便,我們將其Color值設為較暗的灰度色,用於它未被選中時展現出來的顏色。
 
Checkmark是選中時表現出來的圖景,預設是一個對鉤,同理首先在場景檢視中將其大小調大,使其與整個按鈕形狀一樣大,這樣一來,Checkmark與Background一樣大,兩個重疊起來了,當未選中時,表現出來的是Background的景象,選中後表現出來的是Checkmark的景象。對於Checkmark的調整,然後在其Inspector檢視中的Image元件裡設定Source Image或Color屬性值,這裡為了簡便,將Image元件裡的Source Image屬性設為空None,即去掉那個對鉤影象,並將其Color值設為較亮的灰度色,用於它被選中時展現出來的顏色。
這三個按鈕狀的Toggle按設計思路應該為單選,所以按以前所學的知識,需設定它們的Group屬性值為Lable ,同時,對於它們的Is On屬性,第一個Toggle的保持勾選,另兩個去掉勾選,即使開始時,第一個處於預設選中狀態。
3、在Image上建立三個為空的子控制元件,分別命名為Page1、Page2、Page3,並調整它們的大小,使其與Image一樣大,位置上與Image重疊。再在Page1、Page2、Page3上各自建立一個Text子控制元件,也調整它們的大小大致與Image相當,且位置上也與Image重疊,並分別輸入要顯示的文字內容。這三個Text是重疊在一起的,顯示時,其內容也會重疊,如果我們只勾選第一個Text的父控制元件Page1的 ,另兩個去掉勾選,那麼顯示時會預設顯示第一個,另兩個處於未啟用狀態,不會顯示出來,自然就不會發生顯示的重疊了。
4、最後一步我們來實現當我們點選頂部不同的標籤時,下部的內容區域會顯示對應的內容版面。
也許你會認為這要用到指令碼,實際上有更簡便的方法,當然會離不開事件處理機制的。下面以Toggle1為例,選中它,在其Inspetctor檢視中,單擊:
 
中的“+”號,為其新增事件,如下圖:
 
委託事件處理物件,這裡我們把Page1拖給 如下圖:
 
指定事件處理方法:
 
雖然我們沒有編寫自己的指令碼,但Unity有內建的許多方法的,這裡我們選擇第二項GameObject:
 
選擇上邊的動態方法:SetActive,設定結果如下圖:
 
這個事件的執行機理是:當Toggle1的選中狀態發生改變時(注意是狀態發生改變,選中時會產生事件,那麼由選中到取消選中,也會產生事件),所掛接的物件Page1會被啟用或失效。
根據這個原理,Toggle2的事件委託物件為Page2,Toggle3的事件委託物件為Page3,這樣就實現了當我們點選頂部不同的標籤時,下部的內容區域會顯示對應的內容版面了,如下圖:
   
十五、大型遊戲案例UI開發
 
 
1、結構搭建
在Project中建立一些資料夾
 
我們這裡先把一些貼圖導進Sprits中,並把它們轉化為Sprint,其轉化方法請參見前面的Image控制元件中的影象精靈。
2、配置Canvas引數
在Hierarchy中建立UI畫布Canvas,其Inspector中的Canvas、Canvas Scaler(Script)設定如下:
Canvas:
 
Render Mode:渲染模式設為Screen Space – Came,這種模式可在畫布與攝像機之間放三維物體,做出更絢麗的介面。
Render Camera:既然渲染模式為Screen Space – Came,那麼在此處就需為此設定渲染所用的攝像機了,我們把Hierarchy中的主攝像機更名為UICamera後並拖到此處,為此指定渲染所用的攝像機。
Plane Distance:直譯過來為“平面距離”,這裡表示的是畫布距攝像機的距離,預設為100個單位,雖然距離越大,在畫布與攝像機之間所放的三維物體越多,但一般設成200個單位,這裡我們設成200。
Canvas Scaler(Script):
 
Ui Scale Mode: 選第2項,自適應螢幕寬。
Reference Resolution:參考解析度,應根據應用情況而定,這裡我們設成800×600,即畫布的大小寬為800畫素,高為600畫素。
Screen Match Mode:螢幕自適應模式, 選第1項,自適應寬或高。
3、建立背景
在畫布上建立一個Image控制元件,命名為Background,併為其賦值一個Sprits貼圖作為背景圖:
 
此圖看起來會是朦朧的,究其原因是因其預設為半透明狀,將其設為不透明,即可解決。方法為單擊: ,會彈出:
       
其中的R、G、B表示紅綠藍顏色,最後一項A代表的就是透明度,將其滑塊拖到最右,如上圖右,即設成了不透明,返回後其效果如下圖:
 
4、建立供滑動用的系列面板
再在畫布上建立一個Image父控制元件,命名為Sliderpanel,並在其下建立5個Panel,其結構與命名如下:
 
調整這5個panel,使它們向右平鋪開來,如下圖。我們這樣做的目的是想建立一個滑動效果,就像手機上的滑屏效果。
 
這5個面板預設是重疊在一起的,要像上圖那樣把它們向右平鋪開來,其位置的調整,除用滑鼠手工拖動外,其實有更精確的方法。
第1個面板MainPanel在原位,是不需調整的。
第2個面板Panel1應緊排在第1個面板的右邊,我們選中Panel1,在其Inspector中的Rect Transform中設定Left為800,Right為-800,即可將Panel1精確地調整到MainPanel的右邊第一個位置上。這裡的Left、Right的值800、-800怎樣理解?
我們以下列三個系列圖來說明這個問題:
下圖中的第1個,我們是在畫布Canvas上建立一個面板Panel,並調整它的大小,使這個Panel的Left、Top、Right、Bottom分別為200、100、220、120,從圖示就可看出它們分別表示子控制元件Panel的邊與父控制元件Canvas相對應邊之間的距離,這個距離的單位為畫素。如果畫布設定的參考解