Client sided night not working

I’m having trouble with getting this script to work. I have two issues:

  1. The bindableEvent is not getting received
  2. I don’t 100% know how to do what I want to fully do

So first: when the user reaches a certain height, it fires a bindableEvent (localscript)

-- other code
		elseif char:GetPivot().Y >= 2500 then
			event:Fire()
-- other code

this code does work (i used it for other purposes)
Next, another localscript picks it up and prints something (to test)

event.Event:Connect(function()
	print("hi")
end)

However, it never prints hi. Furthermore, I don’t know how to get it to smoothly transition the time from 14:30:00 to 00:00:00.

Please help!

1 Like

still doesnt work, I have tried a lot, but I have a feeling the localscript works in the workspace.

1 Like

The LocalScript can’t run within the workspace context, see more information here. However, if you use a Script with a RunContext value of Client then it will execute within the workspace - read more about that here

It’s a little difficult to help more than this without you knowing what you’re looking for exactly. If your biggest concern is that the event isn’t fired:

  • How often are you checking to see whether the player height exceeds 2500?
  • Are you certain that the event:Fire() line is ever reached?
  • Are the LocalScript instances both in an appropriate container?
  • To confirm: you’re expecting the BindableEvent to fire between clients, and not across the client-server boundary, right?
1 Like

i added a print statement after firing, it gets printed

what i want to happen is that once the user reaches a certian height, the skybox (on the client) transitions to night time, but smoothly.

Yes

its in a while true loop (it is used for other stuff and i can guarantee it does detect the height correctly

I will try that when i can.

1 Like

If your LocalScript is in workspace without relying on a Script’s RunContext then this is most likely why you’re not receiving the event. You could test this quickly by just seeing if anything is able to be printed from your LocalScript - you’ll note that it doesn’t execute unless in an appropriate container. For now, probs is easiest for you to check that; but if not, let us know.

I’m assuming this happens once the event signal is fired? Something like the following example will likely suit your needs. I recommend you read the reference article(s) I linked in the code comment though so you can better understand what’s happening.

Specifically, you should take a look at:

Example Code
-- services
local Lighting = game:GetService('Lighting')
local RunService = game:GetService('RunService')

-- constant(s)
local CLOSE_EPSILON = 1e-3

-- utilities

--[=[
  implements a critically damped harmonic oscillator
  which gradually changes a number towards a desired
  target number over time

  see reference(s) at...
    - Interpolation explained: https://www.gamedev.net/tutorials/programming/general-and-gameplay-programming/linear-interpolation-explained-r5892/
    - SmoothDamp reference: https://www.alexisbacot.com/blog/the-art-of-damping

  @param a   number -- the current value
  @param b   number -- the target value
  @param dt  number -- elapsed time since this method was last called (or frameTime)
  @param v   number -- the current velocity
  @param st  number -- approx. time it takes to reach the target
  @param spd number -- max speed to clamp the maximum change in value

  @return tuple<number, number> -- describes the new value and the new velocity
]=]
local function smoothDamp(a, b, dt, v, st, spd)
  v = v or 0
  st = math.max(st or 0, 1e-4)
  spd = spd or math.huge

  local o = 2 / st
  local x = o*dt
  local e = 1 / (1 + x + 0.48*math.pow(x, 2) + 0.235*math.pow(x, 3))

  local dx = a - b
  local mx = spd*st
  mx = math.clamp(dx, -mx, mx)

  local vx = a - mx
  local v0 = (v + o*mx)*dt
  local v1 = (v - o*v0)*e

  vx = vx + e*(mx + v0)
  if (b - a > 0) == (vx > b) then
    vx = b
    v1 = (vx - b) / dt
  end

  return vx, v1
end

-- config
local dayTimeTarget = 13        -- i.e. 13:00 clocktime
local nightTimeTarget = 20      -- i.e. 20:00 clocktime

local updateFrequency = 1 / 60  -- i.e. 60fps - the frequency at which we'll check for a target / update the Lighting.ClockTime property

local maxSpeed = math.huge      -- i.e. max smoothDamp speed parameter, use this to set a max speed
local smoothTime = 0.6          -- i.e. approx. time it takes for the clock time to reach its target, lower = faster | higher = slower

local event = Instance.new('BindableEvent') -- some bindable event that we're going to listen to
event.Name = 'HeightWatchdog'
event.Parent = workspace

-- main
local desiredTarget
event.Event:Connect(function (isAboveHeight)
  -- expects a boolean describing whether the local client is above / below a specific height
  --   when above the height, it will set the current target to `nightTimeTarget`; otherwise will target `dayTimeTarget`
  if isAboveHeight then
    desiredTarget = nightTimeTarget
    return
  end

  desiredTarget = dayTimeTarget
end)

local lastUpdate = 0
local currentTarget, currentVelocity
RunService.Stepped:Connect(function (gt, dt)
  lastUpdate += dt

  -- check to see if we're ready to update
  -- why are we doing this? see reference @ https://gafferongames.com/post/fix_your_timestep/
  if lastUpdate < updateFrequency then
    return
  end

  local delta = lastUpdate
  lastUpdate = math.fmod(lastUpdate, updateFrequency)
  delta -= lastUpdate

  -- check to see if our desiredTarget has
  -- been changed since our last frame
  if desiredTarget then
    currentTarget = desiredTarget
    desiredTarget = nil
  end

  -- ignore if we don't have a target
  if not currentTarget then
    return
  end

  -- smoothly interpolate the current clocktime to the target clocktime
  local position, velocity = smoothDamp(Lighting.ClockTime, currentTarget, delta, currentVelocity, smoothTime, maxSpeed)
  currentVelocity = velocity

  -- if our current clocktime is approximately the currentTarget
  -- then let's dispose of our target so we don't continue to
  -- erroneously attempt to update our Lighting.ClockTime property
  local distance = math.abs(position - currentTarget)
  if distance < CLOSE_EPSILON then
    currentTarget = nil
  end

  Lighting.ClockTime = position
end)

1 Like