WASD keys not compatible with mobile joystick

The current problem is that when I try and move on mobile my speed is for some reason stuck at 16, when it should be at 25 and gradually increase to 45. The only thing compatible with this script and mobile is the wall climbing, I just need to get the WASD keys to be compatible with the joystick. if you can help that would be greatly appreciated.

local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")

local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local rootPart = character:WaitForChild("HumanoidRootPart")

local wall = nil
local hrp = rootPart
local climbAnim = humanoid:LoadAnimation(character:WaitForChild("Animate").climb.ClimbAnim)
local climbFinished = Instance.new("BoolValue")
climbFinished.Name = "ClimbFinished"
climbFinished.Parent = character

local wDisabled = false

local function disableWKey()
	if not wDisabled then
		wDisabled = true
		UserInputService.InputBegan:Connect(function(input, gameProcessedEvent)
			if input.KeyCode == Enum.KeyCode.W and humanoid:GetState() == Enum.HumanoidStateType.Climbing then
				return true -- Prevent W key from being processed
			end
		end)
	end
end

local function enableWKey()
	if wDisabled then
		wDisabled = false
	end
end

local defaultSpeed = 25
local maxSpeed = 45
local increaseRate = 0.3
local decreaseRate = (maxSpeed - defaultSpeed) / 0.5
local airControlRate = 1
local airDecelerationRate = 0.95
local directionChangeCooldown = 0.2
local currentSpeed = defaultSpeed
local defaultFOV = 70
local maxFOV = 100
local holdingW = false
local holdingOtherKey = {S = false, A = false, D = false}
local fovDecreaseTime = 0.1
local currentFOV = defaultFOV
local targetFOV = defaultFOV
local stopTime = nil
local lastDirectionChangeTime = 0
local isClimbing = false

local function resetSpeedAndFOV()
	currentSpeed = defaultSpeed
	humanoid.WalkSpeed = currentSpeed
	currentFOV = defaultFOV
	targetFOV = defaultFOV
	game.Workspace.CurrentCamera.FieldOfView = defaultFOV
end

local animator = humanoid:WaitForChild("Animator")
local moveAnimation = Instance.new("Animation")
moveAnimation.AnimationId = "rbxassetid://17541868871"
local moveAnimationTrack = animator:LoadAnimation(moveAnimation)

local function onKeyPress(input)
	if input.KeyCode == Enum.KeyCode.W then
		holdingW = true
		stopTime = nil
	elseif input.KeyCode == Enum.KeyCode.S then
		holdingOtherKey.S = true
		stopTime = nil
	elseif input.KeyCode == Enum.KeyCode.A then
		holdingOtherKey.A = true
		stopTime = nil
	elseif input.KeyCode == Enum.KeyCode.D then
		holdingOtherKey.D = true
		stopTime = nil
	end

	if holdingW or holdingOtherKey.S or holdingOtherKey.A or holdingOtherKey.D then
		if not moveAnimationTrack.IsPlaying then
			moveAnimationTrack:Play()
		end
	end
end

local function onKeyRelease(input)
	if input.KeyCode == Enum.KeyCode.W then
		holdingW = false
		stopTime = os.clock()
	elseif input.KeyCode == Enum.KeyCode.S then
		holdingOtherKey.S = false
		stopTime = os.clock()
	elseif input.KeyCode == Enum.KeyCode.A then
		holdingOtherKey.A = false
		stopTime = os.clock()
	elseif input.KeyCode == Enum.KeyCode.D then
		holdingOtherKey.D = false
		stopTime = os.clock()
	end

	if not holdingW and not holdingOtherKey.S and not holdingOtherKey.A and not holdingOtherKey.D then
		if moveAnimationTrack.IsPlaying then
			moveAnimationTrack:Stop()
		end
	end
end

local function increaseSpeedAndFOV(deltaTime)
	if holdingW then
		currentSpeed = math.min(currentSpeed + (increaseRate * deltaTime * 60), maxSpeed)
		humanoid.WalkSpeed = currentSpeed
		local fovProgress = (currentSpeed - defaultSpeed) / (maxSpeed - defaultSpeed)
		targetFOV = defaultFOV + (maxFOV - defaultFOV) * fovProgress
	end
end

local function decreaseSpeed(deltaTime)
	if not holdingW and currentSpeed > defaultSpeed then
		currentSpeed = math.max(currentSpeed - (decreaseRate * deltaTime), defaultSpeed)
		humanoid.WalkSpeed = currentSpeed
	end
end

local function updateFOV(deltaTime)
	if currentFOV ~= targetFOV then
		local fovStep = (targetFOV - currentFOV) * deltaTime / fovDecreaseTime
		currentFOV = currentFOV + fovStep
		if math.abs(targetFOV - currentFOV) < 0.1 then
			currentFOV = targetFOV
		end
		game.Workspace.CurrentCamera.FieldOfView = currentFOV
	end
end

local function isInAir()
	return humanoid:GetState() == Enum.HumanoidStateType.Freefall or humanoid:GetState() == Enum.HumanoidStateType.Jumping
end

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 and not isInAir() then
		moveDirection = moveDirection - camera.CFrame.LookVector
	end

	if moveDirection.Magnitude > 0 then
		moveDirection = moveDirection.Unit
	end

	return moveDirection
end

local function updateAirMovement(deltaTime)
	if isInAir() and not isClimbing then
		local currentTime = os.clock()
		if currentTime - lastDirectionChangeTime >= directionChangeCooldown then
			local movementDirection = getMovementDirection()
			local isMovingInAir = holdingW or holdingOtherKey.S or holdingOtherKey.A or holdingOtherKey.D

			if holdingW and movementDirection.Magnitude > 0 then
				local horizontalDirection = Vector3.new(movementDirection.X, 0, movementDirection.Z).Unit
				if rootPart then
					local currentVelocity = rootPart.Velocity
					local targetVelocity = horizontalDirection * maxSpeed
					rootPart.Velocity = Vector3.new(
						math.clamp(targetVelocity.X * airControlRate + currentVelocity.X * (1 - airControlRate), -maxSpeed, maxSpeed),
						currentVelocity.Y,
						math.clamp(targetVelocity.Z * airControlRate + currentVelocity.Z * (1 - airControlRate), -maxSpeed, maxSpeed)
					)
					lastDirectionChangeTime = currentTime
				end
			end
		end

		if rootPart then
			rootPart.Velocity = Vector3.new(
				rootPart.Velocity.X * airDecelerationRate,
				rootPart.Velocity.Y,
				rootPart.Velocity.Z * airDecelerationRate
			)
		end
	end
end

RunService.RenderStepped:Connect(function(deltaTime)
	if holdingW then
		increaseSpeedAndFOV(deltaTime)
	elseif holdingOtherKey.S or stopTime then
		decreaseSpeed(deltaTime)
		if currentSpeed == defaultSpeed then
			stopTime = nil
		end
		targetFOV = defaultFOV
	end
	updateFOV(deltaTime)
	updateAirMovement(deltaTime)
end)

UserInputService.InputBegan:Connect(onKeyPress)
UserInputService.InputEnded:Connect(onKeyRelease)

player.CharacterAdded:Connect(function(char)
	character = char
	humanoid = character:WaitForChild("Humanoid")
	rootPart = character:WaitForChild("HumanoidRootPart")
	animator = humanoid:WaitForChild("Animator")
	moveAnimationTrack = animator:LoadAnimation(moveAnimation)
	resetSpeedAndFOV()
end)

RunService.Heartbeat:Connect(function()
	local raycastParams = RaycastParams.new()
	raycastParams.FilterDescendantsInstances = {character}
	raycastParams.FilterType = Enum.RaycastFilterType.Exclude

	local leftLeg = character:WaitForChild("Left Leg")
	local raycastResult = workspace:Raycast(leftLeg.Position, hrp.CFrame.LookVector * 5, raycastParams)

	wall = raycastResult and raycastResult.Instance or nil

	if wall and wall.Name == "WallClimb" then
		hrp.Velocity = Vector3.new(hrp.Velocity.X, math.max(20, hrp.Velocity.Y), hrp.Velocity.Z)
		isClimbing = true

		if humanoid:GetState() ~= Enum.HumanoidStateType.Climbing then
			humanoid:ChangeState(Enum.HumanoidStateType.Climbing)
		end

		if not climbAnim.IsPlaying then
			climbAnim:Play()
		end

		climbFinished.Value = false
		disableWKey()
	else
		if climbAnim.IsPlaying then
			climbAnim:Stop()
		end

		climbFinished.Value = true
		enableWKey()
		isClimbing = false
	end
end)

-- Ensure that animations and speeds are reset if the player dies or resets their character
player.CharacterRemoving:Connect(function()
	moveAnimationTrack:Stop()
	resetSpeedAndFOV()
	isClimbing = false
	wDisabled = false
	holdingW = false
	holdingOtherKey = {S = false, A = false, D = false}
	stopTime = nil
end)

-- Reset states and reload animations when the character respawns
player.CharacterAdded:Connect(function(char)
	character = char
	humanoid = character:WaitForChild("Humanoid")
	rootPart = character:WaitForChild("HumanoidRootPart")
	animator = humanoid:WaitForChild("Animator")
	moveAnimationTrack = animator:LoadAnimation(moveAnimation)
	resetSpeedAndFOV()

	-- Ensure climb animation is properly reset
	climbAnim = humanoid:LoadAnimation(character:WaitForChild("Animate").climb.ClimbAnim)
	climbFinished.Parent = character
end)

THIS PROBLEM HAS BEEN OFFICIALLY SOLVED I WAS NOT USING HUMANOID.WALKSPEED I WAS CHANGING THE PLAYERS HRP.VELOCITY. I have made it so it is console, and mobile compatible as everything is working rn

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.