[post being made for a friend who doesn’t yet have access to posting on here; it’s in first person, but it’s all his work and code.]
There is a sun dial that will rotate to the time of day, however when I join my game (assuming Im the only player) everything looks fine. But if my friend was to join minutes later, the sun dial would be at the beginning of its cycle, as opposed to where it is on my screen. Example would be, the game starts at 6am, I play for a while, it become 12pm. My friend joins, its 12pm and the sun is where it should be on the dial, but for my friend the sun (again on the dial) is at sunrise. The actual sun in the skybox is alright, its just the GUI.
You could keep the current time as a NumberValue in ServerStorage. Then at the start of the script set Spinning.Rotation to this Value, and at the end of the while loop just do game.ServerStorage.NumberValue.Value = Spinning.Rotation.
local Spinning = script.Parent
local Value = game.ServerStorage.NumberValue.Value
while true do
wait(1.7578125)
if game.Lighting:GetMinutesAfterMidnight() then
Value = Value + 1.7578125
Spinning.Rotation = Value
end
end
It’s because you’re starting the dial at 0, and just rotating it in a loop. You need to physically calculate the angle based on the time of day, otherwise, when a player respawns/joins the game, they’ll start back at 0°.
I got bored a while ago and actually wrote a Gist that calculates degrees from a given hour/minute. Have a look here:
You’d use it like so:
local Lighting = game:GetService("Lighting")
local TimeOfDay = string.split(Lighting.TimeOfDay, ":")
Image.Rotation = timeToDegrees(TimeOfDay[1], TimeOfDay[2]).hours
Lighting:GetPropertyChangedSignal("TimeOfDay"):Connect(function()
Image.Rotation = timeToDegrees(TimeOfDay[1], TimeOfDay[2]).hours
end)
Obviously you will need to adapt that code to your specific use case, as my intention was to make it easy to display an hour and minute hand on an analogue clock, but you get the idea.
There’s 1440 minutes in a day, so you need to divide the current minutes after midnight by 1440 to give you a number between 0 and 1. Multiply this 360 (number of degrees in a circle), and you’ll get the rotation you need.
I think the maths is right there… I’ve not been awake long haha
Obviously if you want to have it rotate every second, you’ll need to adjust the maths and the methods you use.
When this code is in editor, the sun dial (which is starting at 0 degrees) is which. Which makes sense. When the game starts however, the sun dial snaps to 90 degrees and wont move. It seems to not actually match up with the Time of Day within the lighting. The image is originally right side up, it was created to have the sun and moon on the horizon line, so for it to snap for the sun to be at high noon is progress yet confusing. If the ‘1440’ is changed, say to ‘1’ the Sun Dial won’t snap to 90 but instead snap a little past 0 or over 90 (depending on what time the game is set in, 6am). (The dial will snap to 7 am’s position (for context) and 1pm’s position). Though sometimes this isn’t the case.
Current code, for reference.
local SunDial = script.Parent
local Lighting = game:GetService(“Lighting”)
while true do
if game.Lighting:GetMinutesAfterMidnight() then
You have your brackets wrong. I don’t know if that’s making a difference, but you should enclose the / 1440 in the brackets too. And I’d really recommend not using a while loop for it.
local SunDial = script.Parent
local Lighting = game:GetSevice("Lighting")
-- set the rotation by dividing the current minutes after midnight by the total minutes in a day, and multiplying by 360°
local function SetRotation()
SunDial.Rotation = (Lighting:GetMinutesAfterMidnight() / 1440) * 360
end
-- update when the time of day changes
Lighting:GetPropertyChangedSignal("TimeOfDay"):Connect(SetRotation)
-- rotate to the correct position when the player spawns
SetRotation()
But this assumes that at 0° the top centre half of the image indicates midnight, and the bottom centre is midday.