Scripts/Managers/DayNightManager.cs
using System;
using Milaine.Interfaces;
namespace Milaine.Managers;
public sealed class DayNightManager : Component, IManager {
// 60 -> seconds
private const int MINUTE = 60;
// 5 mins
private const int MAX_TIME = 5 * MINUTE;
public const int MAX_DAYS = 5;
[Property]
public float DayDuration { get; set; } = MAX_TIME;
[Property]
public int Day { get; set; } = 1;
// hour in 24h
private readonly float startHour = 8f;
private readonly float endHour = 18f;
private bool isDayActive = false;
private TimeUntil timeUntilNight;
public string CurrentTimeString { get; private set; } = "8:00 AM";
public Action OnStartDay;
public Action OnEndDay;
protected override void OnStart() {
StartDay();
}
protected override void OnUpdate() {
if (!isDayActive) {
return;
}
float elapsedSeconds = DayDuration - timeUntilNight;
float progress = MathX.Clamp(elapsedSeconds / DayDuration, 0f, 1f);
float totalVirtualHours = endHour - startHour;
float currentVirtualHour = startHour + (progress * totalVirtualHours);
int hours = (int)MathF.Floor(currentVirtualHour);
int minutes = (int)MathF.Floor((currentVirtualHour - hours) * 60f);
string amPm = hours >= 12 ? "PM" : "AM";
int displayHour = hours % 12;
if (displayHour == 0) {
displayHour = 12;
}
CurrentTimeString = $"{displayHour:D2}:{minutes:D2} {amPm}";
if (timeUntilNight) {
EndDay();
}
}
private void StartDay() {
if (isDayActive) {
return;
}
timeUntilNight = DayDuration;
isDayActive = true;
OnStartDay?.Invoke();
}
private void EndDay() {
ResetManager(deep: false);
OnEndDay?.Invoke();
}
public void ResetManager(bool deep = false) {
if (deep) {
CurrentTimeString = "8:00 AM";
}
isDayActive = false;
}
public void NextDay() {
if (Day >= MAX_DAYS) {
return;
}
Day += 1;
StartDay();
}
public void Restart() {
Day = 1;
StartDay();
}
}