Should local script initialize every time when player spawns?

I put a local script inside a ResetOnSpawn set to false ScreenGui.

1: Is this a good practise? my local script is a core part of the client, it handles UIs such as game intro, menu etc.
One of the reasons I’m doing this is because I think it’s not necessary to load everything whenever a player respawns, such as requiring modules, getting services etc. especially player respawns pretty frequently in my game.
Also, I’d like to process follow up actions when player dies in game, such as a transaction fading screen, follow up message after player respawns etc. For an example, inside a local script:

char.Humanoid.Died:Connect(function()
   	wait(6)
    print("Hey!") -- Won't run because player respawns in 5 seconds, this local script no longer exists and vanished from this universe!
end)

2: tl;dr: How’d I detect a local player respawns?
You can detect player respawns but simply running the script because local script runs upon spawn, but in my scenario, if local script only initialize once, how’d I detect it? I thought of using CharacterAdded or character.Changed, but I need some more information regarding on the most efficient way to perform this.

3 Likes

If your code suffers from being reset upon death, try putting it inside StarterPlayerScripts. This will prevent the from being reset, but it still allows for localscripts to run. Alternatively, you can put your script inside a ScreenGui instance with the .ResetOnSpawn property set to false.

TIP: You can disable automatic respawning by setting the .CharacterAutoLoads property of Players to false. To load character manually, call :LoadCharacter() on their Player instance.

4 Likes

CharacterAdded is the best way to do this. It fires everytime a player spawns.

1 Like

Guess I’ll put it inside StarterPlayerScripts instead of a ScreenGui, makes more sense.

CharacterAdded doesn’t fire when a local script initially runs? I think it only runs after CharacterAdded fired. I probably have to fire the function individually.

CharacterAdded should fire the way it’s supposed to.

For initial runs, check for an existing character or if the CharacterAdded signal fires. Every subsequent CharacterAdded fire will tell you when a respawn occurs.

-- A
local function onCharacterAdded(character)
end

Player.CharacterAdded:Connect(onCharacterAdded)

if Player.Character then
    onCharacterAdded(Player.Character)
end

-- B
local character = Player.Character or Player.CharacterAdded:Wait()
1 Like

Why this variable won’t update?

local char = plr.Character or plr.CharacterAdded:Wait()

char.ChildAdded:Connect(function(child)
	print(child) -- ONLY print at the first spawn only
end)

I tried to overwrite the char variable upon second CharacterAdded (Respawn) event, it still won’t print anything:

plr.CharacterAdded:Connect(function(newchar) -- Second spawn
	char = newchar
end)

That’s because the ChildAdded event is still connected to your old character. You require another connection of the function to the new character to make this work as expected.

local char = plr.Character or plr.CharacterAdded:Wait()

local function onChildAdded(child)
    print(child)
end

local function onCharacterAdded(char)
    char.ChildAdded:Connect(onChildAdded)
end

plr.CharacterAdded:Connect(onCharacterAdded)
onCharacterAdded(char)

Be wary that this code raw may cause a memory leak. If you want to guard against that, make sure to disconnect ChildAdded in a CharacterRemoving listener.

Why I can’t overwrite the old character with the new one from CharacterAdded? Inside ChildAdded, I’d like to connect to more other function that use the character variable, my ultimate goal is to have the character variable stand by in anytime no matter the player respawned or not.

For an example:

local plr = game.Players.LocalPlayer
local char = plr.Character
tool = nil

function updateTool(newchar, newtool)
newchar.Head.BrickColor = BrickColor.new("Gold")
tool = newtool

end

char.CharacterAdded:Connect(function(newchar)
newchar.ChildAdded:Connect(function()
updateTool(newchar, tool)

end)

end)

You can and you did the first time around. My code sample was an alternative. Again, the issue was that your functions were connected to the old character, not the new one, which is why your code was supposedly not working.

Got it, thanks! This really took me some to understand it.
I made a separate function to connect character to different events:

function ConnectCharToFunctions(characterToCheck)
	characterToCheck.ChildAdded:Connect(function(child)
		if child:IsA("Tool") then
			-- do something
		end
	end)
	
	characterToCheck.ChildRemoved:Connect(function(child)
		if child:IsA("Tool") then
			-- do something
		end
	end)
end

ConnectCharToFunctions(char)

plr.CharacterAdded:Connect(function(a)

ConnectCharToFunctions(a)

end)