天天看點

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

Unity 2-4 UGUI Unity5.1 UI 案例學習

任務1-1:UGUI簡介

什麼是GUI:

  遊戲的開始菜單

  RPG遊戲的菜單欄、側邊欄和功能欄(比如背包系統、任務清單等)

  設計用來控制移動的虛拟杆和攻擊按鈕

UGUI:

  Unity内置

  GUI也可以用第三方插件實作:如NGUI、DFGUI等

任務1-2:遊戲案例介紹

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

任務1-3:建立遊戲菜單

UGUI中的元件:

  UI -> Panel -- 面闆

    Button -- 按鈕

    Text -- 文本

    Image -- 圖檔

    Raw Image -- 可拖放的材質

    Slider -- 滑動器

    Scrollbar -- 滾動條

    Toggle -- 開關 (check box)

    Input Field -- 輸入框

    Canvas -- 畫布(所有的UI元件都位于Canvas下)

    Event System -- 事件系統(處理有關UI的事件)

幾乎所有的UI元件都有

  Rect Transform -- 用來控制位置和Anchor資訊

  Script腳本 -- 控制元件的功能

Button:

  Button->Text-> Text (Script) -- 可以修改文本顯示

  Image (Script) -- 修改背景圖檔

Toggle:勾選框

  Toggle->Label-> Text (Script) -- 修改文本顯示

  Toggle->Background-> Image (Script) -- 修改背景圖檔

  Toggle->Background->Checkmark-> Image (Script) -- 修改勾選的标志

Slider:滑動器

  Slider -> Value 目前滑塊位置對應的float值 [0, 1]

  Slider->Background-> Image (Script) -- 修改後置背景(滑動塊未滑動區域)

  Slider->Fill Area->Fill-> Image (Script) -- 滑動條前置背景:滑動塊已滑動區域

  Slider->Handle Slide Area->Handle (Script) -> 滑動塊背景

任務1-4:建立公告的文本清單

1. 建立Image,重命名為NoteBg,作為文本的背景

  修改Alpha值:透明度

2. 建立另一個Image,重命名為TitleBg,作為标題背景,為Note的子物體

3. 分别在NoteBg下和TitleBg下建立Text

4. 給NoteBg下的Text添加上下滾動功能

  1. 在NoteBg下建立一個Image,大小與NoteBg->Text一樣

  2. 給Image添加Scroll Rect元件

    将Text作為Image的子物體

    Content屬性:指定擁有滾動功能的控件,這裡指派Text(表示滾動的是Text)

    此時,Text就擁有了可以滾動的功能

    将水準方向的滾動取消勾選 Horizontal

  3. 此時滑動了一下,發現不行,隻是出現了Text整塊能夠被拖拽走

    而且文字沒有顯示完全 -- 将Text拉伸直到文字完全顯示出來

    此時,拖動文本就會發現有了拖動的效果

    但是,超出NoteBg多餘的文本也顯示了出來

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

  4. 通過Mask元件将多餘的文字部分隐藏

    在Image下添加Mask元件即可

  5. 若不想要Image的背景顯示(這裡是純白色)

    将Mask的Show Mask Graphic取消勾選即可

 5. 給文本右邊添加滾動條

  在Image->Scroll Rect中,有兩個Scrollbar

  在NoteBg下建立Scrollbar,修改Direction = Bottom To Top

  将該Scrollbar指派給Image->Scroll Rect-> Vertical Scrollbar

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

任務1-5:監聽按鈕的點選事件

Button的點選事件

建立GameObject GameManager,添加腳本GameManager.cs

  public void OnStartGameButton() { // 自定義函數

    SceneManager.LoadScene("02-Game");

  }

建立新場景02-Game,用于點選StartGame後載入

在StartButton下的Button元件中,點選On Click()的加号

  将GameManager指定給它,并選擇要被觸發的方法,OnStartGameButton()

在Build Settings中添加這兩個場景即可

任務1-6:建立旋轉的小球遊戲

建立Cube,将Cube放在Camera的視野中

旋轉的方法:Transform.

  Rotate(Vector3 eulerAngles, Space relativeTo=Space.Self) -- 

    圍繞x軸做eulerAngles.x的旋轉,

    圍繞y軸做eulerAngles.y的旋轉,

    圍繞z軸做eulerAngles.z的旋轉,

    Space relateiveTo表示對于什麼坐标(world/local)進行旋轉,可設為Space.World

  RotateAround(Vector3 point, Vector3 axis, float angle) -- 

    圍繞point點上的axis坐标旋轉angle度(世界坐标)

  RotateAroundLocal() -- RotateAround()的局部坐标版本

在Cube中建立腳本Cube.cs

  public float rotatingSpeed = 90; // 旋轉90度

  void Update() {

    tranform.Rotate(Vector3.up * Time.deltaTime * rotatingSpeed);

  }

任務1-7:使用Slider控制小球旋轉的速度

在Cube.cs中

  public void ChangeSpeed(float newSpeed) {

    rotatingSpeed = newSpeed;

  }

在建立的UI->Slider中,在On Value Changed(Single)

  将Cube.ChangeSpeed()指派

  表示當Slider的value改變時,會通知Cube gameObject,調用它的ChangeSpeed()方法

    而該方法的實參就是Slider中的value值

此時,當滑動Slider時,會将速度設定為0~1

設定Slider的Max Value和Min Value為0~360即可

任務2-1:案例介紹

素材為UI.unitypackage,導入

UI -> Source檔案夾下都是psd檔案(美工的ps源檔案)

UI -> effect Picture檔案夾中是psd檔案的效果圖(.jpg)

UI -> Sprite檔案夾是切好的圖

任務2-2:開始界面的背景和錨點Anchor介紹

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

建立場景01-Start

将Sprite檔案夾中的圖檔的Texture Type設定為Sprite (2D and UI)

建立UI->Image,設定Image的Source Image為StartScreen,重命名為Background

  在Rect Transform中按住Alt,點選右下方的四周的stretch,

    作用1:将Background的大小拉伸至和父類(Canvas)相同

    作用2:将Background四周的Anchor分别設定在四個頂點上 -- 螢幕縮放時等比縮放

什麼是Anchor:

  控件與錨點之間的距離是保持不變的,比如在螢幕縮放時

  如果四個錨點都在右上角,則螢幕縮放時,該控件相對于右上角的距離是不變的

可以利用Anchor錨點進行螢幕的自适應

任務2-3&2.4:按鈕

之前都是通過UI->Button的方式添加按鈕,這次用其他方法:

  UI->Image -- 按鈕的背景

  在Image中添加Button元件,在Image下添加子物體Text

這就和UI->Button方式建立的按鈕相同了

1. 添加左上方的聲音按鈕 ButtonSound

  a) UI->Image,将Source Image選擇為Button Round的Sprite 

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

    按住shift進行等比縮小

    注:按住Shift等比縮放時,以左上角為基準點;按住Shift+Alt時,以中心點為基準點

  b) UI->Image,作為a)的子物體,将Source Image選擇為ButtonRoundForeground

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

    等比放大直到填充滿Button Round

  c) UI->Image,作為a)的子物體,将Source Image選擇為Sound的Sprite 

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

    會發現圖示太窄了,選擇Set Native Size,并等比放大

  d) UI->Image,作為a)的子物體,将Source Image選擇為Leave的Sprite 

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

,并等比放大

  将a)重命名為ButtonSound,在其添加Button元件,這樣就有了點選功能

    此時點選的時候會發現點選的視覺效果是ButtonRound顔色變暗

    發現Button元件裡的Target Graphic為ButtonRound圖檔

      将其改為ButtonRoundForeground(設定點選的視覺效果)

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

2. 添加右上方郵件按鈕 ButtonMail

  将Sound替換為Mail的Sprite 

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

  将Anchor設定為右上角

3. 添加左下方的設定按鈕 ButtonSettings

  UI->Image,重命名為ButtonSettings

    背景圖檔設定為ButtonRoundBackground的Sprite 

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

    添加Button元件

  UI->Image,設定為子物體,背景圖檔設定為Settings的Sprite 

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

4. 與3相似,Settings換為Controller 

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

任務2-5:開始按鈕 & 設定開始頁面的自适應

建立Play按鈕:ButtonPlay

建立UI->Image,設定背景圖檔為Button Red B 

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

  Set Native Size

  添加Button元件

建立子物體UI->Text,居中,調整大小,顔色白色,字型選擇自定義的造字工坊悅圓

  字型放大為40,内容為PLAY

  添加陰影:在Text裡添加元件Shadow

螢幕自适應:

  ButtonSound的Anchor設定為左上角

  ButtonMail的Anchor設定為右上角

  ButtonSettings、ButtonController、ButtonPlay的Anchor設定為中心點

任務3-1:主場景 -- 頭像面闆

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

左上角:頭像

右上角:體力

左邊:設定按鈕

下方:技能狀态

建立UI->Image-> Source Image設為bg-02的Sprite

建立UI->Image,重命名為Headbar,背景設為bar 

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

  Set Native Size,等比放大,放在左上角

在Bar下建立子物體Text,用來顯示角色名字,顔色白色,字型造字工坊悅圓、大小25

相似的,建立子物體Text,用來顯示Level

點選頭像的時候,顯示人物的詳細資訊:

  添加Button元件

頭像:

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear
Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

任務3-2:體力的進度條(Slider和Filled Image)

UI->Slider 來實作體力的進度條(右上角)

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

Fill Area指的是填充部分,可以修改Fill的顔色為藍色

Handle Slide Area指的是Slider的滑輪部分的顯示,本案例中可以将其删除

自定義Slider的建立:

1. 背景

  建立UI->Image,背景圖檔設為BarBackground 

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

  體力條的背景有兩部分,一部分是棕色邊框,一部分是黑色電池部分

  複制Image,縮小,将Color修改成黑色即可

2. 綠色的填充條

  複制Image,将Color修改成綠色的填充

3. 實作Slider效果

  将最外層的Image添加Slider元件,将BarForegroundGreen指派給Slider的Fill Rect

    此時會發現,綠色的方塊大小放大了

  将BarForegroundGreen的Image Type屬性設定為Filled

    原因:可以選擇顯示該Image的某一部分

    Image Type的四種屬性:Simple/ Sliced/ Tiled/ Filled詳解見任務3-3

    将綠色部分調整大小

    Fill Method選擇Horizontal,Fill Origin選擇Left

  此時,修改Slider中的value,會發現綠色的部分會随着value的改變而填充

4. 葉子裝扮

  UI->Image

5. 左邊的體力辨別

  UI->Image, Source Image為ButtonRoundBackground2、Battle

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

6. 體力值

  UI->Text,字型、字号、顔色、對齊等

7. 此時,外觀實作了,但是,Slider是可以利用滑鼠進行大小調節的,這樣不行

  體力條是不需要與滑鼠進行互動的,隻能通過代碼來修改

  将Slider上的Interactable選項取消勾選即可

8. EnergyBar的錨點設定為右上角

體力條:

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear
Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

任務3-3:Image中的類型simple, sliced, tiled, filled

Image中Image Type的四種屬性:

  Simple/ Sliced/ Tiled/ Filled

Simple:普通模式 -- 僅僅将圖檔正常顯示出來,大小與邊框保持一緻

Sliced:切圖

  如果将某個圖檔放大,内部是填充色,而邊框會出現失真

  一般來說,放大的時候不希望邊框也放大導緻失真

  執行個體:

    選擇一個Sprite,在Inspector中打開Sprite Editor

    将綠色的小線框拖動,将圖檔分割成九個格子(4條線框)

    此時若圖檔縮放,四個角不會縮放,左右邊框隻會上下拉伸,上下邊框隻會左右拉伸

Tiled:按圖檔原來的大小進行平鋪

Filled:顯示圖檔的某一部分

  Filled Method:Radial 360°/ Radial 180°/ Radial 90°/ Horizontal/ Vertical

  Filled Origin:Top/ Bottom/ Left/ Right等等

  Clockwise: Check/ Uncheck

  執行個體:技能的冷卻效果:

    FilledMethod: Radial 360°,FilledOrigin: Top,Anti-Clockwise

任務3-4:設定和對話框按鈕

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear
Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

注:Anchor跟左邊對齊

  記得把ButtonRoundForeground設為按鈕的Target Graphic

任務3-5:技能和技能的冷卻效果

建立技能按鈕:

  UI->Image: Slot2 -- 技能背景

  UI->Image: Sword Icon

  UI->Image: 葉子 -- Leave

  UI->Text: 右上角的快捷鍵顯示

    給字型添加外邊框 -- 添加Outline元件即可

技能冷卻顯示:

  建立相同的Sword Icon的Image

    将顔色修改為黑色,将透明度修改為100

    Image Type設定為Filled

      Filled Method = Radial 360°

      Filled Origin = Top

      Anti-Clockwise

  此時,value從1-0的過程就是技能冷卻結束的過程

技能的使用:

  添加腳本SkillController.cs

  檢測按鈕的點選,并開始冷卻

public class SkillController : MonoBehaviour {

    public float cooldownTime = 2;
    private float timer = 0;
    private bool timerHasStarted = false;
    private  Image skillSwordCooldown;

    private void Start() {
        skillSwordCooldown = 
            transform.Find("Skill_Sword_Cooldown").GetComponent<Image>();
    }

    public void OnClick() {
        timerHasStarted = true;
    }

    private void Update() {
        if (timerHasStarted) {
            timer = timer += Time.deltaTime;
            skillSwordCooldown.fillAmount = 
                (cooldownTime - timer) / cooldownTime; // 冷卻所占比例
            if(timer >= cooldownTime) {
                skillSwordCooldown.fillAmount = 0;
                timer = 0;
                timerHasStarted = false;
            }
        }
    }
}          

檢測快捷鍵的點選,并開始冷卻:

  public KeyCode keycode;

  在Update()中

  if(Input.GetKeyDown(keycode) {

    timerHasStarted = true;

  }

  将keycode設定為Alpha1即可

技能:

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear
Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

任務4-1:視窗邊框

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

UI->Image: 背景為bg-01

UI->Image: 背景為window -- Image Type = Sliced -- 九宮格切圖

  邊框部分不會出現失真模糊

在Window下建立子物體UI->Image: Title

在Title下建立子物體UI->Text:白色、字型、居中、Title等

任務4-2:角色面闆的背景和關閉按鈕

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

按任務4-1建立一個視窗架構

右上角關閉按鈕:UI->Image: ButtonRound + ButtonX + Leave1

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

任務4-3:頭像

在PanelCharacter下建立線框:PenalHead,作為人物狀态的背景

  UI->Image: frame2 -- Image Type = Sliced,放在Window的左半邊

建立人物頭像背景:PenalHead的子物體PortraitBackground

  UI->Image: portrait

建立人物頭像:PortraitBackground的子物體Character

  UI->Image: character

建立等級:PortraitBackground的子物體Level

  UI->Text: 顯示角色目前等級,黑色、字型、Bold、大小、

建立顯示人物名字的葉子和下劃線:空物體PlayerName

  UI->Image: Leave2

  UI->Image: Seperator 

  UI->Text: 居中、字型、白色、大小、Bold等 

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear
Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

任務4-4:人物屬性

在PanelHead下建立人物屬性:Strength

  UI->Text: PropertyName -- 血量、白色偏暗、字型、大小

建立屬性值:為PropertyName子物體

  UI->Image: Input Background,重命名為PropertyValue

    UI->Text: 為InputBackground的子物體,字型、大小、顔色與上相同、居中等

建立屬性值加點按鈕:

  UI->Image: Button Plus,添加Button元件

建立其他兩個屬性:Dex和Focus

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear
Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

任務4-5:背包的頁籤(Toggle  -- 單選/多選按鈕)

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear
Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

Toggle: Toggle元件,其中有IsOn元件,勾選時會顯示下面指派的Graphics物體

Background: Image元件,本例中為勾選框的背景白色正方體

Checkmark: Image元件,本例中為勾選的符号

Label: Text元件

建立背景:PanelKnapsack

  UI->Image: frame-01

建立頁籤:Tab1

  UI->Image: tab-normal,添加Toggle元件

  子物體UI->Image: tab-selected

  将Tab1的Toggle元件中的Graphic設定為tab-selected

    這樣當IsOn為false的時候,tab-selected就不會顯示了

  子物體UI->Text: 裝備

建立其他兩個頁籤Tab2和Tab3

任務4-6:控制台的切換(Toggle)

Tabs的切換:

任務4-5中,使用Toggle實作了三個單選按鈕

現在,需要把他們變為多選按鈕 Toggle Group

  可以通過Toggle Group将一組Toggle進行分類

在PanelKnapsack下添加Toggle Group元件

對于Tab1、Tab2、Tab3,将它們的Group屬性設定為PanelKnapsack

預設讓Tab1處于IsOn開啟狀态,Tab2、Tab3關閉

建立Empty Object 稱為Panel1~Panel3,存儲所有Items:

切換的機理:隐藏其他兩個Panel

注意到,Toggle元件有一個On Value Changed(Boolean),可以用來監聽是否勾選

  在Tab1中的Toggle添加Panel1,并把SetActive()方法傳遞給它

并預設将Panel1和Panel2取消勾選 (手動隐藏) (否則剛開始的時候預設三個面闆都會顯示)

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

任務4-7:設計裝備、消耗品和材料面闆,以及之間的切換

通過網格 Grid Layout Group 實作背包内物品的顯示

Grid Layout Group: 對子物體進行排序

  Cell Size:每個網格的大小

    子物體的大小是不能通過子物體自己設定的,是通過Grid Layout Group控制的

1. 在Panel1下建立空物體Grid,添加Grid Layout Group元件

2. 在Grid下建立子物體

  UI->Image: Slot

  在Slot下建立子物體Item: UI->Image: inventory-04

  此時,Slot之間沒有空隙,并沒有像例圖中那樣顯示(可以直接修改Spacing的值)

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

3. 修改:在Grid下建立空物體,将Slot放入該空物體

  一個Slot對應一個空物體,Grid Layout Group控制的大小為空物體的大小

  調整各個GameObject的大小

4. 增加空的Slot,直至填滿整個Grid

  将Grid->Slot->SlotItem->Item的Image Source設為空,并将Item取消勾選

5. 在最下方顯示物品數量:

  UI->Image: Input Background,下方居中

  建立子物體UI->Text: 字型大小顔色等

  建立子物體兩邊的修飾 UI->Image: Ornament

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear
Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

任務5-1:關卡選擇界面

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

分析:

  關卡分頁顯示,分頁的實作為水準方向的滑動 -- Scroll Rect

  關卡排序顯示 -- 使用Grid Layout Group

  下方的按鈕對應各個頁面 -- Toggle Group

建立背景 UI->Image->bg-01,Anchor&Position stretch

建立Window架構: PanelSelectLevel

建立線框: UI->Image: frame1

任務5-2&5.3:不同類型的關卡按鈕&&并通過Grid Layout排序

建立單個關卡:Levelxxx

  背景 -- UI->Image: ButtonRoundBackground

  等級數 -- UI->Text: 黑色、居中、字型、大小等

  通關的星數量 -- UI->Image: StarLeft,StarCenter,StarRight

  在Levelxxx上添加Button元件

關卡類型:可制作為Prefab

  三星完成 LevelCompletedThreeStars:如上所述

  未三星完成 LevelUncompleted:

    增加UI->Image: ButtonRoundForegroundGreen, 把顔色改為黃色

    增加UI->Image: Leave,把被Foreground遮住的底部葉子還原

    将部分星星隐藏顯示

  未解鎖 LevelLocked:

    增加UI->Image: ButtonRoundForegroundGreen, 把顔色改為深色

    增加UI->Image: Lock

    增加UI->Image: Leave,把被Foreground遮住的底部葉子還原

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear
Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear
Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

通過Grid Layout進行排序:  

在PanelSelectLevel下建立32個空子物體 Level1~Level32

  将上面建立的各個關卡Levelxxx分别放入Level1~Level8

在Frame下建立一個空物體,稱為Grid,添加Grid Layout Group元件

  Start Axis = Vertical; 調整Cell Size

将Level1~Level32放入Grid

需要将Grid進行從左向右的拉伸

  是以将Grid的原點設定在左邊(此時修改Width時,大小會以左邊為基準進行縮放

  如果原點是在中間,則大小會同時往左和右縮放)

注意,此時關卡按照Grid的排序為上下排序,即為

  1 3 5 7

  2 4 6 8

  是以,需要将Text中顯示的關卡數目與Grid的排序進行錯位

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

任務5-4:關卡的滾動清單

&5-5&5.6:控制滑動清單按照頁數滑動 && 緩動效果

實作關卡的滾動效果:Scroll Rect

  詳見任務1-4

  在Frame下建立UI->Image,調整大小,就是Scroll Rect的大小(把Level1~8包含在内)

    添加Scroll Rect元件,Vertical取消勾選,将Grid指派給Content

  将Grid拖動到GridScrollPanel下作為子物體

  在GridScrollPanel中添加Mask元件,用于隐藏Grid中多餘部分的顯示

    取消勾選Show Mask Graphic,用于隐藏GridScrollPanel自身背景的顯示

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear
Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

按照頁數滑動:

現在可以進行滑動了,但是本例的滑動功能比較特别:

  滾動清單分為4頁,當滑動完成後會停留在離它最近的一頁進行顯示

在GridScrollPanel下添加腳本LevelSelectScrollRect.cs

  繼承兩個接口:using UnityEngine.EventSystems;

    IBeginDragHandle, IEndDragHandle

要想得到滑動的位置 -- 在ScrollRect裡可以得到

  private ScrollRect scrollRect = GetComponent<>...

  scrollRect.normalizedPosition;  // The scroll position as a Vector2 btw (0,0) and (1,1)     with (0,0) being the lower left corner. 

    x的值表示水準方向,y表示豎直方向;

    表示目前end drag時所在的位置(以0~1表示)

    注:滑鼠松開後的慣性移動不計入測量(以放開滑鼠那一刻的位置為準)

  此處因為隻需得到水準的滑動,使用scrollRect.horizontalNormalizedPosition即可

需要求得滑動的位置距離哪一頁比較近:

  一共有四頁,第一頁和最後一頁用0, 1表示,中間兩頁用0.333和0.666表示

public void OnEndDrag(PointerEventData eventData) {
    float posX = scrollRect.horizontalNormalizedPosition;
    // 設四個數字,若目前horizontalNormalizedPosition的值離哪個近,就翻到該頁
    // 第一頁:0;第四頁:1
    // 中間兩頁平均分,第二頁0.333,第三頁0.666
    float[] indexArray = new float[] { 0f, 0.333f, 0.666f, 1f };
    //判斷目前滑動位置離哪一頁近
    int index = 0; // 預設離第一頁近 (預設就是在第一頁)
    int targetIndex = 0;
    float offset = Mathf.Abs(posX - indexArray[index]);
    for (index = 1; index < indexArray.Length; index++) {
        // 尋找最近的一頁
        if((Mathf.Abs(posX - indexArray[index])) < offset) {
            offset = posX - indexArray[index];
            targetIndex = index;
        } 
    }
    // targetIndex就是需要定位的頁數
    scrollRect.horizontalNormalizedPosition = indexArray[targetIndex];
}      

緩動效果:

目前的效果是直接變到那一頁,沒有動畫效果,太過于生硬

scrollRect.horizontalNormalizedPosition = indexArray[targetIndex];

  -- 改進:需要使用內插補點運算的方式進行漸變

targetPosX設為全局變量

将上面直接設定Pos的代碼改為設定targetPosX:targetPosX = indexArray[targetIndex];

之後在Update()進行內插補點運算

  scrollRect.horizontalNormalizedPosition = Mathf.Lerp(

    scrollRect.horizontalNormalizedPosition, targetPosX, Time.deltaTime * speed);

此時,實作了緩動效果。

但是,會發現在Update中該內插補點運算是不停地執行的,而在滑動的過程中,scrollRect的位置是不應該被代碼所控制的:

  使用bool startAutoScroll = false; 來判斷是否需要自動緩動

  在OnEndDrag()時,将其設為true,在OnBeginDrag()時,将其設為false

  在Update()中,如果為true的時候才會運作內插補點運算和位置設定

private float targetPosX = 0; // 預設為第一頁
private bool startAutoScroll = false;
private float autoScrollSpeed = 5;

public void OnEndDrag(PointerEventData eventData) {
    // ...求得targetIndex,targetIndex就是需要定位的頁數
    // scrollRect.horizontalNormalizedPosition = indexArray[targetIndex];
    targetPosX = indexArray[targetIndex];
    startAutoScroll = true;
}

void Update() {
    if (startAutoScroll) {
        // 內插補點運算和位置設定
        if (scrollRect.horizontalNormalizedPosition.Equals(targetPosX)) {
            startAutoScroll = false;
        }
    }
}

public void OnBeginDrag(PointerEventData eventData) {
    startAutoScroll = false;
}      

任務5-7&5-8:添加單選按鈕來控制清單的滑動

添加控制清單滑動的單選按鈕:

在Frame下建立空物體SelectLevelToggles,用來存放Toggles

建立子物體UI->Image: Knob,灰色

  建立Knob的子物體,用來顯示toggle被選擇時的狀态 UI->Image: Leave

  在Knob上添加Toggle元件,将其Graphics設定為Leave

    (還記得IsOn為True時Graphics會顯示嗎)

在SelectLevelToggles中添加Toggle Group元件

  并在所有Knob上的Toggle->Group中指派SelectLevelToggles

将所有的Knob的IsOn都uncheck,完成按鈕的添加

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

通過單選按鈕來控制清單的滑動:

Toggle的事件為OnValueChanged(Boolean)

在GridScrollPanel.LevelSelectScrollRect.cs中添加四個方法分别對應四個按鍵的點選事件

public void MoveToPage1(bool isOn) {

  if (isOn) {

    startAutoScroll = true;

    targetPosX = indexArray[0];

}}

并将這四個方法分别在四個Toggle中注冊

此時,可以通過Toggle來控制頁面的滑動了

  但是,用拖拽的方式進行頁面滑動的時候,不能控制Toggle的開關,該怎麼做呢

  -- 通過代碼修改Toggle元件的IsOn屬性即可

首先,得到所有的Toggles:public Toggle[] toggles = new Toggle[4];

在上一任務中得到targetIndex之後,實作toggles[targetIndex].isOn = true; 即可

public class LevelSelectScrollRect : MonoBehaviour, 
    IBeginDragHandler, IEndDragHandler {

    // 用于修改Toogles的IsOn屬性
    public Toggle[] toggles = new Toggle[4]; 

    private ScrollRect scrollRect;
    private float targetPosX = 0; // 預設為第一頁
    private bool startAutoScroll = false;
    private float autoScrollSpeed = 5;
    private float[] indexArray;

    void Start() {
        scrollRect = GetComponent<ScrollRect>();
        indexArray = new float[] { 0f, 0.333f, 0.666f, 1f };
    }

    void Update() {
        if (startAutoScroll) {
            scrollRect.horizontalNormalizedPosition = Mathf.Lerp(
                scrollRect.horizontalNormalizedPosition, targetPosX, 
                Time.deltaTime * autoScrollSpeed);
            if (scrollRect.horizontalNormalizedPosition.Equals(targetPosX)) {
                startAutoScroll = false;
            }
        }
    }

    public void OnEndDrag(PointerEventData eventData) {
        float posX = scrollRect.horizontalNormalizedPosition;
        // 設四個數字,若目前horizontalNormalizedPosition的值離哪個近,就翻到該頁
        // 第一頁:0;第四頁:1;第二頁0.333,第三頁0.666
        int index = 0; // 預設離第一頁近 (預設就是在第一頁)
        int targetIndex = 0;
        float offset = Mathf.Abs(posX - indexArray[index]);
        for (index = 1; index < indexArray.Length; index++) {
            // 尋找最近的一頁
            if((Mathf.Abs(posX - indexArray[index])) < offset) {
                offset = posX - indexArray[index];
                targetIndex = index;
            } 
        }
        // targetIndex就是需要定位的頁數
        targetPosX = indexArray[targetIndex];
        startAutoScroll = true;
        // 通過拖拽導緻的頁面滑動,控制Toggles的IsOn屬性
        toggles[targetIndex].isOn = true;
    }

    public void OnBeginDrag(PointerEventData eventData) {
        startAutoScroll = false;
    }

    // 用于通過Toggles來控制頁面的滑動
    public void MoveToPage1(bool isOn) {
        if (isOn) {
            startAutoScroll = true;
            targetPosX = indexArray[0];
        }
    }
    public void MoveToPage2(bool isOn) {}
    public void MoveToPage3(bool isOn) {}
    public void MoveToPage4(bool isOn) {}
}
               
Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear
Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

任務6-1&6-2:任務清單 -- 背景&&任務項

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

滾動清單

建立背景 UI->Image: bg-01

建立window frame和CloseButton見任務4

在PanelQuest下建立任務對話框:Quest

  背景 UI->Image: quest-bg,Image Type = Sliced,并打開Sprite Editor切圖

    左邊任務類型 UI->Image: quest-leave

      leave的子物體: UI->Image: quest-dialog

    任務名稱 UI->Text: 字型、黑色、Bold、大小等

    右邊按鈕 UI->Image: ButtonRedA,添加Button元件

      子物體: 按鈕文字: UI->Text: Done、白色等

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear
Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

任務6-3:使用Vertical Layout和ScrollRect控制任務清單的滑動

除了Grid Layout Group外,還有Vertical Layout Group和Horizontal Layout Group

這裡因為Quests需要豎直排序,是以使用Vertical Layout Group實作

  Vertical Layout Group會将所有子物體完全填充空間

  是以和上面一樣,需要将Quest放入空物體後再作為Vertical Layout Group的子物體

在PanelQuest下建立空物體QuestListVerticalLayout

  在QuestListVerticalLayout下建立若幹空物體,作為Quest的容器

  Ctrl+D複制出(一共九個)QuestItem

  調整各個物體的大小

實作滾動效果:

建立UI->Image: 添加ScrollRect元件,調節大小

  将QuestListVerticalLayout放入ScrollRect,作為子物體

  并将ScrollRect的Content指定為QuestListVerticalLayout,取消勾選Horizontal

  在ScrollRect中添加Mask,取消勾選show mask graphics

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear
Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

任務7-1&7-2&7-3:遊戲設定界面 -- 聲音的滑動條

&& 遊戲難度按鈕

&& 音效和音樂開關

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

Volume:滑動條 (Slider)

Level:單選 (Toggle Group)

Audio/ Music:選擇框 (Toggle擴充)

老樣子,背景bg-01 +  Window Frame + ButtonClose

音量滑動條:

UI->Text: VOLUME、白色、字型等

UI->Slider:

  Background: Slider Background

  Fill Area->Fill: Slider Background,顔色黃綠色

  Handle Slide Area->Handle: Thumb

  (注:Handle Slide Area的大小和Handle的大小之間的關系要調整好)

選擇遊戲難度的單選按鈕:

UI->Text: DIFFICULTY

UI->Toggle: 

  Background: TickBackground

  Background->Checkmark: Tick

  Label: EASY

建立另外兩個按鈕MED和HARD

在Difficulty上添加Toggle Group元件,并将三個Toggle的Group設定為Difficulty

音效和音樂開關:

UI->Text: AUDIO

UI->ToggleAudio: 

  Background: SwitchBackground

  Background->Checkmark: SwitchOn,并重命名

  Label: on,黃色,在Hierarchy中放在Checkmark下(子物體)

  在Checkmark旁邊添加一個兄弟UI->Image: SwitchOff,位置在右邊

  同樣,在SwitchOff下建立一個 UI->Text: off,紅色,位置在左邊

在ToggleAudio中添加ToggleAudioController.cs腳本,用于自定義控制Toggle

首先需要取得SwitchOn和SwitchOff兩個gameObject

  public GameObject switchOn; 

  public GameObject switchOff;

監聽Toggle的按下:

  public void OnSwitchPressed(bool isOn) {

    switchOn.SetActive(isOn);

    switchOff.SetActive(!isOn);

  }

此時就能進行開關的切換了

但是還需要設定剛開始的初始化狀态

  private Toggle toggle = GetComponent<Toggle>();

  在Start()中手動調用OnSwitchPressed(toggle.isOn); 即可

相同的MUSIC按鈕,複制即可

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear
Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear
Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear
Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

任務8-1:遊戲登入界面 -- 登入面闆、輸入框

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

下方兩個按鈕;中間兩個輸入框,一個單選按鈕

老樣子:bg-01 + Window Frame + ButtonClose

建立線框:UI->Image: frame2,調整大小

建立輸入框Username:

  UI->Text: Name,字型大小,向右對齊等

    UI->Input Field -- InputField元件用來控制輸入,它的屬性:

        Image: 輸入框背景

        Placeholder: 預設顯示值

        Text Component: 輸入時會将輸入值顯示在該元件指向的Text物體中

      子物體 Placeholder: Text元件 -- (當有輸入時,該物體的Text會自動被禁用)

      子物體 Text -- 用來存放InputField中輸入的内容

同樣方法建立輸入框Password:

  但是密碼是不能顯示明文的

  在InputField元件中有一個ContentType屬性,ContentType = Password即可

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear
Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

建立Remember Me單選框:

  UI->Toggle: 

    Background: TickBackground

    Background->Checkmark: Tick

    Label: Remember Me?

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear
Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

建立下方兩個按鈕:

  登入按鈕:

    UI->Image: ButtonRoundBackground,添加Button元件

      UI->Image: Ok

  控制按鈕:

    UI->Image: ButtonRoundBackground,添加Button元件

      UI->Image: ButtonRoundForeground(并設為Button的Graphics)

      UI->Image: Leave

      UI->Image: Controller

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear
Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear

任務8-2:結束語

掰掰

Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習 - FudgeBear