Simulating smoother character movement?

I used one of the scripts and I keep getting this error on line 55
“moveVelocity = math.lerp( moveVelocity, targetMoveVelocity, math.clamp(dt * moveAcceleration, 0, 1) )”

 14:30:17.548  Players.Varsyte.PlayerScripts.MovementControl:55: attempt to call a nil value  -  Client - MovementControl:55

This is the code:

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

player.CharacterAdded:Connect(function(_character)
	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 = math.lerp( moveVelocity, targetMoveVelocity, math.clamp(dt * moveAcceleration, 0, 1) )
		humanoid:Move( moveVelocity )
	end
end	

RunS.RenderStepped:Connect(updateMovement)
2 Likes

Hi,
it looks like the culprit here is your attempt to call “math.lerp”. I was unable to find this function in the documentation: math | Documentation - Roblox Creator Hub

why dont works in mobile

because it only accepts keyboard input, theres nothing in there for mobile

Thank you so much for the script, because this post is just a mess.
But for some reason, my character isn’t able to jump anymore, once i use this script. Do you have any solutions? I couldn’t fix it myself.

okay, for everyones sanity, here’s a version that does not have the bug of slowing down when looking up/down and works on mobile:

local targetMoveVelocity = Vector3.new()
local moveVelocity = Vector3.new()
local Dir = CFrame.Angles(0,0,0)
local moveAcceleration = 5
local stopDecel = 10

local plr = game:GetService("Players").LocalPlayer
local RunS = game:GetService("RunService")
local InputS = game:GetService("UserInputService")
local CAS = game:GetService("ContextActionService")
local ctrlModule = require(plr:WaitForChild("PlayerScripts").PlayerModule:WaitForChild("ControlModule"))

local character = plr.Character or plr.CharacterAdded:Wait()
local camera = game.Workspace.CurrentCamera

local function lerp(a, b, t) return a + (b - a) * t end

local function getWalkDirectionCameraSpace()
	local walkDir = ctrlModule:GetMoveVector()

	if walkDir.Magnitude > 0 then
		walkDir = Vector3.new(walkDir.X, 0, walkDir.Z).Unit * walkDir.Magnitude
		if walkDir.Magnitude > 1 then
			walkDir = walkDir.Unit
		end
	end

	return walkDir
end

local function getWalkDirectionWorldSpace()
	local walkDir = camera.CFrame:VectorToWorldSpace(getWalkDirectionCameraSpace())

	if walkDir.Magnitude > 0 then
		walkDir = Vector3.new(walkDir.X, 0, walkDir.Z).Unit * walkDir.Magnitude
		if walkDir.Magnitude > 1 then
			walkDir = walkDir.Unit
		end
	end

	return walkDir
end

local function noY(vec:Vector3)
	return Vector3.new(vec.X,0,vec.Z)
end

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

RunS.RenderStepped:Connect(updateMovement)
14 Likes

Absolutely Goated.

Thirty Minimum Characters :japanese_goblin:

1 Like