Fantasy Real Time Calendar

Hello all. This is my first time here so please be gentle with me and I apologise If I say anything incredibly wrong.

I’m starting to develop a game with a friend and we are really on our first baby steps.
We do understand mostly Unity and some programming concepts, although, we aren’t masters whatsoever of any of it.

Therefor, one of the main concerns it’s time. The game we are making should work kindda like Civilization.
We want the player to get in game, a multiplayer game, time is already running and he just created his character in that Era, let’s put it this way.

I see Unity has some commands to capture real time, or in any language, we can, sortta easly, create a timer for when the player joins the game, but this is not accuratte, as not every month has 31 days, not every years has 365 days. We tryed a bit with Javascript, following some of the advices founded here too about the subject.

I was wondering if any of you could share some light on the subject. How to achieve the goal that is to have a permanent timer or calender displayed in-game, telling the characters that they are in the day x of the month x of the year x.

We would even like to make this work with the daycicle from Unity, I mean, the day last’s for 24h ficticious hours and when the sun comes up, another day rises with another ficcticious 24h hours (yes, I know, it should be like 14-16 hours of light, 8-10 hours of dark).

So… I know I write alot. I’m hoping to find some help here from someone alot more enlighten than me about this subject. Can you please help?

Thank you for you effort. :wink:

Cheers!

There’s a .NET class called DateTime. it’s useful for Gregorian calendar. I don’t think it can go further than year 1 though, so I’m not sure how to represent BC. You might have to write your own calendar system, if it’s needed. Here’s an example of how DateTime can be used:

using UnityEngine;
using System.Collections;
using System;

public class FantasyTime : MonoBehaviour {

    DateTime dateTime;
    
    // start date and time

    [Range(1, 4000)]
    public int year = 1;

    [Range(1, 12)]
    public int month = 1;

    [Range(1, 31)]
    public int day = 1;

    [Range(0, 23)]
    public int hour;

    [Range(0, 59)]
    public int minute;

    [Range(0, 59)]
    public int second;

    // scale of 1 is real-time
    [Range(-99999f, 99999f)]
    public float timeScale = 10000f;

	// Use this for initialization
	void Start () {
        dateTime = new DateTime(year, 1, 1);
        //Subtract 1 month and 1 day, because we're adding to the dateTime
        //January is the 1st month, but if we add 1 month to dateTime, it will be February
        dateTime = dateTime.AddMonths(month - 1);
        dateTime = dateTime.Add(new TimeSpan(day - 1, hour, minute, second, 0));
    }

    // Update is called once per frame
    void Update() {       
        dateTime = dateTime.AddSeconds(Time.deltaTime * Time.timeScale * timeScale);
    }

    // Quick way to display info, not meant for production
    void OnGUI() {
        string timeString = dateTime.ToLongDateString() + Environment.NewLine + dateTime.ToLongTimeString();
        GUI.Box(new Rect(0f, 0f, 200f, 40f), timeString);
    }
    
    // Milliseconds passed in current day
    public float MillisecondsPassedInCurrentDay() {
        return dateTime.Hour * 60f * 60f * 1000f + 
            dateTime.Minute * 60f * 1000f + 
            dateTime.Second * 1000f + 
            dateTime.Millisecond;
    }
}

Example of a simple day cycle using the FantasyTime class:

using UnityEngine;
using System.Collections;

[RequireComponent(typeof(Light))]
public class SimpleDayCycle : MonoBehaviour {

    FantasyTime fantasyTime;

    private float millisecondsInDay = (24f * 60f * 60f * 1000f);

    // Use this for initialization
    void Start () {
        fantasyTime = FindObjectOfType<FantasyTime>();
        if (fantasyTime == null)
            this.enabled = false;
	}
	
	// Update is called once per frame
	void Update () {
        float lerp = fantasyTime.MillisecondsPassedInCurrentDay() / millisecondsInDay;
        transform.localRotation = Quaternion.Euler(new Vector3(Mathf.Lerp(-90f, 269f, lerp), 0f, 0f));
    }
}

Hopefully, these scripts demonstrate some basics. Adding complexity will require more work. Day night cycle is a common question, so there’s examples available if you search for them. 1, 2

I should also mention, the Unity Asset store has some amazing assets. They can be pricey, but they do exist.