Unity-UGUI製作PageView
【初話】
我的天啊,超級久沒有po新文章了,開局就請讓我先來個土下座Orz,然後我會跪著寫完這篇文以示我的誠意(誤)!但我想應該沒有人對我的下跪有興趣,所以我還是趕緊進入正題吧!
這次在與夥伴製作角色選單時,需要讓使用者可以左右滑動去選擇角色,通常說到這裡十個開發者有十一個會選擇使用ScrollView,但其實我們更需要的是類似PageView的功能。PageView的概念基本上就是你希望使用者滑動完成放開手指後會自動鎖定在某一頁或是某一個物件,並將其顯示在對你來說最理想的位置。
以往使用NGUI時,它就有提供PageView這樣的功能,不過這次我使用的是UGUI,UGUI僅僅提供ScrollView,故這次我要來分享我如何在UGUI上頭實作出PageView的功能,相當簡單,希望可以幫上大家!Let’s GO!
【第一話】Hierarchy的前置作業
我們先來看看PageView於Hierarchy的結構,這部份搭配著圖看比較好理解,由上往下的四個部份來組成:
1. Page View: 控制整個選單的觸碰區域、滑動方式、效果、慣性等等。B圖中的灰色區域便是觸碰區域,玩家在這個區域才能夠有效滑動選單。
2. ViewPort: 處理可視區域。B圖中的粉色區域便是可視區域,總是會有一個物件被置於這個區域的中間。
3. Content: 負責排序底下的所有物件。
4. Items: 內容物,可動態生成及擴充。
Page View
PageView元件做為本篇的主角,大家看到他的相關屬性應該會有點眼熟,沒錯!它是繼承於UGUI的ScrollRect衍伸出來的,這部份稍後讓我另開一話來說明,還請各位先繼續看下去。
由於PageView的特色是在玩家停止滑動時應該自動將某個物件置中於可視區域,故我們應該將慣性(Inertia)關起來,由我們自己來處理相關的滑動。
ViewPort
- 設定長寬(Width and Height),即為此PageView的可視區域。
- Mask元件,遮檔可視區域外的物件。
Content
擁有GridLayoutGroup和ContentSizeFitter兩個元件。
1. GridLayoutGroup: 可以設定底下所有子物件的排列方式,本篇範例的設定為水平向的排列。
2. ContentSizeFitter: 在底下的物件數量變更時,會自動去調整Content的長度或寬度,這也間接影響了玩家可以滑動的範圍。
【第二話】站在ScrollRect的肩膀上
前面提到PageView是繼承於UGUI的ScrollRect元件,然後再覆寫滑動處理的相關函式來完成。ScrollRect的相關說明很容易在Google上找到,除此之外也還有不少優化的文章,就請大家自行去尋找囉!畢竟搜尋網路資源是我們這個世代的本事嘛哈哈哈哈!所以本篇就只會著重在PageView的程式碼實現。
23~26: 覆寫OnBeginDrag函式,此函式會在玩家開始滑動時觸發一次。
28~40: 覆寫OnDrag函式,此函式會在玩家滑動時不斷觸發。因此,在此函式內我們會一直計算落在可視區域內的物件index,存到CurrentObjIndex供外部取得,且在物件變更時呼叫一次變更事件。
42~51: 覆寫OnEndDrag函式,此函式會在玩家結束滑動時觸發一次。在這裡我們要利用Content當前的X座標以及當前可視區域物件的index,算出Content最終的X座標。以本篇範例的物件寬度為150,Content的起始位置為-75,可得如下的規則:
物件index為0,Content最終X座標為-75;
物件index為1,Content最終X座標為-225;
物件index為2,Content最終X座標為-375;
物件index為3,Content最終X座標為-525;
....
56~70: 計算處於可視區域的物件index。利用簡單的除法來算出目前在可視區域的物件是哪個index。以本篇範例的物件寬度為150,Content的起始位置為-75,可得如下的規則:
Content X座標為大於-150,物件index為0;
Content X座標為-150~-299之間,物件index為1;
Content X座標為-300~-449之間,物件index為2;
Content X座標為-450~-600之間,物件index為3;
....
走到這邊,我們已經可以獲得以下的結果。當你結束滑動後,PageView會自動幫你將可視區域當前的物件移到正中間(其實就是與可視區域交疊最多的物件會雀屏中選)。
【第三話】UX優化
我們在第二話所完成的成果,其實已經有了PageView的中心思想,但其實還差一步,也就是放開滑動時物件是瞬間跑到它該去的位置上,這其實是個相當突兀的體驗。試想想我們在看書的時候要從這一頁進到下一頁,勢必會有個翻頁的動態過程,這樣才是個合理的翻頁體驗,因此我們需要幫它加上動態效果。
你當然可以在Update函式裡去做出滑動的效果,但在下使用了DoTween套件以便於實現,於是原先的程式碼會產生這樣的變動,大家可以第二話的程式碼為基礎去修改。
加入動態效果後我們可以很明顯的看到使用者體驗變好了,如下:
【最終話】
自從離開公司後才開始使用UGUI,感覺自己對他還很陌生,希望我的設計師夥伴可以設計更多樣的使用流程XD,相信UGUI會陪伴我面對他的挑戰的哈哈!
喔對了,其實在製作滑動選單(排行榜、聊天清單、交易紀錄等等)的很多時候,物件數量都會非常非常的多,幾百幾千筆的那種多,若是你一口氣將這些幾百幾千的東西生成到Unity的場景上那將會是非常卡頓的事情,所以在業界通常會使用一種叫動態位移的技法,通過這種技法就可以用10個物件(不一定是10個,越少越好)來顯示幾百幾千的資料,是相當節省效能的一個作法,網路上也蠻多相關的討論哦!