- Home /
How to make a date/time system with a fast forward feature?
I was thinking about a system as can be seen in games such as The Sims, SimCity, Cities: Skylines, Europa Universalis, etc. It is for an population/economy simulator. The date shall constantly be displayed in a corner. As the NPCs are supposed to age over time, they need to interact with it as well (birthday event).
My attempt is shown below but I am convinced it is really bad (i.e. months only have 31 days). Most other scripts stop running when time runs too fast.
Instead of fixing it, I would prefer to completely rewrite it. Maybe with invoke repeat to avoid the Update method?
Thanks for your help!
using System.Collections; using System.Collections.Generic; using UnityEngine; using System; using UnityEngine.UI;
public class dayCycle : MonoBehaviour {
public float time;
public TimeSpan currentTime;
public Text timeText;
public static int years;
public static int months;
public static int days;
public static int hours;
public float minutes;
public static int timeSpeed;
public static int speed;
// Use this for initialization
void Start () {
days = 0;
months = 1;
years = 2100;
timeSpeed = 1;
speed = 16;
}
// Update is called once per frame
void Update ()
{
ChangeTime();
if (Input.GetKeyDown(KeyCode.KeypadPlus))
{
timeSpeed = timeSpeed + 1;
}
if (timeSpeed > 2)
{
timeSpeed = 2;
}
if (Input.GetKeyDown(KeyCode.KeypadMinus))
{
timeSpeed = timeSpeed - 1;
}
if (timeSpeed < 0)
{
timeSpeed = 0;
}
}
public void ChangeTime()
{
time += Time.deltaTime * speed;
if (time >= 1 && timeSpeed == 0)
{
minutes += 1;
time = 0;
}
else if (time >= 1 && timeSpeed == 1)
{
minutes = 1 / 60;
hours += 1;
time = 0;
}
else if (time >= 1 && timeSpeed == 2)
{
minutes = 1 / 1440;
hours = 1 / 24;
days += 1;
time = 0;
}
if (minutes == 60 && timeSpeed == 0)
{
hours += 0;
minutes = 0;
}
if (hours == 24)
{
days += 1;
hours = 1;
}
if (days == 32)
{
months += 1;
days = 1;
}
if (months == 13)
{
years += 1;
months = 1;
}
currentTime = TimeSpan.FromSeconds(time);
timeText.text = years + "y " + months + "m " + days + "days " + hours + "h " + minutes + "min";
}
}
Answer by bobisgod234 · Jul 14, 2017 at 05:42 AM
.NET already has very robust and mature date and time handling builtin. e.g. the DateTime structure. It has functions to add/subtract lengths of time, compare DateTimes, etc, and can pretty much do everything you want.
Fast Forwarding with this structure would be as simple as using a float multiplier.
Thanks, I will look into it. For now, I improved my old version and am quite happy with the result. Once I figure out the DateTime structure features, it might be redundant. It was a good learning exercise, though :)
Answer by EuRoKa · Jul 15, 2017 at 08:59 AM
I improved the first version and now created a complete date system outside of the .NET DateTime structure. It recognizes leap years, fast forwards minutes, hours, days, and is easy to access.
using UnityEngine;
using UnityEngine.UI;
public class DateTimeManager : MonoBehaviour
{
public float timeScale;
public int timeMode;
public int startHour, startDay, startMonth, startYear;
public string monthName;
public bool am, noonAm, leapYear;
private Text calendarText;
public double minute, hour, day, second, month;
public int year;
void Start()
{
startHour = 6;
startDay = 15;
startMonth = 07;
startYear = 2017;
year = startYear;
month = startMonth;
day = startDay;
hour = startHour;
year = startYear;
timeMode = 1; //mode 2 and 3 for fast forwarding hours and days respectively
timeScale = 200.0f; //change time speed: 200 = one hour takes 18 seconds
am = true;
noonAm = false; //true = noon is AM; option for 12 am/pm confusion
calendarText = GameObject.Find("Calendar").GetComponent<Text>(); //create text box "Calendar" in Unity
DetermineMonth();
}
void Update()
{
CalculateTime();
}
//for UI
void TextCallFunction()
{
// minutes included
if (timeMode == 1)
{
if (am == true)
{
if (hour <= 9) //single digit hours get a 0
{
if (minute <= 9)
{
calendarText.text = monthName + " " + day + " " + year + " " + "0" + hour + ":0" + minute + " AM";
}
else
{
calendarText.text = monthName + " " + day + " " + year + " " + "0" + hour + ":" + minute + " AM";
}
}
else if (minute <= 9)
{
calendarText.text = monthName + " " + day + " " + year + " " + hour + ":0" + minute + " AM";
if (noonAm == false && hour == 12)
{
calendarText.text = monthName + " " + day + " " + year + " " + hour + ":0" + minute + " PM";
}
}
else
{
calendarText.text = monthName + " " + day + " " + year + " " + hour + ":" + minute + " AM";
if (noonAm == false && hour == 12)
{
calendarText.text = monthName + " " + day + " " + year + " " + hour + ":" + minute + " PM";
}
}
}
else if (am == false)
{
if (hour <= 9)
{
if (minute <= 9)
{
calendarText.text = monthName + " " + day + " " + year + " " + "0" + hour + ":0" + minute + " PM";
}
else
{
calendarText.text = monthName + " " + day + " " + year + " " + "0" + hour + ":" + minute + " PM";
}
}
else
{
if (minute <= 9)
{
calendarText.text = monthName + " " + day + " " + year + " " + hour + ":0" + minute + " PM";
if (noonAm == false && hour == 12)
{
calendarText.text = monthName + " " + day + " " + year + " " + hour + ":0" + minute + " AM";
}
}
else
{
calendarText.text = monthName + " " + day + " " + year + " " + hour + ":" + minute + " PM";
if (noonAm == false && hour == 12)
{
calendarText.text = monthName + " " + day + " " + year + " " + hour + ":" + minute + " AM";
}
}
}
}
}
//minutes excluded
else if (timeMode == 2)
{
if (am == true)
{
calendarText.text = monthName + " " + day + " " + year + " " + hour + " AM";
if (noonAm == false && hour == 12)
{
calendarText.text = monthName + " " + day + " " + year + " " + hour + " PM";
}
}
else if (am == false)
{
calendarText.text = monthName + " " + day + " " + year + " " + hour + " PM";
if (noonAm == false && hour == 12)
{
calendarText.text = monthName + " " + day + " " + year + " " + hour + " AM";
}
}
}
//hours excluded
else if (timeMode == 3)
{
calendarText.text = monthName + " " + day + " " + year;
}
}
//determining month names
void DetermineMonth()
{
if (month == 1)
{
monthName = "Jan";
}
if (month == 2)
{
monthName = "Feb";
}
if (month == 3)
{
monthName = "Mar";
}
if (month == 4)
{
monthName = "Apr";
}
if (month == 5)
{
monthName = "May";
}
if (month == 6)
{
monthName = "Jun";
}
if (month == 7)
{
monthName = "Jul";
}
if (month == 8)
{
monthName = "Aug";
}
if (month == 9)
{
monthName = "Sep";
}
if (month == 10)
{
monthName = "Oct";
}
if (month == 11)
{
monthName = "Nov";
}
if (month == 12)
{
monthName = "Dec";
}
TextCallFunction();
}
//determining total days in a month and leap years
void CalculateMonthLength()
{
if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12)
{
if (day >= 32)
{
month++;
day = 1;
DetermineMonth();
}
}
if (month == 2)
{
if (day >= 29)
{
//leap year
if (year % 4 == 0 && year % 100 != 0)
{
TextCallFunction();
DetermineMonth();
leapYear = true;
}
if (leapYear == false)
{
month++;
day = 1;
DetermineMonth();
}
else if (day == 30)
{
month++;
day = 1;
DetermineMonth();
}
}
if (month == 4 || month == 6 || month == 9 || month == 11)
{
if (day >= 31)
{
month++;
day = 1;
DetermineMonth();
}
}
}
}
//time counter
void CalculateTime()
{
if (timeMode == 1)
{
second += Time.fixedDeltaTime * timeScale;
if (second >= 60)
{
minute++;
second = 0;
TextCallFunction();
}
else if (minute >= 60)
{
if (hour <= 12 && am == true)
{
hour++;
if (hour >= 13)
{
am = false;
hour = 1;
}
}
else if (hour <= 12 && am == false)
{
hour++;
if (hour == 12)
{
day++;
}
else if (hour >= 13)
{
hour = 1;
am = true;
}
}
minute = 0;
TextCallFunction();
}
else if (day >= 28)
{
CalculateMonthLength();
}
else if (month >= 12)
{
month = 1;
year++;
DetermineMonth();
}
}
else if (timeMode == 2)
{
minute++;
timeScale = 1;
if (second >= 60)
{
minute++;
second = 0;
TextCallFunction();
}
else if (minute >= 60)
{
if (hour <= 12 && am == true)
{
hour++;
if (hour >= 13)
{
am = false;
hour = 1;
}
}
else if (hour <= 12 && am == false)
{
hour++;
if (hour == 12)
{
day++;
}
else if (hour >= 13)
{
hour = 1;
am = true;
}
}
minute = 0;
TextCallFunction();
}
else if (day >= 28)
{
CalculateMonthLength();
}
else if (month >= 12)
{
month = 1;
year++;
DetermineMonth();
}
}
else if (timeMode == 3)
{
second += Time.fixedDeltaTime * timeScale;
timeScale = 1;
if (second >= 0.4f)
{
day++;
second = 0;
DetermineMonth();
}
else if (day >= 28)
{
CalculateMonthLength();
DetermineMonth();
}
else if (month >= 12)
{
month = 1;
year++;
DetermineMonth();
}
}
}
}
Your answer
Follow this Question
Related Questions
putting the date into a variable 1 Answer
How to compare two dates? 1 Answer
How do I make a Countdown Timer in Minutes and Seconds only 1 Answer
on trigger enter, start timer, end when button is pressed & output reaction time. 1 Answer
How to make notification appear at certain time without having to press button again? 2 Answers