Game Breaking While I Go Backwards

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)
1 Like

Hello. Could you provide a video on this, but to my understanding it shakes while going backwards?
I once had this issue on a game of mine and i fixed it by setting Humanoid.AutoRotate to false.

I’m sorry I am not sure how I could make a video showing this. But when I tried humanoid auto rotate, it did in fact fix the problem but when I turned around, my camera, and how I change velocities while in the air broke. Keep in mind this game is going to be mainly first person, only 3rd person will be just an option in settings.

is updateAirMovement requiring W to be held intentional?

The holding w is In fact mandatory, because otherwise the juke mechanic does not work. Basically I want to change velocities wherever I look and only if I am holding w. So yeah w being held is intentional. I am just gonna try to fix the animations and see if that works…