I recently ran into an issue when regening a model. So i have chests in my game that the player can gather and a server script that inputs a gui into the players gui that states how much gold is earned and plays a sound. I’ve accomplished this by grouping the chests into one model and whenever a MeshPart(The Chests) are touched the script activates. The problem is I’ve placed a regen script in the model to regen the chests every 600 seconds. The problem is after the model is regened the GUI doesn’t pop up and the sound doesn’t play. Here is an example of this. RegenExample.wmv (2.1 MB)
Here are both of the scripts, the first is the Sound&Gui Script and the second is regen script that I have in the model
local model = workspace.Chests:GetChildren()
debounce = false
for _, part in pairs(model) do
if part:IsA("MeshPart") then
part.Touched:Connect(function(hit)
if hit.Parent:FindFirstChild("Humanoid") then
local player = game.Players:GetPlayerFromCharacter(hit.Parent)
local sound = game.ReplicatedStorage.Sounds.Chest:clone()
local gui = game.ReplicatedStorage.Gui.Gold:clone()
sound.Parent = player.PlayerGui
gui.Parent = player.PlayerGui
sound:Play()
wait(3)--change to how long before the sound plays again after retouching it
local gui = player.PlayerGui:WaitForChild("Gold"):Destroy()
end
debounce = false
end)
end
end
object = script.Parent
if (object ~= nil) and (object ~= game.Workspace) then
model = object
backup = model:clone()
waitTime =600
wait(math.random(0, waitTime))
while true do
wait(waitTime)
model:remove()
wait(0)
model = backup:clone()
model.Parent = game.Workspace
model:makeJoints()
end
end
I’ve tried changing altering the regen script and making it regen just the chests in the model rather than the whole model but I still ran into the same problem. Any help would be appreciated. Thanks!
You’re using a Touched connection on the first instances of the chests. This connection is destroyed when you are cloning the model because the connections only apply to the specific instances you connected them to.
This is why your Touched function does not work (the chests they are connected to are technically destroyed when they are regened).
Iterate through the backup (like you did with pairs() initially) in your second script again to give it the same function with Touched before you parent backup:Clone() to workspace.
Additional notes:
1.) Your debounce doesn’t appear to be being used properly (it only ever sets to false and is never used as a stopping condition)
2.) :Remove() is deprecated, use :Destroy() instead
3.) Rather than cloning the GUI to the player repeatedly, I would have a single copy of the GUI in the player (put the GUI in StarterGui), then just use RemoteEvents. Get the server to tell the client to make the GUI visible etc, then play the sound. Then you only ever need one copy of the GUI and don’t have to keep replicating it to the client for each chest touch.
4.) You never delete the cloned Chest and GUI after parenting them to the PlayerGui
This is a band-aid fix to illustrate the point.
(Sorry for the slow typing! Mobile DevForum is a pain).
object = script.Parent
local debounce = false
if (object ~= nil) and (object ~= game.Workspace) then
model = object
backup = model:clone()
waitTime =600
wait(math.random(0, waitTime))
while true do
wait(waitTime)
model:Destroy()
wait(0)
model = backup:clone()
debounce = false
for _, part in pairs(model) do
if part:IsA("MeshPart") then
part.Touched:Connect(function(hit)
if hit.Parent:FindFirstChild("Humanoid") and debounce == false then
debounce = true
local player = game.Players:GetPlayerFromCharacter(hit.Parent)
local sound = game.ReplicatedStorage.Sounds.Chest:clone()
local gui = game.ReplicatedStorage.Gui.Gold:clone()
sound.Parent = player.PlayerGui
gui.Parent = player.PlayerGui
sound:Play()
wait(3)--change to how long before the sound plays again after retouching it
local gui = player.PlayerGui:WaitForChild("Gold"):Destroy()
debounce = false
end
end)
end
end
model.Parent = game.Workspace
model:makeJoints()
end
end
Thanks for the suggestions! I added the true debounce value, and added the GUI to the starter players GUI and simply don’t have it enabled until they touch a chest. I am however still a bit hung up on the idea of adding another pairs table but for a regen script when it’s just regening the model. Could you provide an examle of this? Because what i’m envisioning when I hear that is just doing another completely different touch event but in the regen script which I can’t really see as being practical
You should probably restructure your code so it’s just a single script that initialises the chests, and handles regenning / connecting the touched events for the regened chests. That way, you do not have two different touched events (this is why I said it was a band-aid fix).
However, the example I gave should work simply if you replace the original regen script with it.
Having the Touched events be connected in the same script as regen is entirely practical, because it is inevitable that you need to connect the regened chests to Touched (they are new instances of the chests each time).
If you’re concerned about memory leaks or something, the Touched connections for every chest are cleaned up / destroyed every time the chests are regened (as the original instances they were connected to are destroyed).
So i tried the combined version of the scripts you provided with the changes to the GUI location now being in starter gear and it doesn’t seem to be working. Now when interacting with the chests the gui and sound no longer plays, nor does it regen. The script is also inside the model itself. Here is the script with the alterations to now pull from starter gui.
object = script.Parent
local debounce = false
if (object ~= nil) and (object ~= game.Workspace) then
model = object
backup = model:clone()
waitTime =600
wait(math.random(0, waitTime))
while true do
wait(waitTime)
model:Destroy()
wait(0)
model = backup:clone()
debounce = false
for _, part in pairs(model) do
if part:IsA("MeshPart") then
part.Touched:Connect(function(hit)
if hit.Parent:FindFirstChild("Humanoid") and debounce == false then
debounce = true
local player = game.Players:GetPlayerFromCharacter(hit.Parent)
local sound = game.ReplicatedStorage.Sounds.Chest:clone()
local gui = player.PlayerGui.Gold
sound.Parent = player.PlayerGui
gui.Enabled = true
sound:Play()
wait(3)--change to how long before the sound plays again after retouching it
gui.Enabled = false
debounce = false
end
end)
end
end
model.Parent = game.Workspace
model:makeJoints()
end
end
It may be easier for me to help you if you let me do this from scratch, since I can’t see everything you’re doing. Would you like to send me your chest + the GUI as an rbxl?
I can script the entire thing in a couple of minutes and send it back to you and it would be a lot easier lmao
This simple system easily works with multiple chests and uses a RemoteEvent + ServerStorage to store chests.
Chests values can be easily changed per chest by editing the “value” attribute of each chest.
Chests can be any BasePart that has the Touched event.
Ah ok, I honestly learned a lot from your script and it’s application. For one that parts can have their own values and a bit more about remote events. Thanks for taking the time to break everything down and point out a a cleaner way of doing things!