unity實(shí)現(xiàn)翻頁(yè)按鈕功能
本文實(shí)例為大家分享了unity實(shí)現(xiàn)翻頁(yè)按鈕功能的具體代碼,供大家參考,具體內(nèi)容如下
效果圖:
UI子父級(jí)關(guān)系:
代碼中也都有加入注釋,有不懂可私信我。腳本中用到了對(duì)象池,我沒(méi)有上傳,可根據(jù)自己需求做相應(yīng)變動(dòng)。
腳本:PageBtnPanelC
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; /// <summary> /// 分頁(yè)按鈕面板控制器 /// </summary> public class PageBtnPanelC : MonoBehaviour { private HorizontalLayoutGroup self_HLG; /// <summary> /// 上一頁(yè)按鈕 /// </summary> private Button lastPageBtn; /// <summary> /// 下一頁(yè)按鈕 /// </summary> private Button nextPageBtn; /// <summary> /// 頁(yè)數(shù)的父物體 /// </summary> private RectTransform pageBtnParent; private HorizontalLayoutGroup pageBtnParent_HLG; /// <summary> /// 上一頁(yè)按鈕點(diǎn)擊事件 /// </summary> private UnityAction<int> lastPageBtnEvent; /// <summary> /// 下一頁(yè)按鈕點(diǎn)擊事件 /// </summary> private UnityAction<int> nextPageBtnEvent; /// <summary> /// 當(dāng)前顯示頁(yè)面的下標(biāo) /// </summary> private int _currentShowPageIndex = 1; public int CurrentShowPageIndex { get { return _currentShowPageIndex; } set { _currentShowPageIndex = value; } } /// <summary> /// 總的頁(yè)面數(shù) /// </summary> private int totalPageNumber = 0; /// <summary> /// 顯示按鈕的個(gè)數(shù) 奇數(shù)個(gè) /// </summary> [Header("必須是奇數(shù)個(gè),且小于總頁(yè)數(shù)")] private int _showBtnCount = 5; public int ShowBtnCount { get { if (_showBtnCount > totalPageNumber) { _showBtnCount = totalPageNumber; } return _showBtnCount; } set { if (value % 2 == 0) { _showBtnCount = value - 1; } else { _showBtnCount = value; } } } /// <summary> /// 頁(yè)數(shù)按鈕 預(yù)設(shè)體 /// </summary> public GameObject btnPrefabs; /// <summary> /// 頁(yè)數(shù)按鈕 存放list /// </summary> public List<PageBtnC> pbcList; private void Start() { Init(); Set(14, 9, (index1) => { Debug.Log("當(dāng)前顯示第:" + CurrentShowPageIndex + "頁(yè)"); }, (index2) => { Debug.Log("當(dāng)前顯示第:" + CurrentShowPageIndex + "頁(yè)"); }, (_pageIndex, _pbc) => { Debug.Log("當(dāng)前顯示第:" + CurrentShowPageIndex + "頁(yè)"); }); } /// <summary> /// 改變顯示的狀態(tài) /// </summary> void ChangeShowState() { int _showBtnCount = ShowBtnCount; /* 判斷是否在可更新范圍內(nèi),如果在更新范圍內(nèi),則將CurrentShowPageIndex設(shè)置為中心位置的按鈕 eg:假設(shè)總共有10頁(yè)(totalPageNumber = 10),顯示按鈕的個(gè)數(shù)為7(ShowBtnCount = 7) 則應(yīng)該在 (ShowBtnCount / 2 + 1) = 4 到 totalPageNumber - ShowBtnCount / 2 = 7 之間設(shè)置 如果CurrentShowPageIndex = 5或6 則應(yīng)該這樣顯示 1.. 3 4 5 6 7 ..10 如果不在更新范圍內(nèi), 如果CurrentShowPageIndex = 1或2或3或4 則應(yīng)該這樣顯示: 1 2 3 4 5 6 ..10 如果如果CurrentShowPageIndex = 7或8或9或10 則應(yīng)該這樣顯示 1.. 5 6 7 8 9 10 */ if (CurrentShowPageIndex >= (ShowBtnCount / 2 + 1) && CurrentShowPageIndex <= (totalPageNumber - ShowBtnCount / 2)) { int _showBtnCount2 = _showBtnCount - 2; _showBtnCount2 /= 2; //判斷起始下標(biāo) int startIndex = CurrentShowPageIndex - _showBtnCount2; int endIndex = CurrentShowPageIndex + _showBtnCount2; //防止超出 if (startIndex <= 1) { startIndex = 2; } //防止超出 if (endIndex >= totalPageNumber) { endIndex = totalPageNumber - 1; } //計(jì)算中心位置按鈕的下標(biāo) 因?yàn)閟howBtnCount不定 int centerIndex = ShowBtnCount / 2; pbcList[centerIndex].Set(CurrentShowPageIndex); //循環(huán)設(shè)置前面一部分按鈕信息 for (int i = 1; i < centerIndex; i++) { pbcList[i].Set(startIndex++); } //循環(huán)設(shè)置后面一部分按鈕信息 for (int i = centerIndex + 1; i < ShowBtnCount - 1; i++) { startIndex++; pbcList[i].Set(startIndex); } } else { //如果點(diǎn)擊的是小于等于4的按鈕下標(biāo) if (CurrentShowPageIndex < (ShowBtnCount / 2 + 1)) { for (int i = 0; i < ShowBtnCount - 1; i++) { pbcList[i].Set(i+1); } }//如果點(diǎn)擊的事大于等于7的按鈕下標(biāo) else if (CurrentShowPageIndex > (totalPageNumber - ShowBtnCount / 2)) { int startNumber = totalPageNumber - ShowBtnCount + 2; for (int i = 1; i < ShowBtnCount; i++) { pbcList[i].Set(startNumber++); } } } /* 判斷總顯示頁(yè)數(shù)是否大于顯示頁(yè)數(shù) 以防止出現(xiàn)這種效果: 例如:totalPageNumber = 7,ShowBtnCount =7 防止出現(xiàn)的效果:1 2 3 4 5 6 ..7 和 1.. 2 3 4 5 6 7 應(yīng)該出現(xiàn)的效果:1 2 3 4 5 6 7 */ if (totalPageNumber > ShowBtnCount){ _showBtnCount -= 2; _showBtnCount /= 2; if (CurrentShowPageIndex - _showBtnCount - 1 > 1) { pbcList[0].Set(1, "1.."); } else { pbcList[0].Set(1); } if (CurrentShowPageIndex + _showBtnCount + 1 < totalPageNumber) { pbcList[ShowBtnCount - 1].Set(totalPageNumber, ".." + totalPageNumber); } else { pbcList[ShowBtnCount - 1].Set(totalPageNumber); } } } private bool isInit = false; public void Init() { if (isInit) return; isInit = true; pbcList = new List<PageBtnC>(); self_HLG = transform.GetComponent<HorizontalLayoutGroup>(); pageBtnParent = transform.Find("PageIndexParent") as RectTransform; pageBtnParent_HLG = pageBtnParent.GetComponent<HorizontalLayoutGroup>(); lastPageBtn = transform.Find("LastPageBtn").GetComponent<Button>(); lastPageBtn.onClick.AddListener(()=> { if (totalPageNumber <= 0) return; if (CurrentShowPageIndex > 1) { CurrentShowPageIndex--; } ResetPageBtnState(); ChangeShowState(); PageBtnC pbc = GetPBCFromIndex(CurrentShowPageIndex); if (pbc != null) { pbc.SetHighlightColor(); } if (lastPageBtnEvent != null) { lastPageBtnEvent(CurrentShowPageIndex); } }); nextPageBtn = transform.Find("NextPageBtn").GetComponent<Button>(); nextPageBtn.onClick.AddListener(()=> { if (totalPageNumber <= 0) return; if (CurrentShowPageIndex < totalPageNumber) { CurrentShowPageIndex++; } ResetPageBtnState(); ChangeShowState(); PageBtnC pbc = GetPBCFromIndex(CurrentShowPageIndex); if (pbc != null) { pbc.SetHighlightColor(); } if (nextPageBtnEvent != null) { nextPageBtnEvent(CurrentShowPageIndex); } }); } /// <summary> /// 設(shè)置信息 /// </summary> /// <param name="totalPageNumber">總頁(yè)數(shù)</param> /// <param name="showBtnCount">顯示多少個(gè)按鈕,填奇數(shù),如果填偶數(shù),則會(huì)強(qiáng)制減1,如:填6,則實(shí)際為5</param> /// <param name="lastBtnEvent">上一頁(yè)按鈕事件</param> /// <param name="nextBtnEvent">下一頁(yè)按鈕事件</param> /// <param name="pageBtnClickEvent">單獨(dú)點(diǎn)擊頁(yè)面按鈕事件</param> public void Set(int totalPageNumber,int showBtnCount,UnityAction<int> lastBtnEvent,UnityAction<int> nextBtnEvent,UnityAction<int,PageBtnC> pageBtnClickEvent) { if (totalPageNumber <= 0) { this.totalPageNumber = 1; } else { this.totalPageNumber = totalPageNumber; } this.ShowBtnCount = showBtnCount; this.lastPageBtnEvent = lastBtnEvent; this.nextPageBtnEvent = nextBtnEvent; CurrentShowPageIndex = 1; pbcList.Clear(); for (int i = 1; i <= ShowBtnCount; i++) { int index = i; PageBtnC pbc = PoolManager.Instance.Spawn(btnPrefabs, pageBtnParent).GetComponent<PageBtnC>(); if (pbc) { pbc.Set(index,null, (pageIndex,pbc111) => { CurrentShowPageIndex = pageIndex; ResetPageBtnState(); ChangeShowState(); PageBtnC pbc1 = GetPBCFromIndex(CurrentShowPageIndex); if (pbc1 != null) { pbc1.SetHighlightColor(); } if (pageBtnClickEvent != null) { pageBtnClickEvent(pageIndex, pbc111); } }); } pbcList.Add(pbc); } pbcList[0].SetHighlightColor(); ChangeShowState(); Util.SetWidth_ChildWidthSame(pageBtnParent_HLG, pageBtnParent); Util.SetWidth_ChildWidthNotSame(self_HLG, transform as RectTransform); } /// <summary> /// 重置所有按鈕的狀態(tài) /// </summary> void ResetPageBtnState() { for (int i = 0; i < pbcList.Count; i++) { pbcList[i].SetNormalColor(); } } /// <summary> /// 回收所有頁(yè)碼 /// </summary> public void Unspawn() { for (int i = pageBtnParent.childCount - 1; i >= 0; i--) { PoolManager.Instance.UnSpawn(pageBtnParent.GetChild(i).gameObject); } } public void Clear() { lastPageBtnEvent = null; nextPageBtnEvent = null; } /// <summary> /// 根據(jù)index得到pagebtnc物體 /// </summary> /// <param name="index"></param> /// <returns></returns> PageBtnC GetPBCFromIndex(int index) { for (int i = 0; i < pbcList.Count; i++) { if (pbcList[i].CurrentPageIndex.Equals(index)) { return pbcList[i]; } } return null; } } public class Util { /// <summary> /// 設(shè)置物體寬度 子物體寬度相同 /// </summary> /// <param name="parentHLG"></param> /// <param name="parent"></param> /// <param name="callback"></param> public static void SetWidth_ChildWidthSame(HorizontalLayoutGroup parentHLG, RectTransform parent, UnityAction<float> endCallBack = null) { float width = 0; float leftPadding = parentHLG.padding.left; float spacing = parentHLG.spacing; int childCount = parent.childCount; if (childCount > 0) { RectTransform singleChildRT = parent.GetChild(0) as RectTransform; width = childCount * singleChildRT.rect.width + (childCount - 1) * spacing + leftPadding; } parent.sizeDelta = new Vector2(width, parent.sizeDelta.y); if (endCallBack != null) { endCallBack(width); } } /// <summary> /// 設(shè)置物體寬度 子物體寬度不同 /// </summary> /// <param name="parentHLG"></param> /// <param name="parent"></param> /// <param name="callback"></param> public static void SetWidth_ChildWidthNotSame(HorizontalLayoutGroup parentHLG, RectTransform parent, UnityAction<float> endCallBack = null) { float width = 0; RectOffset Padding = parentHLG.padding; float spacing = parentHLG.spacing; int childCount = parent.childCount; if (childCount > 0) { for (int i = 0; i < childCount; i++) { RectTransform childRT = parent.GetChild(i) as RectTransform; width += childRT.rect.width; } width += (childCount - 1) * spacing + Padding.left + Padding.right; } parent.sizeDelta = new Vector2(width, parent.sizeDelta.y); if (endCallBack != null) { endCallBack(width); } } }
腳本:PageBtnC
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; /// <summary> /// 頁(yè)碼按鈕控制器 /// </summary> public class PageBtnC : MonoBehaviour,IPool { /// <summary> /// 自己顯示的頁(yè)碼 /// </summary> private int currentPageIndex = 0; public int CurrentPageIndex { get { return currentPageIndex; } } private Button SelfBtn; private Image img; private Text selfText; /// <summary> /// 按鈕事件 /// </summary> public UnityAction<int,PageBtnC> btnClickEvent; /// <summary> /// 按鈕正常和高亮顏色 /// </summary> public Color normalColor; public Color highlightColor; /// <summary> /// 文本正常和高亮顏色 /// </summary> public Color normalTextColor; public Color highlightTextColor; private bool isInit = false; void Init() { if (isInit) return; isInit = true; img = transform.GetComponent<Image>(); selfText = transform.Find("Text").GetComponent<Text>(); SelfBtn = transform.GetComponent<Button>(); SelfBtn.onClick.AddListener(()=> { if (btnClickEvent != null) { btnClickEvent(currentPageIndex,this); } }); } /// <summary> /// 設(shè)置正常顏色 /// </summary> public void SetNormalColor() { img.color = normalColor; selfText.color = normalTextColor; } /// <summary> /// 設(shè)置高亮顏色 /// </summary> public void SetHighlightColor() { img.color = highlightColor; selfText.color = highlightTextColor; } /// <summary> /// 設(shè)置事件 文本內(nèi)容等 /// </summary> /// <param name="currentPageIndex"></param> /// <param name="selfTextStr"></param> /// <param name="btnClickEvent"></param> public void Set(int currentPageIndex,string selfTextStr = null,UnityAction<int,PageBtnC> btnClickEvent = null) { this.currentPageIndex = currentPageIndex; if (btnClickEvent != null) { this.btnClickEvent = btnClickEvent; } if (string.IsNullOrEmpty(selfTextStr)) { selfText.text = currentPageIndex.ToString(); } else { selfText.text = selfTextStr; } } #region 對(duì)象池接口方法 public int GetMaxCount() { return 10; } public string SingletonName() { return this.GetType().Name; } public void Spawn() { Init(); } public void UnSpawn() { SetNormalColor(); } #endregion }
github地址
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
詳解c# 強(qiáng)制轉(zhuǎn)換和類型轉(zhuǎn)換
這篇文章主要介紹了c# 強(qiáng)制轉(zhuǎn)換和類型轉(zhuǎn)換的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)c#,感興趣的朋友可以了解下2020-10-10C#實(shí)現(xiàn)順序隊(duì)列和鏈隊(duì)列的代碼實(shí)例
今天小編就為大家分享一篇關(guān)于C#實(shí)現(xiàn)順序隊(duì)列和鏈隊(duì)列的代碼實(shí)例,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-10-10C#環(huán)形隊(duì)列的實(shí)現(xiàn)方法詳解
這篇文章先是簡(jiǎn)單的給大家介紹了什么是環(huán)形隊(duì)列和環(huán)形隊(duì)列的優(yōu)點(diǎn),然后通過(guò)實(shí)例代碼給大家介紹C#如何實(shí)現(xiàn)環(huán)形隊(duì)列,有需要的朋友們可以參考借鑒,下面來(lái)一起看看吧。2016-09-09C# WinForm制作登錄界面的實(shí)現(xiàn)步驟
本文主要介紹了C# WinForm制作登錄界面的實(shí)現(xiàn)步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05使用Linq注意事項(xiàng)避免報(bào)錯(cuò)的方法
這篇文章主要介紹了使用Linq注意事項(xiàng)避免報(bào)錯(cuò)的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01