# How can I make my CFrame Coaster smoother?

Hello!
I need help with this as I’ve been stuck for a while.

https://gyazo.com/d75ea7e1a32bb6bc51bb0da24671a422

As you can see from the video, the ride only changes speed when it touches a blue dot.

Is there any way to make this smoother? Maybe add some kind of gravity to it?
Thank you!

You can try having specific dots to change the speed, and not every blue dot. For example, you can change the speed of the coaster from `dot1` to `dot5` instead of `dot1`, `dot2`, `dot3`, `dot4`, and `dot5`. You would also use a `Sine` easing style to increase speed for realism.

``````local speedDots = {dot1 = 1, dot5 = 5} -- {dotNumber = speed}
local trainSpeed = 0.5

local function easeInSine(x) -- For speeding up or slowing down
return 1 - math.cos((x * math.pi) / 2)
end

local function easeOutSine(x) -- For braking
return math.sin((x * math.pi) / 2);
end

dot1.Touched:Connect(function()
local x = -- The percent traveled by the train from dot1 to dot 5 (from 0% - 100%, or 0 - 1)
local currentdot = speedDots.dot1 -- The current dot
local nextDot = speedDots.dot5 -- The next dot
trainSpeed = currentDot + easeInSine(x) * (nextDot - currentDot) -- Speeding up the train
end
``````

Yes and no.

If the next position is higher, then theoretically, the carts should move slower.

If the next position is lower, then it’s vice-versa; move faster.

As for a flat plane, you still have to bear in mind the laws of acceleration, which state that friction will cause you to slow down.

It’s basically a case where you need to bear in mind acceleration, gravity, and other underlying factors. Putting them into play, and making movement non-linear, will help smooth-out your coaster.

1 Like

The only issue with that would be the distancing from each cart. Each cart follows one node behind the cart infront. so if it was one long stretch, it wouldn’t work too well.

Here’s what I have set up for this:

``````if LASTNODE.Position.Y > node.Position.Y then
-- GOING DOWN
if SPEED <= 0.1 then
SPEED = 0.1
else
SPEED -= 0.025
end
elseif LASTNODE.Position.Y < node.Position.Y then
-- GOING UP
if SPEED >= 0.5 then
SPEED = 0.5
else
SPEED += 0.0125
end
elseif LASTNODE.Position.Y == node.Position.Y then
-- EVEN
end
``````

It makes it a little bit better, but it accelerates too fast when its going downhill. I wanted to try dividing instead of subtracting. Lemme know what you think.

I’ve edited my previous post for a more in-depth explanation.

To solve that, you can either make the speed of each cart the same as the speed of the cart in front, or make the speed the average speed of the first and last cart.

To solve that, you can either make the speed of each cart the same as the speed of the cart in front

This is actually what I currently do.

I’ve edited my previous post for a more in-depth explanation.

Can you explain it to me more in-depth? I’d love to learn how it works.

Taking the code from my first post:

``````local speedDots = {dot1 = 1, dot5 = 5} -- {dotNumber = speed}
local trainSpeed = 0.5

local function easeInSine(x) -- For speeding up or slowing down
return 1 - math.cos((x * math.pi) / 2)
end

local function easeOutSine(x) -- For braking
return math.sin((x * math.pi) / 2);
end

dot1.Touched:Connect(function()
local x = -- The percent traveled by the train from dot1 to dot 5 (from 0% - 100%, or 0 - 1)
local currentdot = speedDots.dot1 -- The current dot
local nextDot = speedDots.dot5 -- The next dot
trainSpeed = currentDot + easeInSine(x) * (nextDot - currentDot) -- Speeding up the train
end
``````

What this code is doing is to make it so that It slowly increases speed from one point to another instead of every single point which can cause jankiness. Instead of defining the speed, try defining the change in y level, then calculate the speed based off the distance.

How can I add this onto my code? Here’s what I have currently:

``````--// SERVICES \\--
local TS = game:GetService("TweenService")

--// MODULES \\--
local EasyTween = require(game.ReplicatedStorage:WaitForChild("EasyClientTween"))
local tweenHandler = EasyTween.new()

--// VARIABLES \\--
local CARTS = script.Parent.Carts
local NODES = script.Parent.Nodes

local START_NODE = 5
local CURRENT_NODE = START_NODE
local SPEED = 0.2

--// OTHER STUFF \\--
local NEW_SPEED = false
local LASTNODE = NODES.Node0

local function tweenRide(ride,node)

local Goal = {["CFrame"] = node.CFrame}
local TI = TweenInfo.new(
SPEED,
Enum.EasingStyle.Linear,
Enum.EasingDirection.InOut,
0,
false,
0
)
local RideTween = TS:Create(ride,TI,Goal)
RideTween:Play()
end

local function setupRide(ride,node)
if NEW_SPEED == false then
--if node and node:FindFirstChild("Speed") then
--	SPEED = node.Speed.Value
--end
if LASTNODE.Position.Y > node.Position.Y then
-- GOING DOWN
if SPEED <= 0.1 then
SPEED = 0.1
else
SPEED -= 0.025
end
elseif LASTNODE.Position.Y < node.Position.Y then
-- GOING UP
if SPEED >= 0.5 then
SPEED = 0.5
else
SPEED += 0.0125
end
elseif LASTNODE.Position.Y == node.Position.Y then
-- EVEN
end

print(SPEED)
LASTNODE = node
NEW_SPEED = true
end

if not node then
CURRENT_NODE = START_NODE
end

tweenRide(ride.CartNode,node)
end

wait(5)
while wait() do
if NODES:FindFirstChild("Node"..CURRENT_NODE) then
setupRide(CARTS.Cart1,NODES:FindFirstChild("Node"..CURRENT_NODE))
else
CURRENT_NODE = START_NODE
end
if NODES:FindFirstChild("Node"..CURRENT_NODE - 2) then
setupRide(CARTS.Cart2,NODES:FindFirstChild("Node"..CURRENT_NODE - 2))
else
CURRENT_NODE = START_NODE
end
if NODES:FindFirstChild("Node"..CURRENT_NODE - 4) then
setupRide(CARTS.Cart3,NODES:FindFirstChild("Node"..CURRENT_NODE - 4))
else
CURRENT_NODE = START_NODE
end

wait(SPEED - 0.05)
CURRENT_NODE += 1
NEW_SPEED = false
end
``````

I know it’s really messy, I plan to simplify it at some point.
EDIT: Sorry for bugging you a bunch.

Sorry if it’s confusing, Still learning the best method’s to make this work. I really appreciate all the help so far!