local RunS = game:GetService(“RunService”)
local ContextActionService = game:GetService(“ContextActionService”)
local ReplicatedStorage = game:GetService(“ReplicatedStorage”)

local player = game.Players.LocalPlayer
local camera = game.Workspace.CurrentCamera
local character = player.Character or player.CharacterAdded:Wait()
repeat task.wait(1) until character:FindFirstChild(“Values”)
local Values = character.Values

player.CharacterAdded:Connect(function(_character)
character = _character
end)

local GameProcess = false
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 }
}

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

local keysDown = {}

local function getWalkDirectionCameraSpace()
local walkDir = Vector3.new()

for keyBindName, keyBind in walkKeyBinds do
if keysDown[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, character:FindFirstChild(“Humanoid”) and character.Humanoid:GetState() == Enum.HumanoidStateType.Swimming and 1 or 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 targetMoveVelocity = Vector3.new()
local moveVelocity = Vector3.new()
local moveAcceleration = 6

local function updateMovement( dt )
local humanoid = character:FindFirstChild(“Humanoid”)
if humanoid and humanoid.WalkSpeed > 0 then
local moveDir = getWalkDirectionWorldSpace()
if keysDown[Enum.KeyCode.Space] and humanoid:GetState() == Enum.HumanoidStateType.Swimming then
moveDir = Vector3.new(moveDir.x, 1, moveDir.z)
end
targetMoveVelocity = moveDir
moveVelocity = lerp( moveVelocity, targetMoveVelocity, math.clamp(dt * (humanoid:GetAttribute(“Downed”) and 2.5 or moveAcceleration), 0, 1) )
humanoid:Move( moveVelocity )
end
end

local function jumpAction(actionName, inputState, inputObject)
if inputState == Enum.UserInputState.Begin and not Values.Locked.Value then
local humanoid = character:FindFirstChild(“Humanoid”)
if humanoid and humanoid:GetStateEnabled(Enum.HumanoidStateType.Jumping) and humanoid.HipHeight >= -0.5 then
humanoid.Jump = true
end
end
end

local function keyAction(actionName, inputState, inputObject)
local keyCode = inputObject.KeyCode
if inputState == Enum.UserInputState.Begin then
keysDown[keyCode] = true
elseif inputState == Enum.UserInputState.End then
keysDown[keyCode] = nil
end
end

for _, keyBind in walkKeyBinds do
ContextActionService:BindAction(keyBind.Key.Name, keyAction, true, keyBind.Key)
end

ContextActionService:BindAction(“JumpAction”, jumpAction, false, Enum.KeyCode.Space)

RunS.RenderStepped:Connect(updateMovement)
require(script:WaitForChild(“FpsCamera”)):Start()

holding W, A, S or D then trying to chat won’t stop the player, he’ll keep on going until the key is pressed again. tell me what to replace in order to fix that. please dont create any new functions. please dont use UserInputService, use just ContextActionService.