Hello again robloxians!
Well, so i’m making a game where you can use swords to defeat enemys and gain more gold, i’m having a problem with my rewarding script, when the players kills an enemy, it not stops rewarding the player until the enemy respawns.
Here is my script fellas!
local PlayerService = game:GetService("Players")
local Tool = script.Parent.Parent
local Handle = Tool:WaitForChild("Handle")
local SwordStatus = script.Parent:WaitForChild("SwordStatus")
local StatusModule = require(SwordStatus)
Handle.Touched:Connect(function(Hit)
local Humanoid = Hit.Parent:WaitForChild(StatusModule.HumanoidToDamage)
local Player = PlayerService:GetPlayerFromCharacter(Tool.Parent)
Humanoid.Died:Connect(function()
Player.GoldCurrency.Value = Player.GoldCurrency.Value + 100
end)
end)
AQ
1. Why you don’t use a tag system?
Well, i prefer already use a reward system into my sword, it looks more practical than using a tag system.
2. Did you tried using the reward system in the enemy?
Actually, the unique way i thinked for that was using a tag system. So the first question answers the second question.
3. Did you looked into youtube or in devforum?
I didn’t saw someone with the same problem as me in the devforum. While in youtube, major of the videos uses the tag system, or uses a reward system inside the own currency script, some don’t even explain the vídeo and just put a toolbox kill 4 cash in the video. So YouTube ins’t a option.
I think that if the player dies, and the sword touching the humanoid after it dies, they get gold because if the player dies, it will always check if the player died or not, but its recommended to use a tag system to prevent multiple or duplicated gold currency.
So when the enemy dies, you get more gold than usual? That’s probably because you are creating more Humanoid.Died connections every single time you hit the enemy. Why don’t you just use an if statement checking if the enemy is dead after they get hit?
local PlayerService = game:GetService("Players")
local Tool = script.Parent.Parent
local Handle = Tool:WaitForChild("Handle")
local SwordStatus = script.Parent:WaitForChild("SwordStatus")
local StatusModule = require(SwordStatus)
Handle.Touched:Connect(function(Hit)
if(Humanoid.Health <= 0) then --Don't run the script if the enemy is already dead
return
end
local Humanoid = Hit.Parent:WaitForChild(StatusModule.HumanoidToDamage)
local Player = PlayerService:GetPlayerFromCharacter(Tool.Parent)
if(Humanoid.Health <= 0) then
Player.GoldCurrency.Value = Player.GoldCurrency.Value + 100
end
end)
Actually, the script is for killing an NPC/Enemy, and Humanoid.Died don’t works only once? if not, then could i create a bool value inside the enemy and use a if Humanoid.Health <= 0 then do deactivate that bool value?
Yes, it was to reward only 10 (sorry to put in the script 100, but it was just a test) gold, but when the enemy dies, it rewards 10k, it just don’t rewards more cause i used math.clamp to prevent negative values in the currency.
Add a debounce variable that starts as false. If the debounce is false when the enemy dies, set the debounce to true, run the rest of the script, and only set it to false when the enemy respawns (using the CharacterAdded function)
local PlayerService = game:GetService("Players")
local Tool = script.Parent.Parent
local Handle = Tool:WaitForChild("Handle")
local SwordStatus = script.Parent:WaitForChild("SwordStatus")
local StatusModule = require(SwordStatus)
local debounce = false
Handle.Touched:Connect(function(Hit)
local Humanoid = Hit.Parent:WaitForChild(StatusModule.HumanoidToDamage)
local Player = PlayerService:GetPlayerFromCharacter(Tool.Parent)
Humanoid.Died:Connect(function()
if debounce then
return
else
debounce = true
Player.GoldCurrency.Value = Player.GoldCurrency.Value + 100
end
PlayerService:GetPlayerFromCharacter(Humanoid.Parent).CharacterAdded:Connect(function()
debounce = false
end)
end)
end)
Reminding you that Part.Touched fires for every part it touches, including the arm, the torso, the head, the accessories, etc. While I wouldn’t recommend allowing the sword to manage the rewards (since it’s only meant to damage enemies), I’ll still provide my answer.
Keep a reference of the humanoid it finds from the part it touches, and if the sword detects a humanoid, check if it is already referenced:
local PlayerService = game:GetService("Players")
local Tool = script.Parent.Parent
local Handle = Tool:WaitForChild("Handle")
local SwordStatus = script.Parent:WaitForChild("SwordStatus")
local StatusModule = require(SwordStatus)
local EnemyHumanoids = {}
Handle.Touched:Connect(function(Hit)
local Humanoid = Hit.Parent:WaitForChild(StatusModule.HumanoidToDamage)
if (EnemyHumanoids[Humanoid] == true) then
-- If it finds a humanoid inside this table, ignore it.
return
elseif Humanoid:GetState(Enum.HumanoidStateType.Dead) then
-- Don't do anything to a dead humanoid.
return
end
EnemyHumanoids[Humanoid] = true -- Reference the humanoid.
local Player = PlayerService:GetPlayerFromCharacter(Tool.Parent)
-- Use Once instead of Connect to only listen to the event just once.
Humanoid.Died:Once(function()
Player.GoldCurrency.Value = Player.GoldCurrency.Value + 100
EnemyHumanoids[Humanoid] = false -- Deference the humanoid since it is dead.
end)
end)