Speed Manager having issues

The issue is that I am trying to set the users walk speed to 0 while being in a aircombat.
I attribute air combat attribute to the user’s character and if the attribute is true I set the speed to 0. But th issue is that I think it’s going to 0 but automatically changing back to the original walk speed caused by something else that I dont understand…

This is the speed manager:

local SpeedManager = {}

function SpeedManager:applySlow(character, slowFactor, duration)
	if not character then return end
	local humanoid = character:FindFirstChildOfClass("Humanoid")
	if not humanoid then return end

	if SpeedManager[humanoid] then
		SpeedManager[humanoid]["Duration"] = duration
		task.cancel(SpeedManager[humanoid]["Thread"])
	else
		local originalSpeed = humanoid.WalkSpeed
		local originalJumpHeight = humanoid.JumpHeight
		local originalJumpPower = humanoid.JumpPower
		local currentSpeedFactor = character:GetAttribute("CurrentSpeedFactor") or 1
		local newSpeedFactor = currentSpeedFactor * slowFactor

		if currentSpeedFactor == 1 then
			character:SetAttribute("CurrentSpeedFactor", newSpeedFactor)
			humanoid.WalkSpeed = originalSpeed * newSpeedFactor
			humanoid.JumpHeight = 0
			humanoid.JumpPower = 0
		end

		SpeedManager[humanoid] = {
			Factor = newSpeedFactor,
			Duration = duration,
			OriginalSpeed = originalSpeed,
			OriginalJumpHeight = originalJumpHeight,
			OriginalJumpPower = originalJumpPower,
		}
	end
	
	character:SetAttribute("IsStunned", true)

	local Thread = task.delay(duration, function()
		if SpeedManager[humanoid] then
			character:SetAttribute("CurrentSpeedFactor", 1)
			humanoid.WalkSpeed = SpeedManager[humanoid].OriginalSpeed
			humanoid.JumpHeight = SpeedManager[humanoid].OriginalJumpHeight
			humanoid.JumpPower = SpeedManager[humanoid].OriginalJumpPower
			SpeedManager[humanoid] = nil
		end
		character:SetAttribute("IsStunned", false)
	end)

	SpeedManager[humanoid]["Thread"] = Thread
end

function SpeedManager:ApplyEffect(character, effect)
	if not character then return end
	local humanoid = character:FindFirstChildOfClass("Humanoid")
	if not humanoid then return end

	local characterName = character.Name
	print("Applying effect to character:", characterName)

	if effect == "block" then
		if not character:GetAttribute("OriginalWalkSpeed") then
			character:SetAttribute("OriginalWalkSpeed", humanoid.WalkSpeed)
			character:SetAttribute("OriginalJumpHeight", humanoid.JumpHeight)
		end
		humanoid.WalkSpeed = 5
		humanoid.JumpHeight = 0
		print(humanoid.WalkSpeed)
	elseif effect == "normal" then
		humanoid.WalkSpeed = character:GetAttribute("OriginalWalkSpeed") or 16
		humanoid.JumpHeight = character:GetAttribute("OriginalJumpHeight") or 7.2
		character:SetAttribute("OriginalWalkSpeed", nil)
		character:SetAttribute("OriginalJumpHeight", nil)
	end
end

function SpeedManager:MonitorAirCombat(character)
	if not character then return end
	local humanoid = character:FindFirstChildOfClass("Humanoid")
	if not humanoid then return end

	if not character:GetAttribute("OriginalWalkSpeed") then
		character:SetAttribute("OriginalWalkSpeed", humanoid.WalkSpeed)
	end

	local function enforceAirCombatSpeed()
		if character:GetAttribute("AirCombat") then
			humanoid.WalkSpeed = 0
		else
			humanoid.WalkSpeed = character:GetAttribute("OriginalWalkSpeed") or 16
			character:SetAttribute("OriginalWalkSpeed", nil)
		end
	end

	enforceAirCombatSpeed()

	character.AttributeChanged:Connect(function(attributeName)
		if attributeName == "AirCombat" then
			enforceAirCombatSpeed()
		end
	end)

	while character and character.Parent do
		enforceAirCombatSpeed()
		wait(1)
	end
end



return SpeedManager

I call the function right here in a server script

local SpeedManager = require(script.SpeedManager)
local Players = game:GetService("Players")

local function monitorCharacterAirCombat(player)
	player.CharacterAdded:Connect(function(character)
		SpeedManager:MonitorAirCombat(character)
	end)
end

Players.PlayerAdded:Connect(monitorCharacterAirCombat)

for _, player in ipairs(Players:GetPlayers()) do
	monitorCharacterAirCombat(player)
end

I was wondering if there is way to force or prevent other changes to the walk speed until the aircombat is false…

1 Like

Try adding some print commands to watch the script function:



local SpeedManager = {}

function SpeedManager:applySlow(character, slowFactor, duration)
	if not character then return end
	local humanoid = character:FindFirstChildOfClass("Humanoid")
	if not humanoid then return end

	if SpeedManager[humanoid] then
		SpeedManager[humanoid]["Duration"] = duration
		task.cancel(SpeedManager[humanoid]["Thread"])
	else
		local originalSpeed = humanoid.WalkSpeed
		local originalJumpHeight = humanoid.JumpHeight
		local originalJumpPower = humanoid.JumpPower
		local currentSpeedFactor = character:GetAttribute("CurrentSpeedFactor") or 1
		local newSpeedFactor = currentSpeedFactor * slowFactor

		if currentSpeedFactor == 1 then
			character:SetAttribute("CurrentSpeedFactor", newSpeedFactor)
			humanoid.WalkSpeed = originalSpeed * newSpeedFactor
			humanoid.JumpHeight = 0
			humanoid.JumpPower = 0
		end

		SpeedManager[humanoid] = {
			Factor = newSpeedFactor,
			Duration = duration,
			OriginalSpeed = originalSpeed,
			OriginalJumpHeight = originalJumpHeight,
			OriginalJumpPower = originalJumpPower,
		}
	end

	character:SetAttribute("IsStunned", true)

	local Thread = task.delay(duration, function()
		if SpeedManager[humanoid] then
			character:SetAttribute("CurrentSpeedFactor", 1)
			humanoid.WalkSpeed = SpeedManager[humanoid].OriginalSpeed
			humanoid.JumpHeight = SpeedManager[humanoid].OriginalJumpHeight
			humanoid.JumpPower = SpeedManager[humanoid].OriginalJumpPower
			SpeedManager[humanoid] = nil
		end
		character:SetAttribute("IsStunned", false)
	end)

	SpeedManager[humanoid]["Thread"] = Thread
end

function SpeedManager:ApplyEffect(character, effect)
	if not character then return end
	local humanoid = character:FindFirstChildOfClass("Humanoid")
	if not humanoid then return end

	local characterName = character.Name
	print("Applying effect to character:", characterName)

	if effect == "block" then
		if not character:GetAttribute("OriginalWalkSpeed") then
			character:SetAttribute("OriginalWalkSpeed", humanoid.WalkSpeed)
			character:SetAttribute("OriginalJumpHeight", humanoid.JumpHeight)
		end
		humanoid.WalkSpeed = 5
		humanoid.JumpHeight = 0
		print(humanoid.WalkSpeed)
	elseif effect == "normal" then
		humanoid.WalkSpeed = character:GetAttribute("OriginalWalkSpeed") or 16
		humanoid.JumpHeight = character:GetAttribute("OriginalJumpHeight") or 7.2
		character:SetAttribute("OriginalWalkSpeed", nil)
		character:SetAttribute("OriginalJumpHeight", nil)
	end
end

function SpeedManager:MonitorAirCombat(character)
	if not character then return end
	local humanoid = character:FindFirstChildOfClass("Humanoid")
	if not humanoid then return end

	if not character:GetAttribute("OriginalWalkSpeed") then
		character:SetAttribute("OriginalWalkSpeed", humanoid.WalkSpeed)
	end

	local function enforceAirCombatSpeed()
		print("Enforcing")
		if character:GetAttribute("AirCombat") then
			humanoid.WalkSpeed = 0
			print("Walkspeed = Air Combat", humanoid.WalkSpeed)
		else
			humanoid.WalkSpeed = character:GetAttribute("OriginalWalkSpeed") or 16
			character:SetAttribute("OriginalWalkSpeed", nil)
			print("Walkspeed = Normal", humanoid.WalkSpeed)
		end
	end

	enforceAirCombatSpeed()

	character.AttributeChanged:Connect(function(attributeName)
		if attributeName == "AirCombat" then
			enforceAirCombatSpeed()
			print("Changed")
		end
	end)

	while character and character.Parent do
		print("Loop")
		enforceAirCombatSpeed()
		wait(1)
	end
end



return SpeedManager

1 Like

In a local script could you check when the humanoid walk speed property changes and print it, that way you could really diagnose the issue?