Why does my train carriages phase through it to get to the back?


Why does my train carriages phase through it to get to the back?
Here’s my code.

local TrainSuperClass = {}
TrainSuperClass.__index = TrainSuperClass

local Carriages = game.ServerStorage.TrainPassengerCars
local WorkSpace = game:GetService("Workspace")
local TweenService = game:GetService("TweenService")
--local Whistle = script.Parent.WhistleSound
--local Chuffing = script.Parent.ChuffingSound

function TrainSuperClass.new(TrainModel, Nodes)
    local Train = {}
    
    setmetatable(Train, TrainSuperClass)
    
    Train.Nodes = Nodes
    Train.TestModel = TrainModel
	Train.Node = 0
	Train.LastCarriage = nil
	Train.Connections = {}
	
    
    coroutine.wrap(function()
        wait(1)
        Train:Setup()
    end)()
    
    return Train
    
end


function TrainSuperClass:Setup()
    self.Train = self.TestModel:Clone()
    
    if not(self.Nodes:FindFirstChild("Node" ..self.Node)) then
        warn("Cannot find node" ..self.Node)
        return
    end
    
    local Children = (self.Train:GetChildren())
    
    for i = 1, #Children do
        if (Children[i] ~= self.Train.PrimaryPart) then
            local Weld = Instance.new("Weld")
            Weld.Part0 = Children[i]
            Weld.Part1 = self.Train.PrimaryPart
            Weld.C0 = Children[i].CFrame:inverse()
            Weld.C1 = self.Train.PrimaryPart.CFrame:inverse()
            Weld.Parent = self.Train.PrimaryPart
        end
    end
    
    self.Train.Parent = WorkSpace.Train
    self.Train:SetPrimaryPartCFrame(self.Nodes:FindFirstChild("Node" ..self.Node).CFrame + Vector3.new(0,self.Train.PrimaryPart.Size.Y/2,0))
	
	local Killer = self.Train:FindFirstChild("Killer")
	
	if Killer then
		local KillPart = Killer.Touched:Connect(function(hit)
			if hit.Parent:FindFirstChild("Humanoid") then
				hit.Parent:FindFirstChild("Humanoid").Health = 0
			end
		end)
		
		table.insert(self.Connections, KillPart)
	end
	
	self:Move()
end

function TrainSuperClass:GetTime(Distance)
    return Distance / self.Speed
end

function TrainSuperClass:Carriages(Node)

	local Carriage = Carriages:GetChildren()[math.random(1,#Carriages:GetChildren())]:Clone()
	local All = Carriage:GetChildren()

	for A = 1, #All do
		if (All[A].Name ~= self.Train.PrimaryPart and All[A]:IsA("BasePart")) then
			local NewWeld = Instance.new("Weld")
			NewWeld.Name = "Weld"
			NewWeld.Part0, NewWeld.Part1 = All[A], Carriage.PrimaryPart
			NewWeld.C0 = All[A].CFrame:inverse()
			NewWeld.C1 = Carriage.PrimaryPart.CFrame:inverse()
			NewWeld.Parent = Carriage.PrimaryPart
		end
	end

	if not self.LastCarriage then
		self.LastCarriage = self.Train
	end

	Carriage:SetPrimaryPartCFrame(self.LastCarriage:GetPrimaryPartCFrame() * CFrame.new(-Carriage.PrimaryPart.Size.X, 0, 0))

	self.LastCarriage = Carriage
	Carriage.Parent = WorkSpace.Train

	spawn(function()
		self:MoveCarriage(Node, Carriage)
	end)
end

function TrainSuperClass:MoveCarriage(NodeNum, Carriage)
	local Node = self.Nodes:FindFirstChild("Node"..NodeNum)

	if not (Node) then
		Carriage:Destroy()
		return
	end

	local Distance = (Carriage.PrimaryPart.Position - Node.Position).Magnitude

	local Time = self:GetTime(Distance)

	local TweenInfo = TweenInfo.new(
		Time,
		Enum.EasingStyle.Linear,
		Enum.EasingDirection.In,
		0,
		false,
		0
	)

	TweenService:Create(Carriage.PrimaryPart, TweenInfo, {CFrame = Node.CFrame + Vector3.new(0,Carriage.PrimaryPart.Size.Y/2,0)}):Play()

	wait(Time)

	self:MoveCarriage(NodeNum + 1, Carriage)
end

function TrainSuperClass:Move()
	self.Node = self.Node + 1

	local Node = self.Nodes:FindFirstChild("Node"..self.Node)

	if not (Node) then
		self:Stop()
		return
	end

	if self.Node == 1 then
		
		local All = self.Train:GetChildren()

		for A = 1, #All do
			if (All[A].Name ~= self.Train.PrimaryPart and All[A]:IsA("BasePart")) then
				local NewWeld = Instance.new("Weld")
				NewWeld.Name = "Weld"
				NewWeld.Part0, NewWeld.Part1 = All[A], self.Train.PrimaryPart
				NewWeld.C0 = All[A].CFrame:inverse()
				NewWeld.C1 = self.Train.PrimaryPart.CFrame:inverse()
				NewWeld.Parent = self.Train.PrimaryPart
			end
		end
		
		wait(7)
		self.Train:SetPrimaryPartCFrame(Node.CFrame + Vector3.new(0, self.Train.PrimaryPart.Size.Y/2, 0))

		for i = self.CarriagesCount,1,-1 do
			self:Carriages(self.Node)
		end
		
		--Whistle:Play()
		self:Move()
		--Chuffing:Play()
		--Chuffing.Looped = true
		
		return
	end

	local Distance = (self.Train.PrimaryPart.CFrame.p - Node.CFrame.p).Magnitude

	local Time = self:GetTime(Distance)

	local TweenInfo = TweenInfo.new(
		Time,
		Enum.EasingStyle.Linear,
		Enum.EasingDirection.In,
		0,
		false,
		0
	)


	TweenService:Create(self.Train.PrimaryPart, TweenInfo, {CFrame = Node.CFrame + Vector3.new(0,self.Train.PrimaryPart.Size.Y/2,0)}):Play()

	wait(Time)

	self:Move()
end

function TrainSuperClass:Stop()
	wait(5)
	
	for _, v in next, self.Connections do
		v:Disconnect()
	end
	
	self.LastCarriage = nil
	self.Train:Destroy()
	self.Train.Parent = nil
	self.Node = 0
	self:Setup()
end

return TrainSuperClass

Thanks!