Thank you for using proper indentation of the code, that is really good to see.
Though there are some general logical and technical issues with the code you have posted.
1) You are using the local variable TaggedPart
for both; the table of tagged parts, and the single part.
Normally it is best to distinguish what “a variable” contain, so perhaps in this case they could be named TaggedParts
and TaggedPart
.
2) There should be no reason to use a coroutine
for this. - I suppose it is due to the debounce db
local variable, but that could be just as easily be a… local variable within the scope of the for
-loop’s body:
for _,obj in ipairs(objs) do
local db = false -- <<
obj.Touched:Connect(function(hit)
if not db then
db = true
-- ...
db = false
end
end
end
3) You should keep of creating objects, until they are actually needed. Here I think of the creations for tweenOn
and tweenOff
.
Unless you need to have thousands of Tween-objects that are extremely frequently used, there are no (or very few) reasons for pre-creating and -caching such objects.
4) The usage of script.Disabled
is wrong here, and does not do what you think it should do. - Actually I don’t even know what happens with that kind of usage, specially when in a Touched
signal-handler.
That script.Disabled
may be the most problematic thing in your code.
Maybe the above does not give you enough information or hints, so I have created an alternative implementation of the code you posted.
The below code uses a functionality of the Tween
-object, the Completed
event, which will “fire” once the tween has finished. This I would say is better to use, than having an explicit wait(..)
after starting a Tween
.
The alternative implementation also uses more functions, to better illustrate (or categorize) what happens where in the code.
-- Alternative implementation
local CollectionService = game:GetService("CollectionService")
local TweenService = game:GetService("TweenService")
local Players = game:GetService("Players")
--
local debounceGems = {} -- Dictionary of gem-objects that are currently in 'debounce'
--
local function GemHideThenReappear(gem)
gem.Position = Vector3.new(-195.806, 1.322, -189.686)
wait(5)
-- Reappear
local pos1 = math.random(-240.806, -65)
local pos2 = math.random(1.322, 1.322)
local pos3 = math.random(-233.686, -59)
gem.Position = Vector3.new(pos1,pos2,pos3)
gem.Sparkles.Enabled = true
local tween = TweenService:Create(gem, TweenInfo.new(0.5), { Transparency = 0 } )
-- Once tween has completed, then un-debounce the object
tween.Completed:Connect(function()
debounceGems[gem] = nil
end)
tween:Play()
end
--
local function GemTouched(gem, hit)
if not debounceGems[gem] then
local player = Players:GetPlayerFromCharacter(hit.Parent)
if player ~= nil then
-- Set debounce for only this particular object
debounceGems[gem] = true
player.leaderstats.Gems.Value = player.leaderstats.Gems.Value + 1
gem.GemsSound:Play()
gem.Sparkles.Enabled = false
local tween = TweenService:Create(gem, TweenInfo.new(0.5), { Transparency = 1 } )
-- Once tween has completed, then hide the object
tween.Completed:Connect(function()
GemHideThenReappear(gem)
end)
tween:Play()
end
end
end
--
for _,gem in ipairs(CollectionService:GetTagged("Gems")) do
gem.Touched:Connect(function(hit)
-- Need to supply the `GemTouched`-function with what `gem`-object that is actually being touched
GemTouched(gem, hit)
end)
end