Siki_Unity_2-4_UGUI_Unity5.1 UI 案例學習

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

任務1-1:UGUI簡介

什麼是GUI:
  遊戲的開始菜單
  RPG遊戲的菜單欄、側邊欄和功能欄(好比揹包系統、任務列表等)
  設計用來控制移動的虛擬杆和攻擊按鈕框架

UGUI:
  Unity內置
  GUI也能夠用第三方插件實現:如NGUI、DFGUI等ide

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

任務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) -> 滑動塊背景ui

任務1-4:建立公告的文本列表

1. 建立Image,重命名爲NoteBg,做爲文本的背景
  修改Alpha值:透明度spa

2. 建立另外一個Image,重命名爲TitleBg,做爲標題背景,爲Note的子物體.net

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多餘的文本也顯示了出來

  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

任務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介紹

建立場景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 
    按住shift進行等比縮小
    注:按住Shift等比縮放時,以左上角爲基準點;按住Shift+Alt時,以中心點爲基準點

  b) UI->Image,做爲a)的子物體,將Source Image選擇爲ButtonRoundForeground
    等比放大直到填充滿Button Round
  c) UI->Image,做爲a)的子物體,將Source Image選擇爲Sound的Sprite 
    會發現圖標太窄了,選擇Set Native Size,並等比放大
  d) UI->Image,做爲a)的子物體,將Source Image選擇爲Leave的Sprite ,並等比放大

  將a)重命名爲ButtonSound,在其添加Button組件,這樣就有了點擊功能
    此時點擊的時候會發現點擊的視覺效果是ButtonRound顏色變暗
    發現Button組件裏的Target Graphic爲ButtonRound圖片
      將其改成ButtonRoundForeground(設置點擊的視覺效果)

2. 添加右上方郵件按鈕 ButtonMail
  將Sound替換爲Mail的Sprite 
  將Anchor設置爲右上角

3. 添加左下方的設置按鈕 ButtonSettings
  UI->Image,重命名爲ButtonSettings
    背景圖片設置爲ButtonRoundBackground的Sprite 
    添加Button組件
  UI->Image,設置爲子物體,背景圖片設置爲Settings的Sprite 

4. 與3類似,Settings換爲Controller 

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

建立Play按鈕:ButtonPlay

建立UI->Image,設置背景圖片爲Button Red B 
  Set Native Size
  添加Button組件
建立子物體UI->Text,居中,調整大小,顏色白色,字體選擇自定義的造字工坊悅圓
  字體放大爲40,內容爲PLAY
  添加陰影:在Text裏添加組件Shadow

屏幕自適應:
  ButtonSound的Anchor設置爲左上角
  ButtonMail的Anchor設置爲右上角
  ButtonSettings、ButtonController、ButtonPlay的Anchor設置爲中心點

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

左上角:頭像
右上角:體力
左邊:設置按鈕
下方:技能狀態

新建UI->Image-> Source Image設爲bg-02的Sprite
新建UI->Image,重命名爲Headbar,背景設爲bar 
  Set Native Size,等比放大,放在左上角

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

點擊頭像的時候,顯示人物的詳細信息:
  添加Button組件

頭像: 

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

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

Fill Area指的是填充部分,能夠修改Fill的顏色爲藍色
Handle Slide Area指的是Slider的滑輪部分的顯示,本案例中能夠將其刪除

自定義Slider的建立:

1. 背景
  建立UI->Image,背景圖片設爲BarBackground 
  體力條的背景有兩部分,一部分是棕色邊框,一部分是黑色電池部分
  複製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爲ButtonRoundBackground二、Battle

6. 體力值
  UI->Text,字體、字號、顏色、對齊等

7. 此時,外觀實現了,可是,Slider是能夠利用鼠標進行大小調節的,這樣不行
  體力條是不須要與鼠標進行交互的,只能經過代碼來修改
  將Slider上的Interactable選項取消勾選便可

8. EnergyBar的錨點設置爲右上角

體力條: 

任務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:設置和對話框按鈕

 

注: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便可

技能: 

任務4-1:窗口邊框

UI->Image: 背景爲bg-01

UI->Image: 背景爲window -- Image Type = Sliced -- 九宮格切圖
  邊框部分不會出現失真模糊

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

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

按任務4-1建立一個窗口框架

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

任務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等 

 

任務4-4:人物屬性

在PanelHead下建立人物屬性:Strength
  UI->Text: PropertyName -- 血量、白色偏暗、字體、大小

建立屬性值:爲PropertyName子物體
  UI->Image: Input Background,重命名爲PropertyValue
    UI->Text: 爲InputBackground的子物體,字體、大小、顏色與上相同、居中等

建立屬性值加點按鈕:
  UI->Image: Button Plus,添加Button組件

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

任務4-5:揹包的選項卡(Toggle  -- 單選/多選按鈕)

 

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組件
對於Tab一、Tab二、Tab3,將它們的Group屬性設置爲PanelKnapsack

默認讓Tab1處於IsOn開啓狀態,Tab二、Tab3關閉

建立Empty Object 稱爲Panel1~Panel3,存儲全部Items:

切換的機理:隱藏其餘兩個Panel

注意到,Toggle組件有一個On Value Changed(Boolean),能夠用來監聽是否勾選
  在Tab1中的Toggle添加Panel1,並把SetActive()方法傳遞給它

並默認將Panel1和Panel2取消勾選 (手動隱藏) (不然剛開始的時候默認三個面板都會顯示)

 

任務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的值)

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

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

分析:
  關卡分頁顯示,分頁的實現爲水平方向的滑動 -- 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遮住的底部葉子還原

經過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的排序進行錯位

任務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自身背景的顯示

按照頁數滑動:

如今能夠進行滑動了,可是本例的滑動功能比較特別:
  滾動列表分爲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,完成按鈕的添加

經過單選按鈕來控制列表的滑動:

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) {} }  

任務6-1&6-2:任務列表 -- 背景&&任務項

滾動列表

建立背景 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、白色等

 

任務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

任務7-1&7-2&7-3:遊戲設置界面 -- 聲音的滑動條
&& 遊戲難度按鈕
&& 音效和音樂開關

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按鈕,複製便可

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

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

老樣子: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便可

建立Remember Me單選框:
  UI->Toggle: 
    Background: TickBackground
    Background->Checkmark: Tick
    Label: Remember Me?

建立下方兩個按鈕:
  登陸按鈕:
    UI->Image: ButtonRoundBackground,添加Button組件
      UI->Image: Ok
  控制按鈕:
    UI->Image: ButtonRoundBackground,添加Button組件
      UI->Image: ButtonRoundForeground(並設爲Button的Graphics)
      UI->Image: Leave
      UI->Image: Controller

任務8-2:結束語

掰掰

相關文章
相關標籤/搜索