Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

A train that can rotate on all 3 Axis, but it wobbles?

Asked by 3 years ago
Edited 3 years ago

With a lot of thinking and stress I have come up with a nice way of moving a train with carts in a "snake-like" fashion. I will explain a bit how the train is built and what issues I faced and how I solved them, maybe someone can recommend room for improvement this way. Once again I have no actual clue what the best way is to move a train on all 3 angles regardless of rotation. I've done a lot of research for past questions but it seems nobody has really tried this. (Don't know about the jailbreak train or WildWest but they have master scripters backing them up and I don't)

https://gyazo.com/c8bd974469f9616953a69742f19bf687

Every cart is positioned so that its "Front" attachment is at the "Back" attachment of the cart infront of it, for the first cart this is a invisible part (engine) that gets tweened by the client.

At first I attempted to get the angles (xyz) between the cart infront and the current cart. Then I would multiply the angles by 0.9, for some reason I tried different numbers but 0.9 was the best (maybe the angle of the curves was just right for this number?) Because in theory, if cart2 is rotated towards cart1 at 45 degrees and you multiply 45 by 0.9 eventually (never) it would reach cart1s rotation. Apparently this only worked for 0.9, all other numbers made the train stiff like a rod.

local rotation = Vector3.new(previous:ToObjectSpace(current):ToEulerAnglesXYZ()) * 0.9
local startPosition = previous
local desiredRotation = CFrame.Angles(rotation .X, rotation .Y, rotation .Z)
local desiredPosition = (startPosition * desiredRotation)
local desired = desiredPosition  * CFrame.new(0, 0, cart.Model.PrimaryPart.Size.Z / 2)  
cart:Teleport(desired)

So then I tried a totally different approach. Everytime the train moves, I record the average angle of the track nodes, as far back as my train is in length. This gives me the average angle of the track from the start to the end of my train. Then I divide these 3 angles by the amount of carts I have to get the angle of every cart. This for some reason worked almost perfect, the only problem is that it is not smooth. As you can see in the gif below, the train kinda wobbles but the angles of the carts to each other are perfect. http://gyazo.com/896edc6ebbbecf43e24e7f61db21259c

local totalDistance = 0
local totalAngle = Vector3.new(0, 0, 0)
local i = self.Current

while totalDistance <= self.Length do
    local nex = self:Increment(i, -1)
    local currentNode = self.Nodes[i].Node.CFrame
    local behindNode = self.Nodes[nex].Node.CFrame

    totalAngle = totalAngle + Vector3.new(currentNode:ToObjectSpace(behindNode):ToEulerAnglesXYZ())
    totalDistance = totalDistance + (currentNode.Position - behindNode.Position).magnitude
    i = nex
end
totalAngle = totalAngle / #self.Carts

for i = 1, #self.Carts do
    local cart = self.Carts[i]
    local previous = (self.Carts[i-1] and self.Carts[i-1].Model.PrimaryPart.Back.WorldCFrame) or self.Engine.CFrame
    local current = cart.Model.PrimaryPart.Front.WorldCFrame

    local desiredRotation = CFrame.Angles(totalAngle.X, totalAngle.Y, totalAngle.Z)
    local desiredPosition = (previous * desiredRotation)
    local desired = * CFrame.new(0, 0, cart.Model.PrimaryPart.Size.Z / 2)

    cart:Teleport(desired)
end

Any help on why its wobbling is really appreciated, I kinda hesitated to make a post about this because it is kind of complicated to explain. Please also post recommendations if you have made something like this before or know a way better approach to a "CFrame" train

Answer this question