✓ Accepted answer
You are correct in thinking that the script you are using is a bit inefficient. Instead of copying the stone and script over and over again, it could just restore the originals! This script will do just that:
local hits = 0
local target = workspace.Mine.Stone
local targetParent = target.Parent
target.ClickDetector.MouseClick:connect(function(player)
hits = hits + 1
if hits < 3 then return end
target.Parent = nil
wait(3)
target.Parent = targetParent
hits = 0
end)
Notes:
- The script must be placed in ServerScriptService (I am assuming it is a regular Script, not a LocalScript.)
- Saying
if hits < 3 then return end is the same idea as if hits == 3 then, but avoids an extra indentation.
- You have to fill in the 'TODO Reward' line with whatever is appropriate
- This system is open to the abuse of one player trying to mine, getting 2 hits/clicks in, and then another player stealing the 3rd hit and claiming the reward. One method of addressing this (if you are even concerned about it) is to keep track of how many clicks/hits each player has performed separately (and resetting them all when anyone finishes mining the rock). Alternatively, script "who-ever hits it the most will get it so long as at least 3 hits have occurred".
- If the script errors on line 2 in Online mode (though I don't think it will), change it to
workspace:WaitForChild("Mine"):WaitForChild("Stone") - this assumes that both Mine and Stone exist.
Now, if you only have one rock in your entire place, this works fine. However, what if you want multiple rocks? Now, I don't know how you have your Mine folder/model set up. Say that you have lots of Stones in there, but also other stuff that shouldn't be mined. Then we can go through each child and attach the event to any of them that are named "Stone". Each one can have its own local variable hits so that they are kept separate.
local ch = workspace.Mine:GetChildren()
for i = 1, #ch do
if ch[i].Name == "Stone" then
local target = ch[i]
local hits = 0
target.ClickDetector.MouseClick:connect(function(player)
hits = hits + 1
if hits < 3 then return end
target.Parent = nil
wait(3)
target.Parent = targetParent
hits = 0
end)
end
end
Since we declare hits and target inside the for loop, the function that is connected to the MouseClick event will receive those local variables. Each Stone will have its own function that will have its own target/hits variables.
8 comments
Add a debounce?
There's already a debounce. "if hits == 3 then"
I'm confused. Does the stone instantly respawns? And do you need to fix that?
Okay. The stone respawns after 3 seconds. And when it respawns i think it does in workspace or just clones itself again into workspace.
Does this mean you have this script in every stone? You should probably put one script in ServerScriptService to handle all the stone and mineral respawning. It wouldn't be too difficult.
Agree with gold. This is done inefficiently. Also, this is not a debounce but you probably wouldn't need one. It makes one due to line 9. Does it make an extra one besides that one?
If you want to replace the stone after 3 seconds. It's better to make move it to storage then destroying. It takes less scripts.
Confusing.