【Unity】如何制作翻页UI
1众所周知Unity的滚轮很不好用,不像UE那边方便,所以用翻页的UI来代替滚轮
UI设置步骤
创建页面预制体
右键点击 Canvas → UI → Panel,命名为 “Page”。
在 Page 下添加名为Content的空物体,然后给Content添加Grid Layout Group组件,设置:
Cell Size:根据按钮大小调整(例如 100×50)。
Spacing:按钮间距。
Constraint:选择 “Fixed Column Count” 并设置列数(例如 2)。
将 Page 拖到项目面板创建预制体,然后从场景中删除。
创建主 UI 结构
在 Canvas 下创建一个空 GameObject,命名为 “PageContainer”,用于容纳所有页面。
添加 “上一页”、“下一页” 和 “添加按钮” 三个按钮。
添加一个 Text 组件显示页码信息。
关联脚本
创建一个空 GameObject,挂载PagedButtonUI脚本。
在 Inspector 中关联各组件引用:
pageContainer:拖入 “PageContainer”。
pagePrefab:拖入刚才创建的 Page 预制体。
addButton、prevButton、nextButton:分别拖入对应的按钮。
pageInfoText:拖入页码文本组件。
代码如下
using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;public class PagedButtonmanager : MonoBehaviour
{[SerializeField] private Transform pageContainer; // 页面父容器[SerializeField] private GameObject pagePrefab; // 页面预制体[SerializeField] private Button addButton; // 添加按钮[SerializeField] private Button prevButton; // 上一页按钮[SerializeField] private Button nextButton; // 下一页按钮[SerializeField] private Text pageInfoText; // 页码信息文本[SerializeField] private int buttonsPerPage = 10; // 每页按钮数量private List<GameObject> pages = new List<GameObject>(); // 所有页面private int currentPageIndex = 0; // 当前页码private int totalButtons = 0; // 总按钮数void Start(){// 初始化按钮事件addButton.onClick.AddListener(AddNewButton);prevButton.onClick.AddListener(GoToPrevPage);nextButton.onClick.AddListener(GoToNextPage);// 创建第一页CreateNewPage();UpdateNavigationButtons();}// 添加新按钮public void AddNewButton(){totalButtons++;// 检查是否需要创建新页面if ((totalButtons - 1) / buttonsPerPage >= pages.Count){CreateNewPage();}// 计算按钮应该在哪个页面int pageIndex = (totalButtons - 1) / buttonsPerPage;Transform pageContent = pages[pageIndex].transform.GetChild(0);// 从对象池获取或创建新按钮GameObject button = CreateButton();button.transform.SetParent(pageContent, false);button.GetComponentInChildren<Text>().text = "Button " + totalButtons;// 添加按钮点击事件Button btnComponent = button.GetComponent<Button>();btnComponent.onClick.RemoveAllListeners();btnComponent.onClick.AddListener(() => ButtonClicked(totalButtons));// 如果是新创建的页面,切换到该页面if (pageIndex == pages.Count - 1){GoToPage(pageIndex);}}// 创建新页面private GameObject CreateNewPage(){GameObject newPage = Instantiate(pagePrefab, pageContainer);newPage.name = "Page " + (pages.Count + 1);newPage.SetActive(pages.Count == 0); // 只激活第一页pages.Add(newPage);UpdatePageInfo();return newPage;}// 创建按钮private GameObject CreateButton(){// 这里可以实现对象池优化,避免频繁实例化GameObject button = new GameObject("Button");button.AddComponent<RectTransform>();// 添加按钮组件和文本Button btnComponent = button.AddComponent<Button>();GameObject textObj = new GameObject("Text");textObj.transform.SetParent(button.transform, false);Text textComponent = textObj.AddComponent<Text>();textComponent.text = "New Button";textComponent.alignment = TextAnchor.MiddleCenter;textComponent.font = Resources.GetBuiltinResource<Font>("Arial.ttf");// 设置按钮样式Image image = button.AddComponent<Image>();image.color = new Color(0.2f, 0.6f, 0.8f);// 设置文本位置RectTransform textRect = textObj.GetComponent<RectTransform>();textRect.anchorMin = Vector2.zero;textRect.anchorMax = Vector2.one;textRect.sizeDelta = Vector2.zero;return button;}// 按钮点击事件private void ButtonClicked(int buttonIndex){Debug.Log("Button " + buttonIndex + " clicked!");}// 切换到上一页private void GoToPrevPage(){if (currentPageIndex > 0){GoToPage(currentPageIndex - 1);}}// 切换到下一页private void GoToNextPage(){if (currentPageIndex < pages.Count - 1){GoToPage(currentPageIndex + 1);}}// 切换到指定页private void GoToPage(int pageIndex){if (pageIndex >= 0 && pageIndex < pages.Count){// 隐藏所有页面foreach (var page in pages){page.SetActive(false);}// 显示当前页pages[pageIndex].SetActive(true);currentPageIndex = pageIndex;UpdateNavigationButtons();UpdatePageInfo();}}// 更新导航按钮状态private void UpdateNavigationButtons(){prevButton.interactable = currentPageIndex > 0;nextButton.interactable = currentPageIndex < pages.Count - 1;}// 更新页码信息private void UpdatePageInfo(){if (pageInfoText != null){pageInfoText.text = $"Page {currentPageIndex + 1}/{pages.Count}";}}
}