My stun module doesnt work when used first time

This is a support category for asking questions about how to get something done on the Roblox websites or how to do something on Roblox applications such as Roblox Studio.

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!
    I want to make this module work when i require and activate it stuns perfectly.

  2. What is the issue? Include screenshots / videos if possible!
    the issue is sometimes the stun doesnt stop the enemy from moving and getting stunned for the first time doesnt make me stop moving for some reason.

local RunService = game:GetService("RunService")

local stunnedHumanoids = {}
local currDur = {}
local prevTime = {}

local prevWalkSpeed = {}
local prevJumpPower = {}

local displayTime = false

local stun = {}

function stun.Stun(humanoid, stunDuration)
	-- Ensure the humanoid and parent are valid
	if not humanoid or not humanoid.Parent then
		print("Invalid humanoid or parent.")
		return
	end
	local parent = humanoid.Parent

	-- Cancel if invulnerable (Iframes, Parrying, or FParrying)
	if parent:GetAttribute("Iframes") or parent:GetAttribute("Parrying") or parent:GetAttribute("FParrying") then
		print("Humanoid is invulnerable. Stun skipped.")
		return
	end

	-- Check if the humanoid is already stunned
	if not table.find(stunnedHumanoids, humanoid) then
		-- Add humanoid to stunned list
		table.insert(stunnedHumanoids, humanoid)
		prevTime[humanoid] = os.clock()
		currDur[humanoid] = stunDuration

		-- Only apply movement stun if not blocking or parrying
		if not parent:GetAttribute("Blocking") and not parent:GetAttribute("Parrying") then
			-- Wait a frame to ensure humanoid is initialized (fix race condition)
			task.wait()

			-- Store previous movement settings
			prevWalkSpeed[humanoid] = humanoid.WalkSpeed
			prevJumpPower[humanoid] = humanoid.JumpPower

			-- Apply stun (zero walk speed and jump power)
			humanoid.WalkSpeed = 0
			humanoid.JumpPower = 0

			-- Set the "Stunned" attribute on the parent
			parent:SetAttribute("Stunned", true)

			-- Create a Highlight effect on the humanoid
			local HL = Instance.new("Highlight")
			HL.Name = "StunHighLight"
			HL.Parent = parent
			HL.OutlineColor = Color3.fromRGB(255, 0, 0)
			HL.OutlineTransparency = 0
			HL.FillTransparency = 1
			HL.DepthMode = Enum.HighlightDepthMode.Occluded
			print("Highlight applied to humanoid.")
		end

		-- Start the heartbeat loop to track the stun duration
		local connection
		connection = RunService.Heartbeat:Connect(function()
			-- If humanoid or parent no longer exists, disconnect heartbeat
			if not humanoid or not humanoid.Parent then
				if connection then
					connection:Disconnect()
				end
				return
			end

			-- Calculate elapsed time
			local elapsed = os.clock() - prevTime[humanoid]
			if displayTime then
				print(string.format("Stun time: %.2f seconds", elapsed))
			end

			-- If stun duration has elapsed, remove the stun
			if elapsed >= currDur[humanoid] then
				-- Remove from stunned table
				for i = #stunnedHumanoids, 1, -1 do
					if stunnedHumanoids[i] == humanoid then
						table.remove(stunnedHumanoids, i)
						break
					end
				end

				-- Restore movement settings if not blocking
				if parent and not parent:GetAttribute("Blocking") then
					parent:SetAttribute("Stunned", false)

					-- Restore original walk speed and jump power
					humanoid.WalkSpeed = prevWalkSpeed[humanoid] or 16
					humanoid.JumpPower = prevJumpPower[humanoid] or 50

					-- Remove the Highlight effect
					local HL = parent:FindFirstChild("StunHighLight")
					if HL then
						HL:Destroy()
						print("Highlight removed from humanoid.")
					end
				end

				-- Clear stored memory for the stunned humanoid
				prevWalkSpeed[humanoid] = nil
				prevJumpPower[humanoid] = nil
				prevTime[humanoid] = nil
				currDur[humanoid] = nil

				-- Disconnect heartbeat connection when stun duration ends
				if connection then
					connection:Disconnect()
					print("Heartbeat connection disconnected.")
				end
			end
		end)
	else
		-- If already stunned, refresh the timer
		prevTime[humanoid] = os.clock()
		currDur[humanoid] = stunDuration
		print("Humanoid already stunned. Timer refreshed.")
	end
end

return stun

as you can see when i get hit for the first time i can still move (when i get a red highlight is means im stunned) and after that when i get hit again it works.
also sometimes stun doesnt stop enemy from moving.

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    No i didnt. because this module is a stun module i made my self so it most likely wont be in the developer hub.

first problem is from im testing my self when i get hit by attack dummy for the first time stun always doesnt work i am not sure if it still just doesnt load for the first time or its a problem, second problem is when i test with my friend sometimes when im doing a combo it didnt stun and let enemy moves, and sometimes player cant move at all. i am thankful it if someone responds.

1 Like

Sorry after checking my other script (and adding debugs to it) i found the case that my module is working. the problem is the sprint script. for some reason it updates walkspeed to 16 when i get stunned.

local player = game.Players.LocalPlayer

local function effectrun(Input)
	local char = player.Character or player.CharacterAdded:Wait()

	local bodyParts = {
		char:FindFirstChild("Left Arm"),
		char:FindFirstChild("Left Leg"),
		char:FindFirstChild("Right Arm"),
		char:FindFirstChild("Right Leg")
	}

	if Input then
		-- Enable trail effect when sprinting
		for _, part in pairs(bodyParts) do
			if part then
				task.spawn(function()
					-- Check if a TrailPart already exists
					if not part:FindFirstChild("TrailPart") then
						local trailPart = script.TrailPart
						local trail = trailPart.Trail:Clone()
						trail.Parent = part
						trail.Trail.Enabled = true
					end
				end)
			end
		end
	else
		-- Disable and clean up trail effect
		for _, part in pairs(bodyParts) do
			if part then
					local trail = part:FindFirstChild("Trail")
					if trail then
						trail.Trail.Enabled = false -- Disable the trail effect
					
					-- Delay to ensure the effect is disabled, then clean up
					task.delay(0.5, function()
						trail:Destroy()
						
					end)
					end
				end
			end
		end
	end


-- Function to initialize the character and setup everything
local function initializeCharacter(character)
	-- Wait for the Humanoid to load
	local humanoid = character:WaitForChild("Humanoid")

	-- Replace these with your actual animation IDs
	local walkAnimationId = "rbxassetid://122436479354098"
	local runAnimationId = "rbxassetid://106139534273641"

	-- Load animations
	local walkAnimation = Instance.new("Animation")
	walkAnimation.AnimationId = walkAnimationId
	local walkTrack = humanoid:LoadAnimation(walkAnimation)
	walkTrack.Priority = Enum.AnimationPriority.Movement

	local runAnimation = Instance.new("Animation")
	runAnimation.AnimationId = runAnimationId
	local runTrack = humanoid:LoadAnimation(runAnimation)
	runTrack.Priority = Enum.AnimationPriority.Movement

	-- Function to update the WalkSpeed and play animations
	local function updateWalkSpeed()
		local combatTag = character:GetAttribute("CombatTag")
		local weapon = character:FindFirstChild("Weapon")
		local weaponSummoned = weapon and weapon:FindFirstChild("Summoned")

		-- Check conditions for WalkSpeed
		if (combatTag == true) or (weapon and weaponSummoned and weaponSummoned.Value == true)
			and not character:GetAttribute("Stunned",true) then
			humanoid.WalkSpeed = 16
			print("setted walkspeed to 16")
			effectrun(false) -- Stop the sprint trail when WalkSpeed is 16 or lower
		else
			humanoid.WalkSpeed = 26
		end
	end

	-- Function to check movement and update animations
	local function updateAnimations()
		-- Check if the humanoid is moving
		local isMoving = humanoid.MoveDirection.Magnitude > 0
		local isWalking = humanoid.WalkSpeed > 0

		if isMoving and isWalking then
			if humanoid.WalkSpeed > 16 then
				-- Play run animation if WalkSpeed is greater than 16
				if not runTrack.IsPlaying then
					walkTrack:Stop()
					runTrack:Play()
					effectrun(true) -- Enable sprint trail for running
				end
			else
				-- Play walk animation if WalkSpeed is 16 or lower
				if not walkTrack.IsPlaying then
					runTrack:Stop()
					walkTrack:Play()
					effectrun(false) -- Disable sprint trail for walking
				end
			end
		else
			-- Stop both animations and disable sprint trail if the character is not moving
			runTrack:Stop()
			walkTrack:Stop()
			effectrun(false)
		end

		-- Adjust animation speed if the character is in the air
		if humanoid:GetState() == Enum.HumanoidStateType.Jumping or humanoid:GetState() == Enum.HumanoidStateType.Freefall then
			walkTrack:AdjustSpeed(0.25)
			runTrack:AdjustSpeed(0.25)
		else
			walkTrack:AdjustSpeed(1)
			runTrack:AdjustSpeed(1)
		end
	end

	-- Connect to CombatTag changes
	character.AttributeChanged:Connect(function(attributeName)
		if attributeName == "CombatTag" then
			updateWalkSpeed()
		end
	end)

	-- Connect to Weapon.Summoned changes (if weapon exists)
	local function monitorWeapon()
		local weapon = character:FindFirstChild("Weapon")
		if weapon then
			local weaponSummoned = weapon:FindFirstChild("Summoned")
			if weaponSummoned then
				weaponSummoned:GetPropertyChangedSignal("Value"):Connect(function()
					updateWalkSpeed()
				end)
			end
		end
	end

	-- Monitor for new weapons being added to the character
	character.ChildAdded:Connect(function(child)
		if child.Name == "Weapon" then
			monitorWeapon()
			updateWalkSpeed()
		end
	end)

	-- Monitor for weapons being removed
	character.ChildRemoved:Connect(function(child)
		if child.Name == "Weapon" then
			updateWalkSpeed()
		end
	end)

	-- Listen to the Humanoid's state and update animations
	humanoid.Running:Connect(function(speed)
		updateAnimations() -- Update animations on running state
	end)

	-- Listen to the Movement direction and update animations
	game:GetService("RunService").Heartbeat:Connect(function()
		updateAnimations() -- Continuously check movement direction
	end)

	-- Initial setup
	monitorWeapon()
	updateWalkSpeed()
	updateAnimations() -- Ensure animations are set when the game starts
end

-- Listen for CharacterAdded to initialize the script for new characters
player.CharacterAdded:Connect(initializeCharacter)

-- Initialize for the current character (if it already exists)
if player.Character then
	initializeCharacter(player.Character)
end

Sorry if i wasted anyone’s time. i have fixed the sprint script and i just needed to add a return to end if stunned.

if character:GetAttribute("Stunned") then return end

thank you.

1 Like