Accurate Day Night Cycle
Before we can add rest of the logic in SunSky we need 2 structures, these are DayNightCycle_Rules and UTCTimeDifference. Our system will be using UTC Time to calculate Game Time, we don’t want to use clients local time because then it wouldn’t be the same for every player and this would result in different sun positions for players. And yes, this supports multiplayer out of box but it will also works without server.
RealWorldTimeInGameTime is the game world time duration (24 hour cycle).
Rest of the variables.
- GameTimeNow Date Time
- Sunrise Time span
- Sunset Time span
- IsNight_B boolean
- DebugOn (optional)
Also add two event dispatchers IsNight and IsDay.
This one is UTCTimeDifference structure:
This is DN_Rules variable (Replicated):
Go back to DN_PlayerController and finish SendDifferenceToSunSky.
Now in SunSky add BeginPlay event and set DN_Rules. RealWorldStaticStartTime should be set only on server but in this case it doesn’t matter that much because we have time sync.
Drag and drop Event Dispatchers and then select Assign, this is the easiest way to bind event dispatchers.
Create SunIsDown event, this will help us identify when it’s night and day.
Go to UpdateSun function and set Sunrise and Sunset variables.
So what we want to do is make Game World Time do 100% in x Real World Time.
GameTimeNow variable is where Game World Time currently is. This is where we put the result.
100% of Game World Time is 24 hours.
Let’s define 5 minutes of Real World Time to Game World Time.
We have Real World Start Time and Game World Start Time. And then we have Real World Time Now.
- GameTimeNow (result)
- RealWorldStart (06/10/2020 21.31.44)
- GameWorldStart (06/10/2009 15.23.11)
- RealWorldTimeNow (clock)
- RealWorldTimeinGameTime 300 seconds
So in 5 minutes 24 hours happens in game.
We’ll take 50% off from that we’ll get 2.5 minutes and 12 hours or 43200 seconds. We can use this to check if our formula is correct.
How much game time has passed in one second? 86400/300 = 288 seconds or 4 minutes 48 seconds.
So 2.5 minutes have passed how much game time has passed? 43200 = 288 x (60 x 2,5) AND THERE WE GO!
GameTimeNow = (86400 / RealWorldTimeinGameTime) * (RealWorldTimeNow - RealWorldStart)
Then we put it all into UpdateRealTime event.
Then add the function to event tick.
Debug printing function.
Things can get confusing if you try to print GameTimeNow because there is UTC version of AsTime and some people people (including myself many times) used that and then reported me that something was wrong with the sunset and sunrise.
And test it! The Sun should do a full circle in 1 minute with these settings (if you have 1 minute in RealWorldTimeInGameTime).