Review my train script

Hi there !

Recently I made a train using script and not physics and I want you to review it ! Is it any good or suggestions and such!

Thanks for everyone for helping me !

The script in stepps :

A There is a while loop (this keeps the train moving) and inside of it I loop trough all the train cars and cast a ray from them to the rails if the ray result is a rail (currently checking by name but it might change in the future) then I make the selected cars primary parts CFrame to the center of the rail plus Vector3.New(0,1,0) (the “1” is the hight of the train) with a simple tween.
The runservice function is to move the players character with the moving train.

local trainModel = script.Parent
local tweenService = game:GetService("TweenService")
local runService = game:GetService("RunService")


local speed = .01
local multiplier = speed*10
local turnspeed = speed/.2
local locomotive = script.Parent.locomotive

function GetTime(Distance, Speed)
	-- Time = Distance / Speed
	local Time = Distance / Speed
	return Time
end

while wait(speed) do
	for _,trainPart in ipairs(trainModel:GetChildren()) do
		if trainPart:IsA("Model") then
			
			
			local rayOrigin = trainPart.PrimaryPart.Position + trainPart.PrimaryPart.CFrame.LookVector*2
			local rayDirection = Vector3.new(0,-2,0)
			local rayResults = workspace:Raycast(rayOrigin,rayDirection)
			if rayResults and rayResults.Instance.Name == "rail" then
				local rail = rayResults.Instance
				
				--lerp solution (use only if tween wouldn't work)!
				--trainPart.PrimaryPart.CFrame = trainPart.PrimaryPart.CFrame:Lerp(CFrame.new(rail.Position +Vector3.new(0,1,0)+ trainPart.PrimaryPart.CFrame.LookVector) *  CFrame.Angles(trainPart.PrimaryPart.Orientation.x, math.rad(rail.Orientation.Y), trainPart.PrimaryPart.Orientation.z), .2)
				
				local goals = {
					CFrame = CFrame.new(rail.Position +Vector3.new(0,1,0)+ trainPart.PrimaryPart.CFrame.LookVector) *  CFrame.Angles(trainPart.PrimaryPart.Orientation.x, math.rad(rail.Orientation.Y), trainPart.PrimaryPart.Orientation.z)
				}
				local Traintween = tweenService:Create(trainPart.PrimaryPart, TweenInfo.new(GetTime((trainPart.PrimaryPart.Position - rail.Position).Magnitude, 10), Enum.EasingStyle.Linear, Enum.EasingDirection.In, 0, false), goals)
				Traintween:Play()				
				
				local lastPos = trainPart.PrimaryPart.Position
				runService.Stepped:Connect(function(_,deltaTime)
					local currentPos = trainPart.PrimaryPart.Position
					local deltaPos = currentPos - lastPos
					local velocity = deltaPos / deltaTime
					
					trainPart.PrimaryPart.AssemblyLinearVelocity = velocity
					
					lastPos = currentPos
					
				end)
				
			else 
				warn("something broke the loop")
			end
		end
	end
end

Hey there! It sounds like you made a script to move a train in your game, and I’m happy to help you out. Here are a few things I noticed about your code:

  1. You’re using a while loop to keep the train moving, which is great. Just make sure the code doesn’t slow down your game by adding a “wait()” statement inside the loop.
  2. You’re using raycasting to detect when the train is over a rail, which is a good way to keep it on track. But watch out - you’re checking the rail by name, which could cause problems if the name changes. Maybe try checking the rail’s type instead?
  3. You added a cool tweening feature to move the train cars along the rails. It might look smoother if you add some easing to it, though.
  4. It looks like you’re using the RunService to move the player’s character with the train. Maybe you should add a check to make sure the player is close enough to the train first?

Overall, it looks like you’re off to a good start with this script. Keep up the good work!

Thank you for your reply I will try my best to implement these!

2 Likes