How to make smooth character movement

that’s why i made a note in the unMove() function saying that you can change it however you want. Instead of setting the walkspeed to a number, just decrease by 1 until they start moving or it gets to that number

so you want players can’t turn back instantly?
you want them spin like the mid point is in the back?

thats not the problem, they keep moving but in different directions without deaccelerating, so the function unmove will not even start.

What he means is that turning around would take a little more sensitivity , turning around would be slower and smoother

I don’t fully understand what you mean, but basicly i want instead of letting a player instantly walk somewhere, they need to accelerate, and make it so that they cannot turn too much, because they need to change dirictions, and how faster you are, how longer it takes to turn

yes, also starting to walk will also accelerate, instead if instantly walking, so that its smooth andmore realistic

well i guess every time thier move direction changes you could lower the walkspeed so it can build back up, although it won’t work if they change their direction by turning their camera.

Edit: I made a super janky system but I think it works, feel free to tweak it

local char = game.Players.LocalPlayer.Character or game.Players.LocalPlayer.Character:Wait()
local hum = char:WaitForChild("Humanoid")

local moving = false

local movingLV = char.HumanoidRootPart.CFrame.LookVector

local delayTime = 0.5
local speedIncrease = 1
local maxSpeed = 25
local startingSpeed = 10

function unMove()
	moving = false
	hum.WalkSpeed = startingSpeed
	--anything else you want after they stop walking

	if hum.MoveDirection ==,0,0) then
		if moving == true then
	elseif moving == false then
		moving = true
		while hum.MoveDirection ~=,0,0) and moving == true do
			if hum.WalkSpeed <= maxSpeed then

while task.wait() do
	if moving == true then
		if movingLV ~= char.HumanoidRootPart.CFrame.LookVector then
			 e = movingLV - char.HumanoidRootPart.CFrame.LookVector
		local a = e.X if a<0 then a=0-a end
		local b = e.Z if b<0 then b=0-b end
			if a+b >= 0.5 then
				local o = hum.WalkSpeed
				local w = math.ceil(((a+b)/hum.WalkSpeed)*10)
				if hum.WalkSpeed - w >= startingSpeed then
					--print(o, hum.WalkSpeed - w, a+b,(a+b)/hum.WalkSpeed,((a+b)/hum.WalkSpeed)*10)
					hum.WalkSpeed -= w
			movingLV = char.HumanoidRootPart.CFrame.LookVector

the code is pretty ugly and I had to use a while loop but it still kinda works

1 Like

sorry for the wait, thats a good script you made, but it still isn’t smooth. When you stop walking you also instantly stop walking, thats also a problem we need to fix.

1 Like

well i think I’ve provided enough code for you to do the rest. The devforum really isn’t for asking for people to write your code for you, but instead for getting suggestions on how to fix or make your own code.

I do have a suggestion though. When they stop walking or turn directions you could give them a brief decreasing vector force in the direction the they were last facing.

1 Like

in your 2 hours of research i found it in 5 seconds of typing Simulating smoother character movement? - #3 by ThanksRoBama

i already found that, it was outdated ):

but its literally not? you can easily use it

I replaced ControlScript, and i just couldend walk after i did the tutorial

well then you did it wrong. i used it and did it and it works perfectly fine

just read through the posts in the topic

1 Like

I did the tutorial again, but there’s an error:

Here’s the code i made

local RunS = game:GetService("RunService")
local InputS = game:GetService("UserInputService")

local player = game.Players.LocalPlayer
local camera = game.Workspace.CurrentCamera
local character = player.Character or player.CharacterAdded:Wait()

local targetMoveVelocity =
local moveVelocity =
local moveAcceleration = 8

	character = _character

local walkKeyBinds = {
	Forward = { Key = Enum.KeyCode.W, Direction = Enum.NormalId.Front },
	Backward = { Key = Enum.KeyCode.S, Direction = Enum.NormalId.Back },
	Left = { Key = Enum.KeyCode.A, Direction = Enum.NormalId.Left },
	Right = { Key = Enum.KeyCode.D, Direction = Enum.NormalId.Right }

local function getWalkDirectionCameraSpace()
	local walkDir =

	for keyBindName, keyBind in pairs(walkKeyBinds) do
		if InputS:IsKeyDown(keyBind.Key) then
			walkDir += Vector3.FromNormalId( keyBind.Direction )

	if walkDir.Magnitude > 0 then --(0, 0, 0).Unit = NaN, do not want
		walkDir = walkDir.Unit --Normalize, because we (probably) changed an Axis so it's no longer a unit vector

	return walkDir

local function getWalkDirectionWorldSpace()
	local walkDir = camera.CFrame:VectorToWorldSpace( getWalkDirectionCameraSpace() )
	walkDir *=, 0, 1) --Set Y axis to 0

	if walkDir.Magnitude > 0 then --(0, 0, 0).Unit = NaN, do not want
		walkDir = walkDir.Unit --Normalize, because we (probably) changed an Axis so it's no longer a unit vector

	return walkDir

local function updateMovement( dt )
	local humanoid = character:FindFirstChild("Humanoid")
	if humanoid then
		local moveDir = getWalkDirectionWorldSpace()
		targetMoveVelocity = moveDir
		moveVelocity = lerp( moveVelocity, targetMoveVelocity, math.clamp(dt * moveAcceleration, 0, 1) )
		humanoid:Move( moveVelocity )


Do you know how to fix this?

1 Like

I Fixed the error but now i see a warn:
I think the controlscript is updated

well you didnt even follow the posts cause the code is already there

What do you mean? i litterly did what the tutorial said. Could you than tell me what i did wrong?

well, there was code, but i changed it because there was a error.

i changed the line, to this line of code:

mainMoveVector = mainMoveVector:lerp(targetMoveVector, math.clamp(dt * MOVE_ACCELERATION, 0, 1) )

the lerp function is lerp(a, b, t) = a + (b — a) * t