Unity 2-4 UGUI Unity5.1 UI 案例學習
任務1-1:UGUI簡介
什麼是GUI:
遊戲的開始菜單
RPG遊戲的菜單欄、側邊欄和功能欄(比如背包系統、任務清單等)
設計用來控制移動的虛拟杆和攻擊按鈕
UGUI:
Unity内置
GUI也可以用第三方插件實作:如NGUI、DFGUI等
任務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) -> 滑動塊背景
任務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多餘的文本也顯示了出來
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為ButtonRoundBackground2、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元件
對于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取消勾選 (手動隐藏) (否則剛開始的時候預設三個面闆都會顯示)
任務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:結束語
掰掰