Accelerate/Decelerate Custom Game Clock

I created a game clock to have an ingame reference to time, plus, to have a variable defining certain events (like day/night cycle, temperature, seasons, etc.).

It works fine when I set the “timespeedmultiplier” and then hit start to simulate the game. It has to be set to the quantity of seconds that passes in one real second. So if “timespeedmult.” is set at 60, each game minute passes every real second.

The problem comes when I created buttons on the GUI(custom planes with raycast) to be able to change the speed of the game while it’s running. What happens is the time just shifts massively.

Example; if it goes realtime (1 sec = 1 sec) and I switch “timespeedmultiplier” to 60 (1 minute = 1 sec) instead of just speeding up from the actual time, it adds time and then goes quicker. So the problem is that “adding time” thing, I dont know why it happens.
If it’s minute 5 and hour 2, it jumps to (I don’t exactly know) 30 minutes and 6 hours, which, obviously, I don’t want to happen.

Here the code(I skipped the non-time related code); Its C#.

``````///VARIABLES///

public double timeSpeedMultiplier; ///set in inspector then switched ingame
private double realSECOND = 0;

private const double SECONDinSeconds = 1;
private const double MINUTEinSeconds = SECONDinSeconds * 60;
private const double HOURinSeconds = MINUTEinSeconds * 60;
private const double DAYinSeconds = HOURinSeconds * 24;
private const double MONTHinSeconds = DAYinSeconds * (365/12);
private const double YEARinSeconds = MONTHinSeconds * 12;

///UPDATE()///

realSECOND += Time.deltaTime;   ///Real seconds

SECOND = realSECOND * timeSpeedMultiplier;   ///Game seconds
MINUTE = (SECOND/MINUTEinSeconds);
HOUR = ((MINUTE*MINUTEinSeconds)/HOURinSeconds);
DAY = ((HOUR*HOURinSeconds)/DAYinSeconds);
MONTH = ((DAY*DAYinSeconds)/MONTHinSeconds);
YEAR = ((MONTH*MONTHinSeconds)/YEARinSeconds);
``````

I finally got it! I rewrote the whole thing. This code should actually work copy/pasting for those interested. 1,2,3,4 and 5 keys are to change time speed, and it’s displayed with OnGUI function.

The useful variable here is “totalGameSeconds”, which is the time in seconds that has passed since startup taking in account the user speed choices.

``````using UnityEngine;
using System.Collections;

public class GameTimer : MonoBehaviour {

public double totalGameSeconds;

public double seconds;
public double minutes;
public double hours;
public double days;
public double months;
public double years;

private double secondsPerSecond;

void Start () {

secondsPerSecond = 1;
totalGameSeconds += secondsPerSecond * Time.deltaTime;

}

void Update () {

if( Input.GetKeyDown(KeyCode.Alpha1)){
secondsPerSecond = 1;

}
else if( Input.GetKeyDown(KeyCode.Alpha2)){
secondsPerSecond = 60;

}
else if( Input.GetKeyDown(KeyCode.Alpha3)){
secondsPerSecond = 3600;

}
else if( Input.GetKeyDown(KeyCode.Alpha4)){
secondsPerSecond = 86400;

}
else if( Input.GetKeyDown(KeyCode.Alpha5)){
secondsPerSecond = 2629743;

}

totalGameSeconds += secondsPerSecond * Time.deltaTime;

seconds = totalGameSeconds;
minutes = totalGameSeconds / 60;
hours = minutes / 60;
days = hours / 24;
months = days / (365/12);
years = months / 12;
}

void OnGUI(){

GUI.Label(new Rect(0,200, 500, 500), "Total Seconds: " + totalGameSeconds);
GUI.Label(new Rect(0,225, 500, 500), "Seconds Per Second: " + secondsPerSecond);

GUI.Label(new Rect(0,250, 500, 500), "Second: " + (int)seconds%60);
GUI.Label(new Rect(0,275, 500, 500), "Minute: " + (int)minutes%60);
GUI.Label(new Rect(0,300, 500, 500), "Hour: " + (int)hours%24);
GUI.Label(new Rect(0,325, 500, 500), "Day: " + (int)days%(365/12));
GUI.Label(new Rect(0,350, 500, 500), "Month: " + (int)months%12);
GUI.Label(new Rect(0,375, 500, 500), "Year: " + (int)years);

}

}
``````

once you change :
SECONDinSeconds = 1;

``````you need to update all this:
MINUTEinSeconds = SECONDinSeconds * 60;
HOURinSeconds = MINUTEinSeconds * 60;
DAYinSeconds = HOURinSeconds * 24;
MONTHinSeconds = DAYinSeconds * (365/12);
YEARinSeconds = MONTHinSeconds * 12;
``````

so add all that to a method, and call it whenever SECONDinSeconds changes

EDIT: actually I take that back …
I think just get rid of the extra multiplication, use this:

``````SECOND = realSECOND * timeSpeedMultiplier;   ///Game seconds
MINUTE = (SECOND/MINUTEinSeconds);
HOUR = (MINUTE/HOURinSeconds);
DAY = (HOUR/DAYinSeconds);
MONTH = (DAY/MONTHinSeconds);
YEAR = (MONTH/YEARinSeconds);
``````

no need to multiply it all again, that was the prob