直接上代码:
using System;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class CalendarController : MonoBehaviour
{
[SerializeField]private TMP_Text dateText;
[SerializeField]private GameObject itemPrefab;
[SerializeField]private Button nextMonth;
[SerializeField]private Button lastMonth;
private readonly List<GameObject> _dateItems = new();
private const int TotalDateNum = 42;
private const int ItemWidth = 43;
private const int ItemHeight = 43;
private const int LeftAndRightSpacing = 16;
private const int UpperAndLowerSpacing = 10;
private DateTime _dateTime;
private Color _color;
void Start()
{
_color = new Color(0.9176471f,0.9176471f,0.9176471f);
nextMonth.onClick.AddListener(MonthNext);
lastMonth.onClick.AddListener(MonthPrev);
InitItems();
_dateTime = DateTime.Now;
CreateCalendar();
}
private void InitItems()
{
Vector3 startPos = itemPrefab.transform.localPosition;
_dateItems.Clear();
_dateItems.Add(itemPrefab);
for (int i = 1; i < TotalDateNum; i++)
{
GameObject item = Instantiate(itemPrefab,itemPrefab.transform.parent);
item.name = "Item" + (i + 1);
item.transform.localScale = Vector3.one;
item.transform.localRotation = Quaternion.identity;
item.transform.localPosition = new Vector3((i % 7) * (ItemWidth+LeftAndRightSpacing) + startPos.x, startPos.y - (int)(i / 7) * (ItemHeight+UpperAndLowerSpacing), startPos.z);
item.SetActive(true);
_dateItems.Add(item);
}
}
private void CreateCalendar()
{
DateTime firstDay = _dateTime.AddDays(-(_dateTime.Day - 1));
int index = GetDays(firstDay.DayOfWeek);
int monthAllDay = _dateTime.Month - 1 <= 0 ? GetMonthAllDay(_dateTime.Year - 1, 12)
: GetMonthAllDay(_dateTime.Year, _dateTime.Month-1);
for (int i = 0; i < index; i++)
{
TMP_Text label = _dateItems[i].GetComponentInChildren<TMP_Text>();
label.text = (monthAllDay - index + i + 1).ToString();
label.color = _color;
}
int date = 0;
int nextDate = 1;
for (int i = index; i < TotalDateNum; i++)
{
TMP_Text label = _dateItems[i].GetComponentInChildren<TMP_Text>();
DateTime thatDay = firstDay.AddDays(date);
if (thatDay.Month == firstDay.Month)
{
label.text = (date + 1).ToString();
label.color = Color.white;
}
else
{
label.text = nextDate.ToString();
label.color = _color;
nextDate++;
}
date++;
}
dateText.text = $"{_dateTime.Year}年{_dateTime.Month}月";
}
private int GetDays(DayOfWeek day)
{
switch (day)
{
case DayOfWeek.Monday: return 1;
case DayOfWeek.Tuesday: return 2;
case DayOfWeek.Wednesday: return 3;
case DayOfWeek.Thursday: return 4;
case DayOfWeek.Friday: return 5;
case DayOfWeek.Saturday: return 6;
case DayOfWeek.Sunday: return 0;
}
return 0;
}
private void YearPrev()
{
_dateTime = _dateTime.AddYears(-1);
CreateCalendar();
}
private void YearNext()
{
_dateTime = _dateTime.AddYears(1);
CreateCalendar();
}
private void MonthPrev()
{
_dateTime = _dateTime.AddMonths(-1);
CreateCalendar();
}
private void MonthNext()
{
_dateTime = _dateTime.AddMonths(1);
CreateCalendar();
}
private void OnDateItemClick(string day)
{
}
private int GetMonthAllDay(int year,int month)
{
return DateTime.DaysInMonth(year, month);
}
}