Player teleports when trying to move with a train

I made a train system that uses CFrame to move the train. By default the player’s character doesn’t move with the train, so I have to make a script that cframes the player’s character with the train. But I have a problem, where when the player steps on a new train part, the player teleports. Is there anything I can do to fix this?

Here is the code that i’m using:

local Players = game:GetService("Players")
local player = game.Players.LocalPlayer
local RunService = game:GetService('RunService')

local LastTrainCFrame

local Function
local Function2


Function = RunService.Heartbeat:Connect(function()
	local RootPart = player.Character.HumanoidRootPart
	local Ignore = player.Character
	local ray = Ray.new(RootPart.CFrame.p, Vector3.new(0,-500,0))
	local Hit, Position, Normal, Material = workspace:FindPartOnRay(ray,Ignore)
	if Hit and Hit:IsDescendantOf(workspace.Trains) then
		local Train = Hit
		if not LastTrainCFrame then
			LastTrainCFrame = Train.CFrame
		end
		local TrainCF = Train.CFrame 
		local Rel = TrainCF * LastTrainCFrame:inverse()
		LastTrainCFrame = Train.CFrame
		RootPart.CFrame = Rel * RootPart.CFrame
	else
		LastTrainCFrame = nil
	end
	
	if not Function2 then
		Function2 = player.Character.Humanoid.Died:Connect(function()
			Function:Disconnect()
			Function2:Disconnect()
		end)
	end
end)

This must be a localscript inside starter-character-scripts. What can I do to stop the player from teleporting all over the place?

So I found a fix for this, what you need to do is use the following code instead:


local Players = game:GetService("Players")
local player = game.Players.LocalPlayer
local RunService = game:GetService('RunService')

local LastHit
local LastTrainCFrame

local Function
local Function2


Function = RunService.Heartbeat:Connect(function()
	local RootPart = player.Character.HumanoidRootPart
	local Ignore = player.Character
	local ray = Ray.new(RootPart.CFrame.p, Vector3.new(0,-500,0))
	local Hit, Position, Normal, Material = workspace:FindPartOnRay(ray,Ignore)
	if Hit and Hit:IsDescendantOf(workspace.Trains) then
		local Train = Hit
		if not LastTrainCFrame then
			LastTrainCFrame = Train.CFrame
		end
		if Train ~= LastHit then
			LastTrainCFrame = Train.CFrame
		end
		local TrainCF = Train.CFrame 
		local Rel = TrainCF * LastTrainCFrame:inverse()
		LastTrainCFrame = Train.CFrame
		RootPart.CFrame = Rel * RootPart.CFrame
		LastHit = Train
	else
		LastTrainCFrame = nil
	end
	
	if not Function2 then
		Function2 = player.Character.Humanoid.Died:Connect(function()
			Function:Disconnect()
			Function2:Disconnect()
		end)
	end
end)

However, I still have one issue with it, but I will make a new topic on that issue rather than continuing this topic.