Im making a shield script that gets destroyed and stuns the player when the shields health becomes 0. Im using code that changes the baseplates color as a placeholder before writing the actual stun function. The function is inside a ModuleScript, my problem is when the function is fired, instead of waiting the set amount of time, it’ll skip the wait.
Script:
while wait() do
if Health.Value <= 0 then -- If shields health reaches 0
Health.Value = 0
---- Destroy Shield ----
ShieldClone:Destroy()
ShieldWeld:Destroy()
ShieldGyro:Destroy()
ShieldAnim:Stop()
hum.AutoRotate = true
--- Stun Player ---
local stun = require(game.ServerScriptService.StatusEffectIndex)
local stuntime = 10
stun.Stun(stuntime)
break
end
ModuleScript:
local StatusEffects = {}
function StatusEffects.Stun(stuntime)
print("stunned")
workspace.BasePlates.Baseplate.BrickColor = BrickColor.new("Baby blue")
wait(stuntime)
workspace.BasePlates.Baseplate.BrickColor = BrickColor.new("Really red")
end
return StatusEffects
Video:
As you can see in the video, when the shield is broken(dissapears) the baseplate doesn’t become blue before becoming red. How do I make the ModuleScript wait the given time?
Is there any particular reason why the variable stuntime is an argument passed through the the stun function instead of being declared in the module script? If you change that it could work in your favor.
Also the baseplate is turning blue, but only for maybe a frame or two. I think the variable being passed through the stun function isn’t properly getting through, so maybe print(stuntime) would help debug the code you have.
Arbitrary stun times. You could be having several actions in your game which require the stun function but need it to occur for different lengths of time. It makes more sense to have an outside script tell the function how much time the action should last for instead of making it a declaration in the ModuleScript because that’ll cause all stuns to uniformly wait n seconds.
That being said, I don’t why why this isn’t in the form of a class in that case. They’re far more versatile in this kind of scenario.
An example:
local StatusEffects = {}
StatusEffects.__index = StatusEffects
StatusEffects.StunDuration = 10 -- a default value
function StatusEffects:Stun()
print("stunned")
workspace.BasePlates.Baseplate.BrickColor = BrickColor.new("Baby blue")
wait(self.StunDuration)
workspace.BasePlates.Baseplate.BrickColor = BrickColor.new("Really red")
end
end
function StatusEffects.new(stunDuration)
local self = {}
if stunDuration then self.StunDuration = stunDuration end -- To account for no input.
return setmetatable(self, StatusEffects)
end
Then in the script calling this function:
local StatusEffects = require(game.ServerScriptService.StatusEffectIndex).new(10) -- duration of the stun
-- later on
StatusEffects:Stun()
This is by no means a perfect solution but it gets on the right track.
EDIT: I have been told that this is over the top, and after looking at it, I can see why. Thanks for pointing that out
Is there anything else that could be potentially setting the color of the baseplate?
Also, I’m not sure that it’s a good idea to call the function with a loop like this. I’ve seen a few people have issues with it because it sometimes calls the intended functions more than once. Double check to make sure that the function isn’t called more than once.
It’s over the top to be using OOP here. This is a simple stun script. OOP is good for requiring object state and that’s not what’s happening here. Object state isn’t being stored, so there’s no need to have a class here. That’s treading into overengineering grounds.
Really the issue to be tackling here is the wait part.
I don’t think the issue is the wait at this point, the variable is passed successfully, and I can’t see the wait() function failing like this. I suspect that something is up with other parts of the code.
The loop does seem to be the problem because when I call the function outside of the loop the problem doesn’t occur, but the condition inside the loop have to be met in order to stun the player. Is there a way to make sure these conditions are met without using the loop?
So the function works properly without the loop, that’s the issue then. You can use the Changed event to detect any changes.
Here’s an example
local StunModule = require(game.ServerScriptService.StatusEffectIndex)
local stuntime = 10 -- good practice to keep this at the top if they don't change much.
-- code to register shield, I don't know OP's code, so he can handle this.
local connection; connection = Health.Changed:Connect(function(newHealth)
if newHealth <= 0 then
connection:Disconnect()
-- Code to handle shield destruction
ShieldClone:Destroy()
ShieldWeld:Destroy()
ShieldGyro:Destroy()
ShieldAnim:Stop()
hum.AutoRotate = true
StunModule.Stun(stuntime)
end
end)
So I tried printing “stuntime” in the ModuleScript again and its printing nil which is strange because I couldv’e swore it wasn’t before. My bad for the false information