How do I tween a part (turning)

PROBLEM: How would I go about tweening a part (More specifically, A Train)
In all my past train games, I used tweening as it seems to be faster and there is a 100% chance it would not derail. However, it has become rather “Boring”, seeing buildings pass while you sit in a lifeless train just moving straight.

In my 4th train game, I would like to tween a part so as it turns and moves like:

How a train would turn at a turn. how a car would turn on the road. You get it.

The part should be following the direction it is looking at all times while turning.

How would i go about my way coding this :slight_smile:

Maybe you don’t want to use tweening? It might be easier to do something like this:

You could try adding “checkpoints” like some parts in a row, when the train would touch a part (like a part that is named “turn”), it would get the name of the part and if it was called “turn” it would start turning to the next area. EX. Train hits part called “Turn right”, and velocity direction changes

Here’s some example code:

local trainPart = --Insert train main part to detect part touching

-- Train Velocity
local train = {
	Speed = 0
	Direction = 0
}

-- When the train touches parts with "SpeedUp/SlowDown" names
trainPart.Touched:Connect(Function(hitPart)
	if hitPart.Name == "SpeedUp" then
		train.Speed += 1
	if hitPart.Name == "SlowDown" then
		train.Speed -= 1
	elseif hitPart.Name == "TurnRight1" then
		for i = 1,10 do
			train.Direction += 1
		end
	elseif hitPart.Name == "TurnLeft1" then
		for i = 1,10 do
			train.Direction -= 1
		end
	end
end)

-- Update the train's position every 0.1 seconds
while task.wait(0.1) do
	trainPart.CFrame = trainPart.CFrame  + CFrame.new(train.Speed, 0,0)
	trainPart.CFrame = CFrame.Angles(train.Direction,0,0)
end

*VERY untested (may have syntax errors)
** Debounce is probably required too

You may want to look into moving the object along a Bezier curve.

Essentially, whenever the object moves forwards, you calculate it’s angle of rotation using a dictionary of points that define the tracks, as effbeecee suggested. Each track segment would consist of 3 points. A starting point A, and a finishing point B, and then a third point C, that is used for interpolation.

The mathematical formula for a quadratic Bezier curve is as follows,

P = (1 - t)^2 * A + 2 * (1 - t) * t * C + t^2 * B

Where t is the “time”, being the distance that has been travelled along the curve represented as a value between 0 and 1. (Hence why it cannot be used directly to store the progress of your train, as it varies depending on the length of the segment)

Implementing this formula should give you a point on the curve, that can be used to position your train. And together with the difference in the position of the train in last call, you will be able to calculate the angle at which it should be rotated to counter for the positional change.

For example, the first part of the tracks make a 90 degree turn to the left. Then the points A, B and C would be:

local track1 = {
 A = Vector3.new(0, 0, 0),
 C = Vector3.new(10, 0, 0),
 B = Vector3.new(10, 0, 10)
}

Then after reaching B, when t = 1, you would move on to the next set of tracks. If the track should be straight, then the point B should just be on the straight line between A and B, or you may use another formula.

Playing around with this may help you understand the concept of Bezier curves,
https://samgentle.com/playgrounds/bezier

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.