Hello me and @sasial are working on a train script. When we were trying to rotate the train, it was “drifting” and not facing the right way. So my question is, how do we make the train face the right way?
Here is our script:
wait(7)
local trainoff = Vector3.new(1,9,0)
local offpos = trainoff + Vector3.new(0,0,script.OffZ.Value)
for i,v in pairs(script.Parent.Cars:GetChildren()) do
local PrimaryPart = script.Parent.Cars["Car"..i]
PrimaryPart:SetPrimaryPartCFrame(CFrame.new(workspace.Tracks.Start.PrimaryPart.Position + offpos))
offpos = offpos + Vector3.new(0,0,script.Parent.Cars["Car"..i].Box.Size.Z)
end
--- Train Script Below
local RunService = game:GetService("RunService")
local Grinding = true
local function GetDist(p)
return (p.Node1.WorldPosition - p.Node0.WorldPosition).Magnitude
end
local function GetNewPosition(p, a)
return (p.Node1.WorldPosition - p.Node0.WorldPosition) * a + p.Node0.WorldPosition
end
local function GetNewNode(currentNode, dir)
return currentNode.Part.NextNode.Value
end
local function GrindRail(Train, RailParts, CurrentPart)
--AlignPosition.Attachment1.Position = AlignPosition.Attachment0.WorldPosition
local CurrentNode = RailParts[CurrentPart]
--alpha between Node0 and Node1
local a = 0--dist2.Unit:Dot(dist1)/dist2.Magnitude
--All variables should be found by now!
--AlignPosition.Enabled = true
local connection
local CurrentRatio = GetDist(CurrentNode.Part)
connection = RunService.Heartbeat:Connect(function(dt)
a = a + dt*script.Speed.Value/CurrentRatio
print(a)
if a > 1 then
repeat
local newPart = GetNewNode(CurrentNode, 1)
if newPart then
CurrentNode = RailParts[newPart]
local NewRatio = GetDist(newPart)
a = a - 1
a = a * NewRatio/CurrentRatio
CurrentRatio = NewRatio
else
connection:Disconnect()
break
end
until a <= 1
elseif a < 0 then
repeat
local newPart = GetNewNode(CurrentNode, -1)
if newPart then
CurrentNode = RailParts[newPart]
local NewRatio = GetDist(newPart)
a = a + 1
a = a * NewRatio/CurrentRatio
CurrentRatio = NewRatio
else
connection:Disconnect()
break
end
until a >= 0
end
if CurrentNode and Grinding then
local dir = (CurrentNode.Part.Node1.WorldPosition - CurrentNode.Part.Node0.WorldPosition).Unit
--[[Train.PrimaryPart.CFrame = Train.PrimaryPart.CFrame:Lerp(CFrame.new(
GetNewPosition(CurrentNode.Part,a) + Vector3.new(0,10,0),
GetNewPosition(CurrentNode.Part,a) + Vector3.new(0,10,0) + dir
), 0.1)--]]
for i,v in pairs(script.Parent.Cars:GetChildren()) do
print(i)
local car = script.Parent.Cars["Car"..i]
-- print(getdistancetonode(currentpart,dir,i))
-- print(i)
--print(ii.." "..i)
local offpos = trainoff + Vector3.new(0,0,script.OffZ.Value)
local hyp= CurrentNode.Part.Size.X/2
--[[car:SetPrimaryPartCFrame(CFrame.new(car.PrimaryPart.Position--[[,CurrentNode.Part.NextNode.Value.Position+trainoff--):Lerp(CFrame.new(
GetNewPosition(CurrentNode.Part,a) + trainoff + Vector3.new(hyp * math.sin(math.rad(CurrentNode.Part.Orientation.Y)),0,hyp * math.cos(math.rad(CurrentNode.Part.Orientation.Y))).unit,
CurrentNode.Part.NextNode.Value.Position + trainoff + Vector3.new(hyp * math.sin(math.rad(CurrentNode.Part.Orientation.Y)),0,hyp * math.cos(math.rad(CurrentNode.Part.Orientation.Y))).unit--)
, 0.1))--]]
car.PrimaryPart.CFrame = CurrentNode.Part.CFrame:ToWorldSpace(trainoff)
--car.PrimaryPart.Orientation = CurrentNode.Part.Orientation
end
wait(1/script.Speed.Value)
--AlignPosition.Attachment1.Position = GetNewPosition(CurrentNode.Part,a) + Vector3.new(0,3,0)
else
--AlignPosition.Enabled = false
wait(2)
Grinding = false
end
end)
end
wait(1)
print("waiting for setup...")
wait(2.3)
print("ready!")
local train = script.Parent
local RailParts = {}
local RailModel = workspace.Tracks
for _, part in ipairs(RailModel:GetChildren()) do
RailParts[part.PrimaryPart] = {
Part = part.PrimaryPart
}
end
GrindRail(train, RailParts, workspace.Tracks.Start.PrimaryPart)
Your help is much appreciated.
