Addressing the Problem
Hey guys! So recently, my friend and partner in my current Roblox project @Naperin suggested a solution to a problem that I admittedly didn’t even realised existed. In the past, I had assumed that the default Roblox day/night system was sufficient, and didn’t change gameplay drastically, but having implemented a simple loop to increment Lighting.ClockTime
, it soon became apparent that there are several issues:
- First and foremost, shadows lose their crispness during the “Night” on Roblox, (which is from 06:00-18:00 at the default latitude in studio.
- Secondly, at night, the world appears darker and therefore is much harder to navigate for players.
For a game like mine where an easily navigable open world is paramount, this poses several issues! Furthermore, a simple solution such as a tween on the ClockTime
property wouldn’t suffice either, because in my game, like many others on the platform, there is a region system, which means that there are other factors that affect the Lighting
's properties. Therefore, a Tween
wouldn’t be appropriate because it would override all other changes made!
My Solution
@Naperin suggested using a roundabout method to achieve a night with crisp shadows just like day, and so I took his advice on board, and decided to make a pseudo-night time during the Roblox day time! Simply put, my ClockTime
now loops from 06:00 (dawn) till 18:00 (dusk), and then back to 06:00 and back up till 18:00 (dusk).
To make the experience even more immersive, I swap out the skybox when day turns to night, and this gives the impression that the sun during our pseudo-night time is actually the moon! As a final touch, I use a sine wave to smoothly interpolate values in a realistic manner, that doesn’t seem abrupt and isn’t linear, so that it mimics best the smooth change between day and night in real life.
Here’s an extract of my code!
local function applyNewLighting(dayProgression)
local alpha = (math.sin(dayProgression/(DayLength*2) * math.pi * 2) + 1)/2
for key, _ in pairs(LightingSerialised.Night) do
local newValue = GetLightingNewValue(alpha, key)
if typeof(newValue) == "Vector3" then
Lighting[key] = Color3.fromRGB(newValue.x, newValue.y, newValue.z)
else
Lighting[key] = newValue
As you can see, I use Vector3
values instead of Color3
values to store my colours, because they allow for a greater variety of mathematical operations to be performed and avoid the clamping issues associated with Color3
's.
Tutorial
For the full tutorial, please see my YouTube video. It explains the maths and structure of the code, as I go through and code it with you! It will hopefully clear up any misconceptions about the process that you may have. It also contains the source code in the description alongside my Lighting
effects to further help you all create an immersive day-night system in game!
If you have any feedback, or questions, I’d be more than happy to answer them below!