I’ve managed to figure out how to get a block to follow the nodes, but I’m more concerned on how it is going to follow the next node’s orientation given ONLY the CFrame position.
I would want the orientation to change smoothly along the position movement. This is what I’ve been experiencing for better clarity. I’m using RunService for this method, it does not use TweenService, instead it places the block into a new CFrame value. As of right now, it only changes the position, but I need help on trying to get the orientation set.
The video lags, not the movement. I’d like to also keep in mind that speed can change constantly to the point where it can stop anywhere on the nodes if set to 0.
That seems to snap, where I want the orientation essentially ‘tween’ on the same speed as the position movement. But this is going in the right direction!
That solution will not work because the method to place the block goes into small increments based on subtracting two Vector3 values, which is the train and the node it’s heading towards.
I personally feel like if you are using the solution that @det3rr proposed, there’s no simpler way than tweening the CFrame.LookAt, I suspect Basepart/Model:PivotTo() would also snap if that’s the case with CFrame.LookAt snapping.
Since you are working with subtracting two Vector3 values, have you tried Cframe:VectorToObjectSpace?
I’m subtracting position Vector3 values, sorry. What I replicated was basically ‘lerping’ the positions at a consistent speed using position subtraction.
The easiest solution, I think, would be thinking more into the future, when the train car has an actual length
You could get the exact position of the back of the car and the front of the car and orient it between those two points, this would fix the snapping position (but would leave a snapping velocity but it shouldnt look noticeable)
To fix the snapping orientation its an easy fix just use linear interpolation! Assumming you’re already moving the train and have the node and next node as variables. This will lerp it to the next node’s look vector depending on how far along it is on the current node. Node or track node just makes more sense to me for some reason.
local function GetDirectionalCFrame(Train, Node, NextNode):CFrame
local Start = (Node.CFrame * CFrame.new(0, 0, -Node.Size.Z/2)).Position;
local End = (Node.CFrame * CFrame.new(0, 0, Node.Size.Z/2)).Position;
local Alpha = (Train.Position - End).Magnitude/(Start-End).Magnitude;
local DirectionalCFrame = CFrame.fromMatrix(Train.Position, Node.CFrame.LookVector:Lerp(NextNode.CFrame.LookVector, Alpha), Vector3.new(0, 1, 0));
return DirectionalCFrame;
end