luaroblox

Part instance doesn't remove itself when told so


I've got a local script which fires a remote event each 0.1 seconds. Such remote event is then picked by a global script, which then creates a part with a sound in it where the raycast, created by the local script, lands. This part is supposed to remove itself once its sound finishes playback ( sound.Ended:Wait() ).

The problem is that, on low framerates, the part will not remove although its sound has finished playing, this way creating unnecessary lag because of the number of parts laying around.

The global script in question:

local remoteEvent = script.Parent.esquirlaEvent
local tool = script.Parent

remoteEvent.OnServerEvent:Connect(function(player, startPosition, impacto, colordobjeto, materialdobjeto)
    local function crearescombros()
        
        local visual = Instance.new("Part")
        visual.Parent = game.Workspace.esquirlas
        visual.Anchored = true
        visual.CanCollide = false
        visual.Transparency = .5
        visual.Shape = Enum.PartType.Ball
        visual.Position = impacto
        visual.Size = Vector3.new(2, 2, 2)
        
        
        local sonido = Instance.new("Sound")
        sonido.Parent = visual
        sonido.SoundId = "rbxassetid://15229796402"
        sonido.Volume = 0.5
        sonido.MaxDistance = 70
        sonido:Play()
        
        wait(.1)
        visual.Transparency = .8
        wait(.1)
        visual.Transparency = 1
        
        sonido.Ended:Wait()
        visual:Remove()
        
    end
    
    crearescombros()
    
end)

Any help is welcomed.


Solution

  • So here's the thing about wait, even though you tell it to yield for a specific amount of time, the engine will do the best it can but there's no guarantee that the time yielded will be exactly the amount you specified.

    So in this code :

            sonido:Play()
            
            wait(.1)
            visual.Transparency = .8
            wait(.1)
            visual.Transparency = 1
            
            sonido.Ended:Wait()
    

    It's possible that your sound will have finished playing before the it makes it to the sonido.Ended:Wait() line. So now your code is blocked waiting for a signal that will never fire, because it already has. Since the sound doesn't play again, your code cannot progress from this point.

    You should check if the sound is still playing before blocking.

            if sonido.Playing then
                sonido.Ended:Wait()
            end