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