This is a short tutorial! On Roblox, there’s been a long-standing issue of adding acceleration and deceleration to your character movement to make it feel “heavier.” It’s a key part of more realistic games. However, so far with walkspeed-based methods, deceleration hasn’t always been an obvious solution. So, find out how to add it yourself!
Experience level: Beginner
Time required: 5 mins
Note: Script line numbers might be innacurate to ± 10 lines! Refer to the screenshots to make sure your code is in the right place.
Video example
Video example here!
Download the .rbxl example here:
HeavyMovementDemo.rbxl (184.2 KB)
Forking the PlayerModule
-
Playtest your game in Roblox Studio, and look for
Players > [your username] > PlayerScripts > PlayerModule
. Copy the “PlayerModule” ModuleScript.
PlayerModule at the bottom of the screenshot -
Stop the playtest and paste the “PlayerModule” into
StarterPlayer > StarterPlayerScripts
Modifying the PlayerModule
-
Expand “PlayerModule” and open the “ControlModule” ModuleScript.
-
Navigate to around line 105 (Use Ctrl + G or Cmd + G to quickly jump there). Past the following snippet of code:
-- Custom accel/decel variables
self.speedRatio = 0
self.retainedMoveDirection = Vector3.new()
- Navigate to around line 530. Paste this snippet of code:
-- Accelerate when player is trying to move
if moveVector.Magnitude > 0.1 then
-- accelTime to reach full speed in seconds
local accelTime = 0.5
self.speedRatio = math.min(self.speedRatio + dt * (1 / accelTime), 1)
-- apply player input relevant moveVector
self.retainedMoveDirection = moveVector
else
-- Decelerate when they stopped
-- decelTime to reach full stop in seconds
local decelTime = 0.12
self.speedRatio = math.max(self.speedRatio - dt * (1 / decelTime), 0)
-- "freeze" the retainedMoveDirection, because moveVector is now a zero vector
end
- Replace the line
self.moveFunction(Players.LocalPlayer, moveVector, false)
with the following:
local customMoveVector = self.retainedMoveDirection * self.speedRatio
self.moveFunction(Players.LocalPlayer, customMoveVector, false)
- Playtest, and you now should be accelerating and decelerating when you move!
(Advanced) Easing the acceleration
This is entirely optional, but will make movement feel a lot better for players. Basically, it applies the constant acceleration from 0-100% to an EasingStyle, to “arc” the acceleration. For example, Quad (Out) looks like this: (x-axis is speedRatio
and y-axis is easedSpeedRatio
)
-
Define
TweenService
outside of theControlModule.OnRenderStepped
function.
-
Paste the following snippet, replacing the
self.moveFunction(...)
and the previous code you pasted.
-- Applies speedRatio (0-1) to an EasingStyle to control the "feel" of the acceleration/deceleration
local easedSpeedRatio = TweenService:GetValue(self.speedRatio, Enum.EasingStyle.Quart, Enum.EasingDirection.Out)
local customMoveVector = self.retainedMoveDirection * easedSpeedRatio
self.moveFunction(Players.LocalPlayer, customMoveVector, false)
- Playtest, and movement should feel noticeably smoother! You can change the EasingStyle and EasingDirection however you’d like. For faster initial acceleration, use EasingStyle.Circular. For a “tripping” feel, use EasingStyle.Back. Refer to this page for visuals on each style and direction.
- 1
- 2
- 3
- 4
- 5
0 voters