Since I’d like to reward players upon mining an ore, I wish to implement a currency granting segment. However, I’m currently facing an issue in regards to how many times it runs. Currently, due to the amount of parts in the model, it’s repeating a code 15 times and I don’t wish to keep it that way. I’ve tried adding a debounce, but this didn’t work unfortunately. Below you’ll find the script responsible for this. Any help would be appreciated!
OreTouchedEvent.OnServerEvent:Connect(function(player, Ore)
local char = player.Character
local hum = char:FindFirstChildOfClass("Humanoid")
if not debounce then
if hum then
local pickaxe = char:FindFirstChild("Pickaxe")
if pickaxe then
for _, v in(Ore:GetChildren()) do
if v:IsA("BasePart") and v.Name ~= "Hitbox" then
v.Transparency += 0.25
if v.Transparency == 1 then
if Ore.Name == "Rock" then
print("rock!")
elseif Ore.Name == "IronOre" then
print("iron!")
end
end
end
end
debounce = true
task.wait(3)
debounce = false
end
end
end
end)
The thing is that .Touched events fire for every part that touches them, so here it would run 15 times. It is better to put the debounce on the server anyway, is there any way you can send your code on the server side so we can take a look please?
I’ll put the code here, so if there’s an issue with my localscript, it can be found.
local Rock = script.Parent
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Hitbox = script.Parent:WaitForChild("Hitbox")
local replicatedStorage = game:GetService("ReplicatedStorage")
local OreTouchedEvent = replicatedStorage.OreTouchedEvent
local Character = Player.Character or Player.CharacterAdded:Wait()
local Pickaxe = Character:WaitForChild("Pickaxe")
local Handle = Pickaxe:WaitForChild("Handle")
local Count = 0
Hitbox.Touched:Connect(function(player)
local function Check()
if Handle:GetAttribute("IsActivated") == true then
Count += 1
local Cast = workspace:Raycast(Handle.Position, Handle.CFrame.LookVector * 2)
if Cast then
if Cast.Instance.Name ~= Rock.Name then return end
else
return
end
end
end
repeat task.wait(1) Check() until Count == 5
OreTouchedEvent:FireServer(Rock)
Count = 0
end)
I’ve tried doing so, and it still runs the code 15 times.
if v.Transparency == 1 and not debounce2 then
debounce2 = true
if Ore.Name == "Rock" then
print("rock!")
elseif Ore.Name == "IronOre" then
print("iron!")
debounce2 = false
Debounce should be true immediately after the check for if it is false, otherwise in the time it takes to run the function, the remote event can be fired many times and start running. This will cause multiple print outs. Try that and see if it helps.
I’ve tried doing this, however, the code still runs 15 times…
if v.Transparency == 1 and not debounce2 then
debounce2 = true
if Ore.Name == "Rock" then
print("rock!")
elseif Ore.Name == "IronOre" then
print("iron!")
debounce2 = false
What I’d do is: check if anything is touching the players pickaxe on client → fire event to server and complete a sanity check which checks if the players pickaxe is actually touching an ore → if the sanity check if passed then reward the player.
You removed the task.wait() before setting the debounce to false.
Also you should put the debounce in your localscript so you save memory by not firing the event 15 times.
If you want to keep the debounce on the server, then make it a table and give every player a boolean like this:
local devounce = {}
debounce[player.UserId] = false
Make sure to delete set it to nil when the player leaves. Only do this if you want multiple people to be able to toch ores at the same time.
Oh, it wasn’t deleted, I just made a new debounce variable as the first one is being used to ensure the ore doesn’t disappear instantly. I wish to somehow make it so that the code snippet is only ran once instead of 15 times over.
You could use a RemoteFunction that returns once finished instead of a RemoteEvent and put the debounce in your LocalScript. Before you’d call the RemoteFunction set the debounce to true, then after the RemoteFunction set it back to false. And ofcourse you’d check if the debounce is false before doing all of this.
Sorry if I’m not being very clear or don’t format my text nicely, it’s late and I’m on my phone.
local hitBox -- put your hotbox here
hitbox.Touched:Connect(function(hit)
if hit.Name == "Ore" then
mineOre:FireServer(hit)
end
end)
and this on server:
mineOre.OnServerEvent:Connect(function(player, ore)
local character = player.Character
if not character then
return
end
local pickaxe = character:FindFirstChild("Pickaxe")
if pickaxe then
local hitbox = pickaxe:FindFirstChild("Hitbox")
if hitbox then
if table.find(hitbox:GetTouchingParts(), ore) then
print("Reward player")
end
end
end
end)
local Idkwhattocallthisboolvalue = true --You can change the name of this--
OreTouchedEvent.OnServerEvent:Connect(function(player, Ore)
local char = player.Character
local hum = char:FindFirstChildOfClass("Humanoid")
if not debounce then
if hum then
local pickaxe = char:FindFirstChild("Pickaxe")
if pickaxe then
for _, v in(Ore:GetChildren()) do
if v:IsA("BasePart") and v.Name ~= "Hitbox" and Idkwhattocallthisboolvalue then
v.Transparency += 0.25
if v.Transparency == 1 then
if Ore.Name == "Rock" then
print("rock!")
Idkwhattocallthisboolvalue = false
elseif Ore.Name == "IronOre" then
print("iron!")
Idkwhattocallthisboolvalue = false
end
end
end
end
debounce = true
task.wait(3)
debounce = false
end
end
end
end)
Apologies for not getting back until a day later, but where exactly would I put the debounce within the localscript? This is my first time using a remote function, and I’m rather new at setting a debounce.
local debounce = {}
OreTouchedEvent.OnServerEvent:Connect(function(player, Ore)
local char = player.Character
local hum = char:FindFirstChildOfClass("Humanoid")
if not debounce[Ore] then
debounce[Ore] = true
if hum then
local pickaxe = char:FindFirstChild("Pickaxe")
if pickaxe then
local fullyTransparent = true
for _, v in pairs(Ore:GetChildren()) do
if v:IsA("BasePart") and v.Name ~= "Hitbox" then
v.Transparency += 0.25
if v.Transparency < 1 then
fullyTransparent = false
end
end
end
if fullyTransparent then
if Ore.Name == "Rock" then
print("rock!")
elseif Ore.Name == "IronOre" then
print("iron!")
end
end
end
end
task.wait(3)
debounce[Ore] = false
end
end)