unity 制作翻页按钮功能

效果图:

UI子父级关系:

代码中也都有加入注释,有不懂可私信我。脚本中用到了对象池,我没有上传,可根据自己需求做相应变动。

脚本:PageBtnPanelC

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
/// <summary>
/// 分页按钮面板控制器
/// </summary>
public class PageBtnPanelC : MonoBehaviour {
    private HorizontalLayoutGroup self_HLG;
    /// <summary>
    /// 上一页按钮
    /// </summary>
    private Button lastPageBtn;
    /// <summary>
    /// 下一页按钮
    /// </summary>
    private Button nextPageBtn;
    /// <summary>
    /// 页数的父物体
    /// </summary>
    private RectTransform pageBtnParent;
    private HorizontalLayoutGroup pageBtnParent_HLG;
    /// <summary>
    /// 上一页按钮点击事件
    /// </summary>
    private UnityAction<int> lastPageBtnEvent;
    /// <summary>
    /// 下一页按钮点击事件
    /// </summary>
    private UnityAction<int> nextPageBtnEvent;
    /// <summary>
    /// 当前显示页面的下标
    /// </summary>
    private int _currentShowPageIndex = 1;
    public int CurrentShowPageIndex {
        get {
            return _currentShowPageIndex;
        }
        set {
            _currentShowPageIndex = value;
        }
    }
    /// <summary>
    /// 总的页面数
    /// </summary>
    private int totalPageNumber = 0;
    /// <summary>
    /// 显示按钮的个数  奇数个
    /// </summary>
    [Header("必须是奇数个,且小于总页数")]
    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>
    /// 页数按钮  预设体
    /// </summary>
    public GameObject btnPrefabs;
    /// <summary>
    /// 页数按钮 存放list
    /// </summary>
    public List<PageBtnC> pbcList;

    private void Start()
    {
        Init();
        Set(14, 9, (index1) =>
        {
            Debug.Log("当前显示第:" + CurrentShowPageIndex + "页");
        }, (index2) =>
        {
            Debug.Log("当前显示第:" + CurrentShowPageIndex + "页");
        }, (_pageIndex, _pbc) =>
        {
            Debug.Log("当前显示第:" + CurrentShowPageIndex + "页");
        });
    }
    /// <summary>
    /// 改变显示的状态
    /// </summary>
    void ChangeShowState() {
        int _showBtnCount = ShowBtnCount;
        /*
         判断是否在可更新范围内,如果在更新范围内,则将CurrentShowPageIndex设置为中心位置的按钮
         eg:假设总共有10页(totalPageNumber = 10),显示按钮的个数为7(ShowBtnCount = 7)
            则应该在  (ShowBtnCount / 2 + 1) = 4  到    totalPageNumber - ShowBtnCount / 2 = 7 之间设置

            如果CurrentShowPageIndex = 5或6
            则应该这样显示     1..  3  4  5  6  7  ..10

            如果不在更新范围内,
            如果CurrentShowPageIndex = 1或2或3或4     则应该这样显示:  1  2  3  4  5  6  ..10
            如果如果CurrentShowPageIndex = 7或8或9或10   则应该这样显示   1..  5  6  7  8  9  10
         */
        if (CurrentShowPageIndex >= (ShowBtnCount / 2 + 1) && CurrentShowPageIndex <= (totalPageNumber - ShowBtnCount / 2))
        {
            int _showBtnCount2 = _showBtnCount - 2;
            _showBtnCount2 /= 2;

            //判断起始下标
            int startIndex = CurrentShowPageIndex - _showBtnCount2;
            int endIndex = CurrentShowPageIndex + _showBtnCount2;

            //防止超出
            if (startIndex <= 1)
            {
                startIndex = 2;
            }
            //防止超出
            if (endIndex >= totalPageNumber)
            {
                endIndex = totalPageNumber - 1;
            }

            //计算中心位置按钮的下标   因为showBtnCount不定
            int centerIndex = ShowBtnCount / 2;

            pbcList[centerIndex].Set(CurrentShowPageIndex);

            //循环设置前面一部分按钮信息
            for (int i = 1; i < centerIndex; i++)
            {
                pbcList[i].Set(startIndex++);
            }

            //循环设置后面一部分按钮信息
            for (int i = centerIndex + 1; i < ShowBtnCount - 1; i++)
            {
                startIndex++;
                pbcList[i].Set(startIndex);
            }
        }
        else {
            //如果点击的是小于等于4的按钮下标
            if (CurrentShowPageIndex < (ShowBtnCount / 2 + 1))
            {
                for (int i = 0; i < ShowBtnCount - 1; i++) {
                    pbcList[i].Set(i+1);
                }
            }//如果点击的事大于等于7的按钮下标
            else if (CurrentShowPageIndex > (totalPageNumber - ShowBtnCount / 2)) {

                int startNumber = totalPageNumber - ShowBtnCount + 2;

                for (int i = 1; i < ShowBtnCount; i++) {
                    pbcList[i].Set(startNumber++);
                }
            }
        }

        /*
         判断总显示页数是否大于显示页数
         以防止出现这种效果:
         例如:totalPageNumber = 7,ShowBtnCount =7
         防止出现的效果:1  2  3  4  5  6  ..7  和  1..  2  3  4  5  6  7
         应该出现的效果: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>
    /// 设置信息
    /// </summary>
    /// <param name="totalPageNumber">总页数</param>
    /// <param name="showBtnCount">显示多少个按钮,填奇数,如果填偶数,则会强制减1,如:填6,则实际为5</param>
    /// <param name="lastBtnEvent">上一页按钮事件</param>
    /// <param name="nextBtnEvent">下一页按钮事件</param>
    /// <param name="pageBtnClickEvent">单独点击页面按钮事件</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>
    /// 重置所有按钮的状态
    /// </summary>
    void ResetPageBtnState() {
        for (int i = 0; i < pbcList.Count; i++) {
            pbcList[i].SetNormalColor();
        }
    }
    /// <summary>
    /// 回收所有页码
    /// </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>
    /// 根据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>
    /// 设置物体宽度   子物体宽度相同
    /// </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>
    /// 设置物体宽度   子物体宽度不同
    /// </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>
/// 页码按钮控制器
/// </summary>
public class PageBtnC : MonoBehaviour,IPool {
    /// <summary>
    /// 自己显示的页码
    /// </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>
    /// 设置正常颜色
    /// </summary>
    public void SetNormalColor() {
        img.color = normalColor;
        selfText.color = normalTextColor;
    }
    /// <summary>
    /// 设置高亮颜色
    /// </summary>
    public void SetHighlightColor() {
        img.color = highlightColor;
        selfText.color = highlightTextColor;
    }
    /// <summary>
    /// 设置事件   文本内容等
    /// </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 对象池接口方法
    public int GetMaxCount()
    {
        return 10;
    }

    public string SingletonName()
    {
        return this.GetType().Name;
    }

    public void Spawn()
    {
        Init();
    }

    public void UnSpawn()
    {
        SetNormalColor();
    }
    #endregion
}

github地址:https://github.com/yiwei151/PageTurnFunction

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
要实现在 Unity点击按钮翻页,可以按照以下步骤进行操作: 1. 创建一个 UI 按钮:在 Unity 中创建一个 Canvas,并在其中创建一个 Button。 2. 编写翻页逻辑:在代码中编写翻页逻辑,比如在按钮点击事件中切换页面。 3. 给按钮添加事件监听:将按钮的点击事件与翻页逻辑进行绑定,使得点击按钮时可以触发翻页逻辑。 4. 测试按钮功能:在 Unity 中运行程序,点击按钮测试翻页功能是否正常。 以下是一个简单的示例代码,可以在按钮点击时切换页面: ```csharp using UnityEngine; using UnityEngine.UI; public class PageController : MonoBehaviour { public GameObject[] pages; public Button nextPageButton; public Button prevPageButton; private int currentPageIndex = 0; void Start() { ShowPage(currentPageIndex); nextPageButton.onClick.AddListener(NextPage); prevPageButton.onClick.AddListener(PrevPage); } void NextPage() { if (currentPageIndex < pages.Length - 1) { currentPageIndex++; ShowPage(currentPageIndex); } } void PrevPage() { if (currentPageIndex > 0) { currentPageIndex--; ShowPage(currentPageIndex); } } void ShowPage(int index) { for (int i = 0; i < pages.Length; i++) { if (i == index) { pages[i].SetActive(true); } else { pages[i].SetActive(false); } } } } ``` 在这个示例中,我们定义了一个 PageController 类来管理页面的显示和翻页逻辑。在 Start 方法中,我们首先显示当前页面,然后将 NextPage 和 PrevPage 方法分别绑定到 nextPageButton 和 prevPageButton 的点击事件中。在 NextPage 和 PrevPage 方法中,我们检查是否可以翻页,然后更新 currentPageIndex 并调用 ShowPage 方法来显示新页面。在 ShowPage 方法中,我们遍历所有页面,只显示当前页面,隐藏其他页面。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值