I have been trying to create in-game time/calendar system.
In my current project I want to be able to register events at specific times on specific days/seasons.
An in-game day is 30 minutes, each month is 30 days long, there are the usual 4 seasons.
So far I have decided a singleton class called TimeManager will handle the in-game time/date and this is where things can register an event at a specific time.
public class TimeManager : MonoBehaviour
{
public float timeMultiplier = 1f;
//One in-game day is 30 minutes.
public float MINUTES_IN_INGAME_DAY = 30f;
//there are 1800 seconds in 30 minutes
public float INGAME_DAY_IN_SECONDS = 1800f;
//there 60 seconds to a minute
public static float SECONDS_IN_MINUTES = 60f;
public static int DAYS_IN_MONTH = 30;
public static TimeManager Instance;
private int _CurrentDay = 0;
private int _CurrentYear = 0;
private int _CurrentMonth = 0;
private int _CurrentSeason = 0;
private float CurrentBaseTime = 0;
public Days CurrentDay = Days.MONDAY;
public Seasons CurrentSeason = Seasons.SPRING;
public Months CurrentMonth = Months.JANUARY;
private void Awake()
{
Instance = this;
}
private void Update()
{
UpdateTime();
}
private void OnValidate()
{
INGAME_DAY_IN_SECONDS = MINUTES_IN_INGAME_DAY * SECONDS_IN_MINUTES;
}
private void UpdateTime()
{
CurrentBaseTime += Time.deltaTime * timeMultiplier;
if (CurrentBaseTime >= INGAME_DAY_IN_SECONDS)
{
//new month
if(_CurrentDay > DAYS_IN_MONTH)
{
_CurrentDay = 0;
_CurrentMonth++;
//new year, reset season
if (_CurrentMonth > 12)
{
_CurrentYear++;
_CurrentMonth = 0;
CurrentSeason = Seasons.SPRING;
}
//new season
if (_CurrentMonth % 4 == 0)
{
_CurrentSeason++;
CurrentSeason = (Seasons)(_CurrentSeason % 4);
}
CurrentMonth = (Months)_CurrentMonth;
}
else
{
//same month
_CurrentDay++;
}
CurrentDay = (Days)(_CurrentDay % 7);
//reset time to "midnight"
CurrentBaseTime = 0;
}
}
public int GetCurrentDay()
{
return _CurrentDay;
}
public float GetTimeInMinutes(float elapsedTime)
{
return (elapsedTime / SECONDS_IN_MINUTES);
}
public float GetTimeInHours(float elapsedTime)
{
return (elapsedTime / SECONDS_IN_MINUTES / MINUTES_IN_INGAME_DAY) * 24f;
}
private void OnGUI()
{
GUI.color = Color.black;
GUI.Label(new Rect(10f, 0f, 400f, 20f), new GUIContent("World Time Info"));
GUI.Label(new Rect(10f, 20f, 400f, 20f), new GUIContent("Current Time In Seconds : " + CurrentBaseTime));
GUI.Label(new Rect(10f, 40f, 400f, 20f), new GUIContent("Current Day : " + GetCurrentDay()));
GUI.Label(new Rect(10f, 60f, 400f, 20f), string.Format("H: {0} M : {1} S : {2}" , Mathf.Round(GetTimeInHours(CurrentBaseTime)), Mathf.Round(GetTimeInMinutes(CurrentBaseTime)), CurrentBaseTime - GetTimeInHours(CurrentBaseTime)));
}
}
The problem I am having is taking the total seconds of the day and properly converting it to a 24 hour format, currently for every 2 times the minutes increments the hour value will go up by one. (gif included watch the minutes and hours)
I am entirely unsure where how to proceed with this, It's reached a point where I am bashing random things in and watching the outcome to see if it matches what I expect, I would like help converting in-game day in seconds to hours/minutes/seconds, in 24 hour format if possible.
I have read up on an alternative but atleast the one I read involved using the DateTime class, which I don't think would help me in my case, as the day and month length are none standard.
Thank you for reading.