I would like to achieve a node based train kit which updates its speed to match the value,
The issue I have currently is that when value updates, the speed stays the same and does not change throughout the course of the nodes
I have tried researching on the forum and other websites for quite some time but have not found the solution yet.
Current Script :
local rs = game:GetService("RunService")
local train = script.Parent
local curSpeed = train:WaitForChild("CurrentSpeed") -- Wait for the CurrentSpeed property to exist and retrieve it
local nodes = train.Parent.Parent.Nodes
local nodeReady = nodes.Parent.NodeReady
local loco = train.Locomotive
local front = loco.Front
local back = loco.Back
local base = loco.Base
local gap = (front.Position - back.Position).Magnitude
local loco_model = loco.Model
local remote = script.Parent.Parent.Parent.Parent.Parent.ServerScriptService.RemoteEvent
local startingNode = train.StartingNode
print("Started")
repeat wait() until nodeReady.Value
function SetStartingNode()
front.Current.Value = nodes:FindFirstChild("Node_" .. startingNode.Value)
back.Current.Value = nodes:FindFirstChild("Node_" .. startingNode.Value)
end
function NextNode(target)
local curNode = target.Current
local nextNode = curNode.Value.NextNode.Value
curNode.Value = nextNode
end
function Move(target, deltaTime)
local curNode = target.Current.Value
local nextNode = target.Current.Value.NextNode.Value
if not nextNode then
curSpeed.Value = 0
return
end
local distanceTraveledOnSection = (curNode.Position - target.Position).Magnitude
local sectionLength = (curNode.Position - nextNode.Position).Magnitude
local newAlpha = ((distanceTraveledOnSection + curSpeed.Value * deltaTime)) / sectionLength
target.CFrame = curNode.CFrame:Lerp(nextNode.CFrame, newAlpha)
if newAlpha >= 1 then
NextNode(target)
end
end
function UpdateSpeed()
while true do
wait(1)
curSpeed = train:WaitForChild("CurrentSpeed") -- Update the curSpeed value
end
end
rs.Heartbeat:Connect(function(deltaTime)
Move(front, deltaTime)
Move(back, deltaTime)
base.CFrame = CFrame.new(back.Position, front.Position) * CFrame.new(0, front.Size.Y/2 + base.Size.Y/2, -gap/2)
loco_model:SetPrimaryPartCFrame(base.CFrame * CFrame.new(0, base.Size.Y/2 + loco_model.PrimaryPart.Size.Y/2, 0))
end)
SetStartingNode()
Please keep me updated as I am very confused about it.
One thing to check is whether the Move function uses the correct value of curSpeed. You might want to update the Move function to include the new curSpeed value each time it’s called, like this:
function Move(target, deltaTime)
local curNode = target.Current.Value
local nextNode = target.Current.Value.NextNode.Value
if not nextNode then
curSpeed.Value = 0
return
end
local distanceTraveledOnSection = (curNode.Position - target.Position).Magnitude
local sectionLength = (curNode.Position - nextNode.Position).Magnitude
local newAlpha = ((distanceTraveledOnSection + curSpeed.Value * deltaTime)) / sectionLength
target.CFrame = curNode.CFrame:Lerp(nextNode.CFrame, newAlpha)
if newAlpha >= 1 then
NextNode(target)
end
end
Double -check the code that sets the curSpeed variable to make sure it’s being called correctly and that there are no typos or errors.
That does work to some extent, I can only manage to make the train change speed by changing the value on the server side, any idea how a key bind would be able to change that value server side using a script?
Certainly! You could use a RemoteFunction to allow the client to send information to the server and change the speed value. So, it’ll be like:
– on the server side:local train = – set this to the train object you want to controllocal remoteFunction = Instance.new(“RemoteFunction”)remoteFunction.Name = “ChangeTrainSpeed”remoteFunction.OnServerInvoke = function(player, speed)train.curSpeed.Value = speedendremoteFunction.Parent = game.ReplicatedStorage
– on the client side:local remoteFunction = game.ReplicatedStorage:WaitForChild(“ChangeTrainSpeed”)local function onKeyDown(inputObject, gameProcessedEvent)if gameProcessedEvent then return endif inputObject.KeyCode == Enum.KeyCode.Space thenremoteFunction:InvokeServer(20) – change the number argument to the speed you wantendendgame:GetService(“UserInputService”).InputBegan:Connect(onKeyDown)
This sets up a RemoteFunction on the server that can be invoked by the client to change the train’s speed value. On the client side, you listen for a key press event and send the speed value through the remote function when the key is pressed.
It would probably be better to use a RemoteEvent rather than a RemoteFunction if feedback is not necessary. In this case, it is not necessary since you are just telling the server to change the speed of the train.
Thank you, it resolved the base of the problem. It certainly isn’t fully optimised in terms of performance for some reason but I’ll find a way to fix that.