I’m having trouble with getting this script to work. I have two issues:
- The bindableEvent is not getting received
- 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