local HUD = script.Parent
-- Using this module as an example
local LevelMenu = HUD:WaitForChild('LevelMenu')
local LevelMenuControl = require(LevelMenu.LevelMenuControl)
Now this module is this
local LevelMenuControl = {}
print(1)
local ReplicatedStorage = game:GetService('ReplicatedStorage')
local Remotes = ReplicatedStorage:WaitForChild('Remotes')
local Events = Remotes:WaitForChild('Events')
local GetData = Events:WaitForChild('GetData')
local Frame = script.Parent
local Bar = Frame:WaitForChild('Bar')
local Exp = Frame:WaitForChild('Exp')
local Level = Frame:WaitForChild('Level')
local WhiteExp = Bar:WaitForChild('WhiteExp')
GetData.OnClientEvent:Connect(function(data)
local ExpNeeded = data.Level * 50
Level.Text = data.Level
Exp.Text = data.Exp .. ' / ' .. ExpNeeded
WhiteExp.Text = Exp.Text
if Bar then
Bar:TweenSize(UDim2.new(data.Exp / ExpNeeded, 0, 1, 0), 'Out', 'Linear', 0.5, true) -- ERROR HERE
end
end)
GetData:FireServer()
return LevelMenuControl
and heres my output when I die
[1]
[13:04:11.216 - Can only tween objects in the workspace]
[13:04:11.216 - Script ‘Players.NinjoOnline.PlayerGui.HUD.LevelMenu.LevelMenuControl’, Line 25]
[1]
[13:04:11.316 - Can only tween objects in the workspace]
[13:04:11.317 - Script ‘Players.NinjoOnline.PlayerGui.HUD.LevelMenu.LevelMenuControl’, Line 25]
So my question is, once I die, does the old module keep running? I have ResetOnSpawn set to true (I need the UI elements to be reset when you die)
Thing is, if Bar exists, then I tween it, so not sure how I can get this error as it has to exist first before it can tween
Yes, they do. Literally spent forever trying to figure out some bugs to find out that this is what was happening. Basically you just gotta manually disconnect all events and break all loops when the player dies to stop the module and it should go to the garbage collector.
local Alive = true;
local Connections = {};
--Loop example
while Condition do
if not Alive then break; end
--Other loop stuff
end
--Anonymous Connection Example
table.insert(Connections,Game.Workspace.Changed:Connect(function(Property)
--DoStuffHere
end));
--Alternative Connection Example
local WorkspaceConnection = Game.Workspace.Changed:Connect(function(Property)
--DoStuffHere
end)
table.insert(Connections, WorkspaceConnection);
--Breaking it all
Player.CharacterAdded:Connect(function()
for _,v in ipairs(Connections) do
v:Disconnect();
end
Alive = false;
end)
Just to add onto this reply, you can just disconnect it whenever the script’s parent becomes nil:
local function UpdateData(data)
local ExpNeeded = data.Level * 50
Level.Text = data.Level
Exp.Text = data.Exp .. ' / ' .. ExpNeeded
WhiteExp.Text = Exp.Text
if Bar then
Bar:TweenSize(UDim2.new(data.Exp / ExpNeeded, 0, 1, 0), 'Out', 'Linear', 0.5, true)
end
end
GetData:FireServer()
local Connection = GetData.OnClientEvent:Connect(UpdateData)
local ParConnection; ParConnection = script:GetPropertyChangedSignal('Parent'):Connect(function()
if script.Parent == nil then
Connection:Disconnect()
ParConnection:Disconnect()
end
end)
return LevelMenuControl
You can also directly transfer the event and function through the module and make the script connect it, and you won’t have to worry about this happening, in theory:
LevelMenuControl.Connections = {}
local function UpdateData(data) ... end
GetData:FireServer()
LevelMenuControl.Connections[GetData.OnClientEvent] = UpdateData
return LevelMenuControl
local LevelMenuControl = require(LevelMenu.LevelMenuControl)
-- load the rest of your modules
for _,module in ipairs{LevelMenuControl, --[[rest of your modules]]} do
for event, func in pairs(module.Connections) do
event:Connect(func)
end
end
Modules do keep running after death. The problem is that your ModuleScript is referencing an old copy of the Gui. If you have the Gui set to ResetOnRespawn, it will get removed when Player.Character changes. The Gui then gets detached from the DataModel and you can’t tween it anymore.
This issue can be fixed through any combination of the methods above or ensuring that your Gui only uses recent copies of a Gui. For example, instead of upvalues for the Gui, move them into the function connected to the remote.