Distance between train cars sometimes differs

I am trying to create an effective train movement system without relying on physics, as it can break sometimes. The script basically takes the time in between frames, multiplies it by the speed, adds it to the distance traveled between 2 nodes, divides that by the section length, and lerps the bogey to the new alpha.

  1. What do you want to achieve? Keep it simple and clear!

I would like the distance between the train cars to be the same, 5 studs.

  1. What is the issue? Include screenshots / videos if possible!

The issue is that sometimes it does not stay constant/nearly constant.
Video: https://streamable.com/2gnnex
(skip to 0:50 to see it working as intended)

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?

I’ve tried making the starting speed 0, then setting it to something. I have tried looking for solutions, but to no avail.

Code:

local cont = true
game:GetService("RunService").Heartbeat:Connect(function(dt)
	print("Time in between frame: "..dt)
	print("Current Speed: "..script.Parent.CurrentSpeed.Value)
	for i = 1, script.Parent.Cars.Value do
		local v = script.Parent:FindFirstChild("Car"..tostring(i))
		print(v.Name.." Continuation: "..tostring(cont))
		if cont == true then 
			if v:IsA("Model") then
				print(v.Name.." Speed: "..script.Parent.CurrentSpeed.Value)
				local train = v
				local nodes = train.Parent.Parent.Parent.Nodes
				local loco = train.Locomotive
				local front = loco.Front
				local back = loco.Back
				local base = train.Base
				local gap = (front.Position-back.Position).Magnitude

				local function NextNode(target)
					target.Current.Value = target.Current.Value.NextNode.Value
				end

				local function Move(target, dt)
					local curNode = target.Current.Value
					local nextNode = target.Current.Value.NextNode.Value
					if nextNode then
						local distanceTraveledOnSection = (target.Position-curNode.Position).Magnitude
						local sectionLength = (nextNode.Position-curNode.Position).Magnitude
						local alpha = (distanceTraveledOnSection+script.Parent.CurrentSpeed.Value*dt)/sectionLength
						target.CFrame = curNode.CFrame:Lerp(nextNode.CFrame, alpha)
						if alpha >= 1 then
							NextNode(target)
						end
					else
						script.Parent.CurrentSpeed.Value = 0
						cont = false
						print("STOP!")
						return
					end
				end
				Move(front, dt)
				Move(back, dt)
				base.CFrame = CFrame.new(back.Position, front.Position)*CFrame.new(0,7.5,-gap/2)
			end
		end
	end
end) 

Help would really be appreciated!

Here is the place file for anyone who wants it:
TrainMovementSystem.rbxl (79.4 KB)

One other thing: Whenever I press stop, the distance between car 1 and 2 becomes 5 every time.

Is there any reason you can’t simply move the train model itself using :PivotTo(CFrame)? This should move the entire model as a unit, instead of relying on a program that moves each car individually. Theoretically, this should eliminate the inconsistency in distance between the cars.

Moving the entire train as one would make the cars go off the track completely. At curves, the train is not straight.

I solved it — just set the bogies position and start the script.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.