# 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
end

hum:GetPropertyChangedSignal("MoveDirection"):Connect(function()
if hum.MoveDirection == Vector3.new(0,0,0) then
if moving == true then
unMove()
end
return
elseif moving == false then
moving = true
while hum.MoveDirection ~= Vector3.new(0,0,0) and moving == true do
if hum.WalkSpeed <= maxSpeed then
hum.WalkSpeed+=speedIncrease
end
end
end
end)

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
print("A")
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
end

end
movingLV = char.HumanoidRootPart.CFrame.LookVector
end
end
end
``````

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:

``````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 = Vector3.new()
local moveVelocity = Vector3.new()
local moveAcceleration = 8

character = _character
end)

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 = Vector3.new()

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

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
end

return walkDir
end

local function getWalkDirectionWorldSpace()
local walkDir = camera.CFrame:VectorToWorldSpace( getWalkDirectionCameraSpace() )
walkDir *= Vector3.new(1, 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
end

return walkDir
end

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 )
end
end

RunS.RenderStepped:Connect(updateMovement)
``````

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