Let’s create a beautiful day and night cycle for a multiplayer game in Unreal 4. Our night will be a pitch black and day will have a spectacular sky and lighting. In bonus part we’ll create a moon and lighting and to go even further on i’ll show you how to do it in C++. This system will have a full dynamic lighting so no baking and sitting and waiting for hours, you’ll have a new feature in your game before you go to bed.
Blueprint Only Project Files
First we need to enable Sun Position Plugin.
Goto Settings -> Plugins and enable Sun Position Calculator.
Add Sun and Sky to your level.
Select View Options in Content Browser and turn on Show Plugin Content.
Right click SunSky in World Outliner and Browse to Asset.
Dublicate SunSky and replace SunSky from level with dublicate.
Open Level Blueprint. I’m using Third Person Example.
Create two variables in level blueprint.
- GameTimeUpdateDelay is 1,0
- ServerGameTime is Replicated
Add Switch Has Authority to BeginPlay. Set ServerGameTime variable in Authority.
Create Timer and Event. Use Date Time + Timespan to add time into Date Time.
Drag SunSky from outliner into level blueprint. Now we don’t yet have FromDateTime function from SunSky so create everything you can and come back.
Make your level look like this, so remove Directional Light, Skylight, Atmospheric Fog…
Then Build Lighting. Level is going to be pitch black but that’s what we wan’t for now.
Then Edit SunSky (the one you dublicated and added to level).
Now in SunSky add function named FromDateTime.
FromDateTime will have one input variable:
Then break it like this into year, month, day and solar time of SunSky variables.
Unfortunately there is a small bug here. Because Solar Time is 0/100 and date time is 0/60 it’s going to skip like 40, this will create Sun skipping/jumping effect at the change of every hour and that is just going to look terrible. So i came up with this, super smooth, zero skipping time conversion function:
There’s a small gap between 99.2 (when 59.59) / 100 (60) so what that booster does it goes through values 99.3, 99.4, 99.5, 99.6, 99.7, 99.8 and 99.9, before 59.59 is met.
Go back to level blueprint and add FromDateTime function where it belongs.
Also set enable Replicates so we don’t forget it.
You may wan’t to set DirectionalLight Intensity to 10 lux
or Enable Extend default luminance range in Auto Exposure settings.
Now you can test it. Set Net Mode “Play As Client”-
Now this has a small bug, Game Time is not accurate. The Game Time should change exactly 10 minutes every 1 seconds but sometimes it’s 10 more or less. This is not what we wan’t.
The time should be updated every frame, or at least the time on server. We need a static starting point where we can calculate the time. Then we send this value to clients and they can calculate it from there without server constantly spamming it to clients. This static start point is going to be real world UTC time. Then we should have rules which are replicated so if admin wan’ts to change time in real time it can happen, or make time go faster or slower.
Sometimes UTC time can be off by one or two seconds between server and client so first we have to sync UTC time on clients with the server.
For time sync we need Player Controller Class so create a new one:
Put it in Gamemode folder.
Open it and enable Replicates.
In DN_PlayerController we create one variable, event dispatcher and function.
TimeDifferenceToServer is Timespan:
Then we have two events GetServerTime (Run On Server, Reliable) and ReceiveServerTime (Run on owning client, Reliable):
Then create event SendDifferenceToSunSky:
We’ll come back to this once we finish coding.
Then we have BeginPlay and event dispatcher:
Now create new Game Mode. Add New -> Blueprint Class -> Game Mode Base.
Put it in Gamemode folder.
Then open it and Select Class Defaults and Set Player Controller Class to DN_PlayerController.
And go to Project Settings.
In Project -> Maps & Modes -> Set Default GameMode to DN_GameMode.