I am currently working on a tag game, and the problem is when I am in the air and i press s(go backwards) my character shakes, and looks very broken. I think the problem is inside the updateAirMovement() function but I am not sure. I am a beginner scripter so I don’t have a lot of experience if you could help that would be greatly appreciated. Here is the script
local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local rootPart = character:WaitForChild("HumanoidRootPart")
local UserInputService = game:GetService("UserInputService")
local runService = game:GetService("RunService")
local defaultSpeed = 16
local maxSpeed = 75
local increaseRate = 1 -- Speed increase per frame
local directionChangeCooldown = 0.1 -- Delay in seconds between direction changes
local currentSpeed = defaultSpeed
local holdingW = false
local holdingOtherKey = {S = false, A = false, D = false}
local lastDirectionChange = 0 -- Timestamp of the last direction change
-- Function to reset speed
local function resetSpeed()
currentSpeed = defaultSpeed
humanoid.WalkSpeed = currentSpeed
end
-- Function to handle key press
local function onKeyPress(input)
if input.KeyCode == Enum.KeyCode.W then
holdingW = true
elseif input.KeyCode == Enum.KeyCode.S then
holdingOtherKey.S = true
elseif input.KeyCode == Enum.KeyCode.A then
holdingOtherKey.A = true
elseif input.KeyCode == Enum.KeyCode.D then
holdingOtherKey.D = true
end
end
-- Function to handle key release
local function onKeyRelease(input)
if input.KeyCode == Enum.KeyCode.W then
holdingW = false
resetSpeed()
elseif input.KeyCode == Enum.KeyCode.S then
holdingOtherKey.S = false
elseif input.KeyCode == Enum.KeyCode.A then
holdingOtherKey.A = false
elseif input.KeyCode == Enum.KeyCode.D then
holdingOtherKey.D = false
end
end
-- Function to increase speed
local function increaseSpeed(deltaTime)
if holdingW then
currentSpeed = math.min(currentSpeed + (increaseRate * deltaTime * 60), maxSpeed)
humanoid.WalkSpeed = currentSpeed
end
end
-- Function to check if the character is in the air
local function isInAir()
return humanoid:GetState() == Enum.HumanoidStateType.Freefall or humanoid:GetState() == Enum.HumanoidStateType.Jumping
end
-- Function to get the movement direction
local function getMovementDirection()
local camera = game.Workspace.CurrentCamera
local moveDirection = Vector3.new()
if holdingW then
moveDirection = moveDirection + camera.CFrame.LookVector
end
if holdingOtherKey.A then
moveDirection = moveDirection - camera.CFrame.RightVector
end
if holdingOtherKey.D then
moveDirection = moveDirection + camera.CFrame.RightVector
end
if holdingOtherKey.S then
moveDirection = moveDirection - camera.CFrame.LookVector
end
if moveDirection.Magnitude > 0 then
moveDirection = moveDirection.Unit
end
return moveDirection
end
-- Function to update movement in the air
local function updateAirMovement(deltaTime)
if isInAir() and holdingW and tick() - lastDirectionChange >= directionChangeCooldown then
local movementDirection = getMovementDirection()
if movementDirection.Magnitude > 0 then
local horizontalDirection = Vector3.new(movementDirection.X, 0, movementDirection.Z).Unit
if rootPart then
local targetVelocity = Vector3.new(horizontalDirection.X * currentSpeed, rootPart.Velocity.Y, horizontalDirection.Z * currentSpeed)
rootPart.Velocity = targetVelocity
lastDirectionChange = tick()
else
return -- Exit the function if rootPart is nil
end
end
end
end
-- Update speed and movement every frame
runService.RenderStepped:Connect(function(deltaTime)
increaseSpeed(deltaTime)
updateAirMovement(deltaTime)
end)
-- Connect functions to input events
UserInputService.InputBegan:Connect(onKeyPress)
UserInputService.InputEnded:Connect(onKeyRelease)
-- Ensure speed is reset when character spawns
player.CharacterAdded:Connect(function(char)
character = char
humanoid = character:WaitForChild("Humanoid")
rootPart = character:WaitForChild("HumanoidRootPart")
resetSpeed()
end)