您现在的位置是:首页 >技术杂谈 >Unity 实现实时日历网站首页技术杂谈

Unity 实现实时日历

一条闲の鱼 2025-03-27 12:01:02
简介Unity 实现实时日历

Unity 实现日历功能

功能描述

在 Unity 中实现一个简单的日历功能。该日历能够显示当前月份的所有日期,自动高亮当天日期,并允许用户选择高亮其他日期。用户还可以通过按钮切换到上一个月或下一个月,并点击某个日期以获取其具体信息。

项目结构

UI 组件

在这里插入图片描述

  • Year Text: 显示当前年份的文本组件。
  • Month Text: 显示当前月份的文本组件。
  • Day Grid: 使用 GridLayoutGroup 管理日期按钮的父对象,用于排列和显示每一天。
  • Day Button Prefab: 日期按钮预制体,包含一个 Toggle 组件和一个用于显示日期数字的 Text 组件。
  • LastMonthBtn/NextMonthBtn: 用于切换月份的按钮。

脚本文件

  • CalendarCtrl.cs: 控制日历逻辑的脚本,实现显示当前日期、高亮当天、选择其他日期以及月份切换功能。

全部代码

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
/**********************************
 *作者:一条闲の鱼
 *时间:2024-11-08 10:28:18
 *邮箱:1536604034@qq.com
 *版本:1.0
 *Unity版本:2019.4.30f1c3
 **********************************/
/// <summary>
/// 描述:显示日历
/// </summary>
public class CalendarCtrl : MonoBehaviour
{
    [Header("年份文本")]
    public Text yearText;
    [Header("月份文本")]
    public Text monthText;
    [Header("生成天数父物体")]
    public GridLayoutGroup dayGrid;
    [Header("天数预制体")]
    public GameObject dayButtonPrefab; // 用于显示日期的预制件
    public int startDayOfWeek = 0; // 0 for Sunday, 1 for Monday, etc.
    private DateTime currentDate;
    /// <summary>
    /// 真实系统时间
    /// </summary>
    private DateTime rightDateTime;
    void Start()
    {
        currentDate = DateTime.Now;
        rightDateTime = DateTime.Now;
        UpdateCalendar();
    }
    void UpdateCalendar()
    {
        // 清除现有的按钮
        foreach (Transform child in dayGrid.transform)
        {
            Destroy(child.gameObject);
        }
        // 设置当前月份和年份
        yearText.text = currentDate.ToString("yyyy-MMM").Split('-')[0];
        monthText.text = currentDate.ToString("yyyy-MMMM").Split('-')[1];
        // 获取当前月份的第一天和总天数
        DateTime firstDayOfMonth = new DateTime(currentDate.Year, 
currentDate.Month, 1);
        int daysInMonth = DateTime.DaysInMonth(currentDate.Year, 
currentDate.Month);
        // 上个月的信息
        DateTime previousMonth = currentDate.AddMonths(-1);
        int daysInPreviousMonth = DateTime.DaysInMonth(previousMonth.Year, 
previousMonth.Month);
        // 填充前面的空白天数
        int startDayOffset = ((int)firstDayOfMonth.DayOfWeek - startDayOfWeek + 7) 
% 7;
        for (int i = 0; i < startDayOffset; i++)
        {
            int previousMonthDay = daysInPreviousMonth - startDayOffset + i + 1;
            DateTime date = new DateTime(previousMonth.Year, previousMonth.Month, 
previousMonthDay);
            CreateDayButton(date, false); // false 表示这些日期属于上个月
        }
        // 创建每一天的按钮
        for (int day = 1; day <= daysInMonth; day++)
        {
            DateTime date = new DateTime(currentDate.Year, currentDate.Month, day);
            CreateDayButton(date, true); // true 表示这些日期属于当前月
        }
        // 下个月的信息
        int endDayOffset = (startDayOffset + daysInMonth) % 7;
        if (endDayOffset != 0)
        {
            for (int i = 0; i < 7 - endDayOffset; i++)
            {
                DateTime date = new DateTime(currentDate.Year, currentDate.Month, 
1).AddDays(daysInMonth + i);
                CreateDayButton(date, false); // false 表示这些日期属于下个月
            }
        }
    }
    void CreateDayButton(DateTime date, bool isCurrentMonth)
    {
        GameObject dayButton = Instantiate(dayButtonPrefab, dayGrid.transform);
        dayButton.GetComponentInChildren<Text>().text = date.Day.ToString();
        // 根据是否是当前月设置按钮的外观
        if (!isCurrentMonth)
        {
            dayButton.GetComponentInChildren<Text>().color = Color.gray;
        }
        dayButton.name = date.ToString("yy-MMM-d");
        // 添加点击事件
        dayButton.GetComponent<Toggle>().onValueChanged.AddListener((isOn) => { if 
(isOn) OnDayButtonClicked(date); } );
        dayButton.GetComponent<Toggle>().group = 
transform.Find("Panel").GetComponent<ToggleGroup>();
        if (date.Year == rightDateTime.Year && date.Month == rightDateTime.Month && 
date.Day == rightDateTime.Day)
        {
            dayButton.GetComponent<Toggle>().isOn = true;
            dayButton.transform.Find("Text").GetComponent<Text>().color = 
Color.green;
        }
    }
    public void OnDayButtonClicked(DateTime date)
    {
        Debug.Log("Clicked on date: " + date.ToString("yyyy/MM/dd"));
    }
    // 添加方法以切换月份
    //通过按钮点击事件绑定
    public void NextMonth()
    {
        currentDate = currentDate.AddMonths(1);
        UpdateCalendar();
    }
    public void PreviousMonth()
    {
        currentDate = currentDate.AddMonths(-1);
        UpdateCalendar();
    }
}

关键功能

  • UpdateCalendar(): 更新日历视图,包括清除旧的按钮和生成新的日期按钮。
  • CreateDayButton(): 创建每个日期按钮,并根据是否为当前月设置外观。
  • Toggle 交互: 每个日期按钮都附带一个 Toggle 组件,通过事件监听实现日期选择与日志输出。

UI 配置

  • Canvas 设置: 使用 Screen Space - Overlay 模式确保 UI 始终显示在屏幕上,结合 Canvas Scaler 调整不同分辨率下的显示效果。
  • Hierarchy 视图: 在层级视图中,CalendarUIScreen 对象包含了面板和所有相关的 UI 子对象,确保各个元素清晰管理。
  • Inspector 检查: 确保所有必需的 UI 组件正确链接到 CalendarCtrl 脚本。
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。