Functions still being activated even though the script is gone

In my game, I keep getting errors all over my scripts because functions are still being called even after my scripts are being destroyed/their ancestors are being destroyed. For instant its happening in my GUI scripts when my characters die - I get errors like this
image

I can easily fix this with if script.Parent~=nil then but I don’t want to have to put this everywhere in my code. Did roblox always behave in this way. Did something change?

Destroy won’t terminate the while thread. Nothing’s changed, this has always been the case.

You shouldn’t be using a while loop here anyhow, you should be using events - specifically Changed whenever relevant (such as on your XP value). This UpdateLevel function is only meant to update some text, therefore, you only need to call it as in when a change is made rather than at all times.

That’s exactly what I’m doing. The functions are not in a loop. I am updating the xp value for testing purposes though

Does script.Parent.Level.LEVEL exists or do you have any typo in it? (Make sure to check in a play mode)

it exist lmao. The issue comes from when the script is being deleted - specifically as the player is dying-the GUI gets destroyed, but the script still runs for a slight time after strangely

Can you please show me the Explorer?

image

The issue may be related to task.spawn as I was able to reproduce the issue. My assumption is that you use it to run UpdateLevel, inside a loop. coroutine.wrap and pcall might be good alternatives if you have to use multiple threads.

I’m not! Heres my full script right now

local Player = game:GetService("Players").LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild("Humanoid")
local PlayerInfo = game.Players.LocalPlayer:WaitForChild("Info")
local playerData = game.Players.LocalPlayer:WaitForChild("Data2")
local Healthbar = script.Parent
PrevPos = UDim2.new(0,0,0,0)
PrevPos2 = UDim2.new(0,0,0,0)
PrevPos3 = UDim2.new(0,0,0,0)


function UpdateMagic ()
	
	script.Parent.MagicIcon.MagicReq.Text = "x"..PlayerInfo.Magic.Value
	for i=1,6 do
		script.Parent.MagicIcon.Visible = false
		wait(0.1)
		script.Parent.MagicIcon.Visible = true
		wait(0.1)
	end
end

function UpdateLevel ()
	
	local level = playerData.Level
	local xp = playerData.XP
	local maxLevel = math.floor(10+((level.Value * 15) ^ 1.5)) 
	script.Parent.Level.LEVEL.Text = "LVL "..level.Value.."    xp"..xp.Value.."/"..maxLevel
	script.Parent.Level.Bar.Size = UDim2.new(xp.Value/maxLevel,0,1,0)

end

local function UpdateHealthbar()
	Humanoid.CameraOffset = Vector3.new(0,4,0)
	if Humanoid~=nil then
		local MaxHealth = Humanoid.MaxHealth
		local Health = Humanoid.Health
		if Health%2== 0 then
			for i=1,6 do
				if script.Parent~=nil then
					wait(0.1)
					script.Parent.Health.Position = PrevPos
					script.Parent.Health.HealthClip.Position = PrevPos2
					script.Parent.Health.HealthClip.HealthShow.Position = PrevPos3	
					wait(0.1)
					script.Parent.Health.Position = UDim2.new(0+(MaxHealth/10)-1,0,script.Parent.Health.Position.Y.Scale,0)
					script.Parent.Health.HealthClip.Position = UDim2.new(-1+(Health/MaxHealth),0,script.Parent.Health.HealthClip.Position.Y.Scale,0)
					script.Parent.Health.HealthClip.HealthShow.Position = UDim2.new(-1+(MaxHealth/10),0,script.Parent.Health.HealthClip.HealthShow.Position.Y.Scale,0)			
				end
			end
		else
			for i=1,6 do
				if script.Parent~=nil then
					wait(0.1)
					script.Parent.Health.Position = PrevPos
					script.Parent.Health.HealthClip.Position = PrevPos2
					script.Parent.Health.HealthClip.HealthShow.Position = PrevPos3	
					wait(0.1)
					script.Parent.Health.HealthClip.Position = UDim2.new(-1+(Health/MaxHealth),0,script.Parent.Health.HealthClip.Position.Y.Scale,0)
					script.Parent.Health.HealthClip.HealthShow.Position = UDim2.new(-0.9+(MaxHealth/10),0,script.Parent.Health.HealthClip.HealthShow.Position.Y.Scale,0)
				end	
			end	
		end
	
		if script.Parent~=nil then
			PrevPos = script.Parent.Health.Position
			PrevPos2 = script.Parent.Health.HealthClip.Position
			PrevPos3 = script.Parent.Health.HealthClip.HealthShow.Position
		end
	end
end


UpdateHealthbar()


Humanoid:GetPropertyChangedSignal("Health"):Connect(UpdateHealthbar)
Humanoid:GetPropertyChangedSignal("MaxHealth"):Connect(UpdateHealthbar)
PlayerInfo.Magic.Changed:Connect(UpdateMagic)
playerData.XP.Changed:Connect(UpdateLevel)
playerData.Level.Changed:Connect(UpdateLevel)
UpdateMagic()
UpdateLevel()

I feel like somehow the script is surviving even after the player dies… I have gui reset on death on!

Ok so looking into it myself now that I’m home, I think there’s some sort of memory leak similar to what this guy experienced: Destroying Characters - #3 by JimmyChance

When my characters are dying to the void, they’re not being properly destroyed. So far using Character:Destroy() and then LoadCharacter() has fixed my issue

Is “playerData” a folder parented to the character? If so each time you die and an attempt to reference it is made these errors will occur.

You could add a Humanoid.Died or Player.CharacterRemoving which could then stop the entire script.