Issue with setting walkspeed

Alright so I’m making a tower defense game, and in it there is a final boss that can stun towers. The issue I’m dealing with is that the Boss stops moving after attacking, and it doesn’t seem to be setting its walkspeed back to normal. During the attack, the boss is supposed to basically stop moving, then start moving again after the attack. Here’s my script (server script inside of Boss):

local TweenService = game:GetService("TweenService")

local towers = workspace.Towers
local mob = script.Parent

local tweenInfo = TweenInfo.new(
	1,
	Enum.EasingStyle.Linear,
	Enum.EasingDirection.Out,
	0
)

local originalWalkSpeed = mob.Humanoid.WalkSpeed

local function RestoreWalkSpeed()
	if mob.Humanoid.WalkSpeed == 0.001 then
		print("Restoring walkspeed:", originalWalkSpeed)
		mob.Humanoid.WalkSpeed = originalWalkSpeed
	end
end

local function Attack()
	local maxDistance = 30
	local anim = mob.Animations.Stun
	local animator = mob.Humanoid:WaitForChild("Animator")
	local animTrack = animator:LoadAnimation(anim)

	local currentWalkSpeed = mob.Humanoid.WalkSpeed
	mob.Humanoid.WalkSpeed = 0.001
	print("Setting walkspeed to 0.001")
	wait(0.4)

	mob.Ring.Transparency = 0.75
	local tween1 = TweenService:Create(mob.Ring, tweenInfo, {Size = Vector3.new(30, 0.1, 30), Transparency = 1})
	local sound = mob.Sounds.Stun
	tween1:Play()
	sound:Play()
	animTrack:Play()
	print("Everything complete")

	wait(1.5)

	tween1.Completed:Connect(function()
		mob.Ring.Size = Vector3.new(30, 0.1, 30)
		print("Tween1 completed")
	end)

	for _, target in pairs(towers:GetChildren()) do
		local config = target:FindFirstChild("Config")
		local isCliff = config and config:FindFirstChild("IsCliff")
		if isCliff and not isCliff.Value and config:FindFirstChild("Stun") then
			local distance = (target.HumanoidRootPart.Position - mob.HumanoidRootPart.Position).Magnitude
			if distance < maxDistance and config.Stun.Value == 0 then
				config.Stun.Value = 5
			end
		end
	end

	wait(1)
	local cooldown = 15
	wait(cooldown)

	print("Repeating Attack...")
	Attack()
end

mob.Humanoid.WalkSpeed = originalWalkSpeed

wait(5)
Attack()

coroutine.wrap(RestoreWalkSpeed)()

As you can see I’ve tried to debug it in the output, but I still can’t figure it out. Everything is printing out except for the “Restoring walkspeed” part, so I think there’s an issue with that function. Any help is appreciated :slight_smile:

That is quite obvious it is not working because the function Attack repeats itself. You should move the coroutine.wrap line to the one after wait(cooldown)

Also, you don’t need a coroutine for it.

I moved got rid of the coroutine.wrap and moved the line where I called the RestoreWalkSpeed function to underneath wait(cooldown) line and it still isn’t working. Here’s the updated script in case I missed something:

local TweenService = game:GetService("TweenService")

local towers = workspace.Towers
local mob = script.Parent

local tweenInfo = TweenInfo.new(
	1,
	Enum.EasingStyle.Linear,
	Enum.EasingDirection.Out,
	0
)

local originalWalkSpeed = mob.Humanoid.WalkSpeed

local function RestoreWalkSpeed()
	if mob.Humanoid.WalkSpeed == 0.001 then
		print("Restoring walkspeed:", originalWalkSpeed)
		mob.Humanoid.WalkSpeed = originalWalkSpeed
	end
end

local function Attack()
	local maxDistance = 30
	local anim = mob.Animations.Stun
	local animator = mob.Humanoid:WaitForChild("Animator")
	local animTrack = animator:LoadAnimation(anim)

	local currentWalkSpeed = mob.Humanoid.WalkSpeed
	mob.Humanoid.WalkSpeed = 0.001
	print("Setting walkspeed to 0.001")
	wait(0.4)

	mob.Ring.Transparency = 0.75
	local tween1 = TweenService:Create(mob.Ring, tweenInfo, {Size = Vector3.new(30, 0.1, 30), Transparency = 1})
	local sound = mob.Sounds.Stun
	tween1:Play()
	sound:Play()
	animTrack:Play()
	print("Complete")

	wait(1.5)

	tween1.Completed:Connect(function()
		mob.Ring.Size = Vector3.new(30, 0.1, 30)
		print("Tween1 completed")
	end)

	for _, target in pairs(towers:GetChildren()) do
		local config = target:FindFirstChild("Config")
		local isCliff = config and config:FindFirstChild("IsCliff")
		if isCliff and not isCliff.Value and config:FindFirstChild("Stun") then
			local distance = (target.HumanoidRootPart.Position - mob.HumanoidRootPart.Position).Magnitude
			if distance < maxDistance and config.Stun.Value == 0 then
				config.Stun.Value = 5
			end
		end
	end

	wait(1)
	local cooldown = 15
	wait(cooldown)
	
	RestoreWalkSpeed()

	print("Repeating Attack...")
	Attack()
end

mob.Humanoid.WalkSpeed = originalWalkSpeed

wait(5)
Attack()

Also, I’m using the cooldown as the amount of time in between attacks, so it wouldn’t make sense to move it there in the first place.

Whoops! I meant before the wait(cooldown), my bad. It should work after that.

P.S, don’t use “wait()”. Use “task.wait()” instead, it’s much more efficient.

1 Like

task.wait waits a shorter time but is not more efficient. Although wait is deprecated, it throttles, so if the game is slower, it will wait longer to save performance.

task.wait will wait a more accurate time but will not throttle. In OP’s case, task.wait is preferred.

1 Like