Source Code for LevelSelector.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
public class LevelSelector : MonoBehaviour{
public GameObject levelHolder;
public GameObject levelIcon;
public GameObject thisCanvas;
public int numberOfLevels = 50;
public Vector2 iconSpacing;
private Rect panelDimensions;
private Rect iconDimensions;
private int amountPerPage;
private int currentLevelCount;
// Start is called before the first frame update
void Start(){
panelDimensions = levelHolder.GetComponent<RectTransform>().rect;
iconDimensions = levelIcon.GetComponent<RectTransform>().rect;
int maxInARow = Mathf.FloorToInt((panelDimensions.width + iconSpacing.x) / (iconDimensions.width + iconSpacing.x));
int maxInACol = Mathf.FloorToInt((panelDimensions.height + iconSpacing.y) / (iconDimensions.height + iconSpacing.y));
amountPerPage = maxInARow * maxInACol;
int totalPages = Mathf.CeilToInt((float)numberOfLevels / amountPerPage);
LoadPanels(totalPages);
}
void LoadPanels(int numberOfPanels){
GameObject panelClone = Instantiate(levelHolder) as GameObject;
PageSwiper swiper = levelHolder.AddComponent<PageSwiper>();
swiper.totalPages = numberOfPanels;
for(int i = 1; i <= numberOfPanels; i++){
GameObject panel = Instantiate(panelClone) as GameObject;
panel.transform.SetParent(thisCanvas.transform, false);
panel.transform.SetParent(levelHolder.transform);
panel.name = "Page-" + i;
panel.GetComponent<RectTransform>().localPosition = new Vector2(panelDimensions.width * (i-1), 0);
SetUpGrid(panel);
int numberOfIcons = i == numberOfPanels ? numberOfLevels - currentLevelCount : amountPerPage;
LoadIcons(numberOfIcons, panel);
}
Destroy(panelClone);
}
void SetUpGrid(GameObject panel){
GridLayoutGroup grid = panel.AddComponent<GridLayoutGroup>();
grid.cellSize = new Vector2(iconDimensions.width, iconDimensions.height);
grid.childAlignment = TextAnchor.MiddleCenter;
grid.spacing = iconSpacing;
}
void LoadIcons(int numberOfIcons, GameObject parentObject){
for(int i = 1; i <= numberOfIcons; i++){
currentLevelCount++;
GameObject icon = Instantiate(levelIcon) as GameObject;
icon.transform.SetParent(thisCanvas.transform, false);
icon.transform.SetParent(parentObject.transform);
icon.name = "Level " + i;
icon.GetComponentInChildren<TextMeshProUGUI>().SetText("Level " + currentLevelCount);
}
}
// Update is called once per frame
void Update(){
}
}
Source Code for PageSwiper.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class PageSwiper : MonoBehaviour, IDragHandler, IEndDragHandler{
private Vector3 panelLocation;
public float percentThreshold = 0.2f;
public float easing = 0.5f;
public int totalPages = 1;
private int currentPage = 1;
// Start is called before the first frame update
void Start(){
panelLocation = transform.position;
}
public void OnDrag(PointerEventData data){
float difference = data.pressPosition.x - data.position.x;
transform.position = panelLocation - new Vector3(difference, 0, 0);
}
public void OnEndDrag(PointerEventData data){
float percentage = (data.pressPosition.x - data.position.x) / Screen.width;
if(Mathf.Abs(percentage) >= percentThreshold){
Vector3 newLocation = panelLocation;
if(percentage > 0 && currentPage < totalPages){
currentPage++;
newLocation += new Vector3(-Screen.width, 0, 0);
}else if(percentage < 0 && currentPage > 1){
currentPage--;
newLocation += new Vector3(Screen.width, 0, 0);
}
StartCoroutine(SmoothMove(transform.position, newLocation, easing));
panelLocation = newLocation;
}else{
StartCoroutine(SmoothMove(transform.position, panelLocation, easing));
}
}
IEnumerator SmoothMove(Vector3 startpos, Vector3 endpos, float seconds){
float t = 0f;
while(t <= 1.0){
t += Time.deltaTime / seconds;
transform.position = Vector3.Lerp(startpos, endpos, Mathf.SmoothStep(0f, 1f, t));
yield return null;
}
}
}