I ran into an issue while using this module.Everything works fine until I implemented a few lines for the stun to work more well with my game.The problem basicly makes all players who ever been stunned stay stunned forever.
Can anyone maybe help with what’s the problem with my module.
Help is appreciated!
“CanAttack” is just a Bool Value thats located in a player character to determine if he or she is allowed to use a move.
local heartbeat = game:GetService("RunService").Heartbeat
local Stunned = {}
local clock = os.clock
local isChecking = false
local checkConnection
local currentTime
local stunnedHumanoids
local function stunChecker()
currentTime = clock()
stunnedHumanoids = 0
for humanoid, data in pairs(Stunned) do
if not data.stunned then continue end
if currentTime >= data.duration then
data.stunned = false
data.changedConn:Disconnect()
data.changedConn = nil
if humanoid:IsDescendantOf(workspace) then
humanoid.WalkSpeed = data.speed
humanoid.JumpPower = data.jumpPower
humanoid.JumpHeight = data.jumpHeight
--local CanAttack = humanoid.Parent.CanAttack
humanoid.Parent.CanAttack.Value = data.stunbool
humanoid.Parent:SetAttribute("Stunned", false)
end
end
stunnedHumanoids += 1
-- print(string.format("waiting: %f", data.duration - currentTime))
end
if stunnedHumanoids == 0 then
checkConnection:Disconnect()
isChecking = false
end
end
--//Stun Handler
return {Stun = function (humanoid, duration, CanAttack)
if humanoid.Health <= 0 then return end
if not Stunned[humanoid] then
Stunned[humanoid] = {}
end
local data = Stunned[humanoid]
currentTime = clock()
if not data.stunned then -- not stunned
data.stunned = true
data.duration = currentTime + duration
data.speed = humanoid.WalkSpeed
data.jumpPower = humanoid.JumpPower
data.jumpHeight = humanoid.JumpHeight
data.stunbool = humanoid.Parent.CanAttack.Value
humanoid.WalkSpeed = 0
humanoid.JumpPower = 0
humanoid.JumpHeight = 0
CanAttack.Value = false
humanoid.Parent:SetAttribute("Stunned", true)
elseif data.duration - currentTime < duration then -- update duration if less time left
data.duration = currentTime + duration
end
if not data.changedConn then
data.changedConn = humanoid.Changed:Connect(function()
humanoid.WalkSpeed = 0
humanoid.JumpPower = 0
humanoid.JumpHeight = 0
CanAttack.Value = false
end)
end
if not data.diedConn then
data.diedConn = humanoid.AncestryChanged:Connect(function()
data.diedConn:Disconnect()
if data.changedConn then data.changedConn:Disconnect() end
Stunned[humanoid] = nil
end)
end
if not isChecking then
isChecking = true
checkConnection = heartbeat:Connect(stunChecker)
end
end}
--local StunHandler = require(game.ReplicatedStorage.StunHandlerV2)
--StunHandler.Stun(hit.Parent.Humanoid, 10, hit.Parent.CanAttack)
Hey @YugaHinohara
I think its the CanAttack value which is being set after the stun duration is over. In the stunChecker function, where u have this code:
humanoid.Parent.CanAttack.Value = data.stunbool
This sets the CanAttack value to data.stunbool, which is the value of the CanAttack value at the time the stun was initiated. This means that even after the stun duration is over, the CanAttack value is still being set to false (or whatever value it had when the stun was initiated), which is why all players who have ever been stunned are staying stunned forever.
To fix this issue, you can modify the data table to include the original value of the CanAttack value, like this:
if not Stunned[humanoid] then
Stunned[humanoid] = {
stunbool = humanoid.Parent.CanAttack.Value,
}
end
Then, in the stunChecker function, you can set the CanAttack value to the original value when the stun duration is over, like this:
humanoid.Parent.CanAttack.Value = data.stunbool
This should fix the issue and allow players to become unstunned after the stun duration is over.
Hope it helped, or made sense
Sincerely Delusively
It works perfectly fine and everything until today when I was just messing around in my game and the stun issue happened again.Same issue where I checked the Console and see no error from the module script.Though what I know is that the attribute named “Stunned” is gone from humanoid and yet all the properties of stun still remain active.
Seems like this bug happens at random time and I cant seem to trigger this bug at will.
It’s possible that there is some code or interaction in your game that is causing the “Stunned” attribute to be removed from the humanoid. If this attribute is being used by your stun module to determine whether a humanoid is currently stunned, then that could explain why the stun properties remain active even though the attribute is gone.
One way to investigate this issue would be to add some additional logging to your stun module to help you identify when the attribute is being removed, and what might be causing it. For example, you could add a print statement inside the stunChecker function to log the state of each stunned humanoid and whether or not it has the “Stunned” attribute. This might help you identify when the attribute is being removed and potentially narrow down the cause of the issue.
Another possibility is that there is some kind of race condition or synchronization issue in your code that is causing the stun module to get out of sync with the state of the game. If this is the case, it might be helpful to review your code and make sure that all relevant events and data are being properly synchronized and updated in a consistent and reliable manner.
I found the source of the problem on complete accident and manage to track it down but still is clueless to why the attribute is still staying the same.
How my iframe works in my game is that I create a Force Field and named it “Iframes”
Every time when I activate Iframes and use a skill that stuns myself it will make me stun forever.
(The red aura is the iframes activated)
Video showing the issue
Also sorry for the extremely insanely late reply since I was busy with personal stuff in my life.
-- StunHandlerV2.lua
local StunHandlerV2 = {}
local Debris = game:GetService("Debris")
-- Table to keep track of players that are stunned and their stun durations
local stunnedPlayers = {}
-- Function to stun the humanoid for a given duration
function StunHandlerV2.Stun(humanoid, duration)
-- Validate input
if not humanoid or not humanoid:IsA("Humanoid") then
warn("Invalid humanoid provided.")
return
end
local character = humanoid.Parent
local stunnedValue = character:FindFirstChild("Stunned") or Instance.new("BoolValue", character)
-- Only create the BoolValue if it doesn't exist
if not character:FindFirstChild("Stunned") then
stunnedValue.Name = "Stunned"
end
-- If the humanoid is already stunned, update the stun duration
if stunnedPlayers[humanoid] then
-- Update the stun duration to the latest one
stunnedPlayers[humanoid].endTime = tick() + duration
return
end
-- Set the Stunned BoolValue to true and add the humanoid to the stunnedPlayers table
stunnedValue.Value = true
stunnedPlayers[humanoid] = {
endTime = tick() + duration, -- Store the time when stun should end
stunBillboard = script.StunnedBillBoard:Clone() -- Store the stun billboard for cleanup
}
-- Parent the stun billboard to the humanoid's head
local stun = stunnedPlayers[humanoid].stunBillboard
stun.Parent = humanoid.Parent.Head
Debris:AddItem(stun, duration) -- Automatically remove after duration
-- Disable the humanoid's abilities
humanoid.WalkSpeed = 0
humanoid.JumpPower = 0 -- Set jump height to 0
humanoid.JumpHeight = 0
-- Connection to handle humanoid death
local diedConnection
diedConnection = humanoid.Died:Connect(function()
-- Clean up stun state on death
stunnedValue.Value = false
stunnedPlayers[humanoid] = nil
-- Clean up the connection to prevent memory leaks
diedConnection:Disconnect()
end)
-- Stun handler loop to manage the duration and keep updating
task.spawn(function()
while stunnedPlayers[humanoid] and tick() < stunnedPlayers[humanoid].endTime do
task.wait(0.1) -- Small wait to avoid tight looping
end
-- Ensure humanoid is still valid before re-enabling abilities
if humanoid and humanoid.Parent then
humanoid.WalkSpeed = 16 -- Default walk speed
humanoid.JumpPower = 50 -- Default jump power
humanoid.JumpHeight = 7.2 -- Default jump height
end
-- Set the Stunned BoolValue to false and remove from stunned players
stunnedValue.Value = false
stunnedPlayers[humanoid] = nil
-- Clean up the connection if it wasn't triggered
if diedConnection then
diedConnection:Disconnect()
end
end)
end
return StunHandlerV2
CREDITS TO CHATGPT LOL
Like I tried a lot of different methods, first only being replacing os.clock as It was accurate etc.
I moved module into the Server Script Service, etc etc
In the end I got fed up and just relied to ChatGPT to just make a whole new stun module.
The bool value named “Stunned” in my player character is the indicated whether if I could use any moves depending on the value. If true then it means I am stunned thus I can’t use any move. And the Billboard is a indicator of being stunned. So it can be removed, its not really needed.
Love the fact I replied and solved my own problem after like almost an year.