Connecting a function after disconnecting

Greetings,

There is a similar topic to this, but I’m a little too rookie to understand the explanations offered and how I’d need to go about changing this code.
I currently have a .Died event linked to respawning a character into an arena. Previously I used .CharacterAppearanceLoaded, however this would end up causing issues as the wait time for respawn is too long for smooth functionality and it would respawn the wrong people on many occasions.

I was using .Died to begin with, but the main issue is that after the first death, the event would disconnect due to how the code runs, the new character was not detected for the event. I’ve tried reconnecting it, but it was not as easy as :Connect().

I am using built-in arrays and dictionaries to store many values such as the players, their lives and their teams.
universePlayers is a table storing the Players.Player instance
universeLives and UniverseTeams store the .Name of universePlayers alongside their indices.

Enough talking, here’s the code:

local deathevent
	for i = 1, #universePlayers do
		deathevent = workspace:FindFirstChild(universePlayers[i].Name).Humanoid.Died:Connect(function()
			if not universePlayers[i] then
				return warn("Tracking remove.")
			end
			universeLives[universePlayers[i].Name] -= 1
			print(universePlayers[i].Name .. " has " .. universeLives[universePlayers[i].Name] .. " lives left.")

			if universeLives[universePlayers[i].Name] == 0 then
				--spectate(universeLives[i])
				print(universePlayers[i].Name .. " is out.")
				deathevent:Disconnect()

				local isTeamOut = 0
				if universeTeams[universePlayers[i].Name] == 1 then
					for i,v in pairs(universeTeams) do
						if v == 1 then
							if universeLives[i] == 0 then
								isTeamOut += 1
							end
						end
					end
				elseif universeTeams[universePlayers[i].Name] == 2 then
					for i,v in pairs(universeTeams) do
						if v == 1 then
							if universeLives[i] == 0 then
								isTeamOut += 1
							end
						end
					end
				end
				print("Team out check =" .. isTeamOut)
				if isTeamOut == 2 then
					if universeTeams[universePlayers[i].Name] == 1 then
						for i,v in pairs(universeTeams) do
							if v == 2 then
								local duelPlayerCharacter = workspace:FindFirstChild(i)
								local duelPlayer = Players:GetPlayerFromCharacter(duelPlayerCharacter)
								duelPlayer.leaderstats.Wins.Value = duelPlayer.leaderstats.Wins.Value + 1
								print(duelPlayer.Name .. " wins!")
								deathevent:Disconnect()
							end
						end
					else
						for i,v in pairs(universeTeams) do
							if v == 1 then
								local duelPlayerCharacter = workspace:FindFirstChild(i)
								local duelPlayer = Players:GetPlayerFromCharacter(duelPlayerCharacter)
								duelPlayer.leaderstats.Wins.Value = duelPlayer.leaderstats.Wins.Value + 1
								print(duelPlayer.Name .. " wins!")
								deathevent:Disconnect()
							end
						end
					end
				else
					return
				end

				gameEnd = true
				
			else
				print("Respawning")
			
				if #universePlayers == 2 then
					for player = 1, #universePlayers do
						print(universePlayers[player])
						respawnInformation(universePlayers[player])
					end
					fullRespawnShield()
				else
					print(universePlayers[i])
					warn(universePlayers[i].Name .. "respawn sequence started. This should not respawn other players.")

					universePlayers[i]:LoadCharacter()
					universePlayers[i].CharacterAppearanceLoaded:Wait()
					respawnInformation(universePlayers[i])
					deathevent:Connect()
					singleRespawnShield(universePlayers[i])
				end
			end
		end)
	end

The top portion deals with taking the player out of the game if he has 0 lives, and checking if his teammates also do, in which case, the game ends.
The bottom portion deals with respawn, where I’d need the .Died event reapplied.

edit:
SOLUTION CODE BELOW

local deathevent
	
	local function createDeathEvent(player)
		--if not table.find(universePlayers, player) then
		--	deathevent:Disconnect()
		--	return warn("Tracking remove.")
		--end
		local humanoid = workspace:FindFirstChild(player.Name).Humanoid
		
		deathevent = humanoid.Died:Connect(function()
			universeLives[player.Name] -= 1
			print(player.Name .. " has " .. universeLives[player.Name] .. " lives left.")

			if universeLives[player.Name] == 0 then
				--spectate(universeLives[i])
				print(player.Name .. " is out.")
				deathevent:Disconnect()

				local isTeamOut = 0
				if universeTeams[player.Name] == 1 then
					for i,v in pairs(universeTeams) do
						if v == 1 then
							if universeLives[i] == 0 then
								isTeamOut += 1
							end
						end
					end
				elseif universeTeams[player.Name] == 2 then
					for i,v in pairs(universeTeams) do
						if v == 1 then
							if universeLives[i] == 0 then
								isTeamOut += 1
							end
						end
					end
				end
				print("Team out check =" .. isTeamOut)
				if isTeamOut == 2 then
					if universeTeams[player.Name] == 1 then
						for i,v in pairs(universeTeams) do
							if v == 2 then
								local duelPlayerCharacter = workspace:FindFirstChild(i)
								local duelPlayer = Players:GetPlayerFromCharacter(duelPlayerCharacter)
								duelPlayer.leaderstats.Wins.Value = duelPlayer.leaderstats.Wins.Value + 1
								print(duelPlayer.Name .. " wins!")
								deathevent:Disconnect()
							end
						end
					else
						for i,v in pairs(universeTeams) do
							if v == 1 then
								local duelPlayerCharacter = workspace:FindFirstChild(i)
								local duelPlayer = Players:GetPlayerFromCharacter(duelPlayerCharacter)
								duelPlayer.leaderstats.Wins.Value = duelPlayer.leaderstats.Wins.Value + 1
								print(duelPlayer.Name .. " wins!")
								deathevent:Disconnect()
							end
						end
					end
				else
					return
				end

				gameEnd = true

			else
				print("Respawning")

				if #universePlayers == 2 then
					for player = 1, #universePlayers do
						print(universePlayers[player])
						respawnInformation(universePlayers[player])
					end
					fullRespawnShield()
				else
					warn(player.Name .. "respawn sequence started. This should not respawn other players.")

					player:LoadCharacter()
					local character = player.CharacterAppearanceLoaded:Wait()
					local newPlayer = Players:GetPlayerFromCharacter(character)
					respawnInformation(player)
					createDeathEvent(newPlayer)
					singleRespawnShield(player)
				end
			end
		end)
	end

	for i = 1, #universePlayers do
		createDeathEvent(universePlayers[i])
	end
3 Likes

You should use the CharacterAdded event so you can give humanoids the Died event everytime they respawn like this:

Players.PlayerAdded:Connect(function(plr)
	plr.CharacterAdded:Connect(function(char)
		local Humanoid = char.Humanoid
		Humanoid.Died:Connect(function()
			-- your code here
		end)
	end)
end)

I’m not sure how your game works, i.e. if the arena is the only mode, if there’s a round system, etc.
But this should help you solve your problem

4 Likes

You can just connect again with .Died, if you want that whole code to be ran then you can make a function.

4 Likes

Not sure if I’d be able to do this. This game contains multiple duelingarenas. You and your opponent step on pads which sends you to fight in that specific arena. This ~300 line script is found in each individual arena.
Everything that happens should be localised to that arena, so Players.PlayerAdded would break the game unless I can localize it.

edit:
To answer the questions, these arenas are the only mode per say, but as mentioned, there’s 10+ of them. 1v1, 2v2, 3v3s all included. The script in the post is from a 2v2 arena.
There is an outscore (lives system), which is actually what’s doing my head in and why I’ve created the post haha

3 Likes

This is the part I’m confused about. As seen near the bottom of that block of code, I’ve tried to rerun deathevent:Connect(), but as I’ve learned, it’s not as simple.

I’m not sure how I’d reconnect .died again for the specific player that died. If I while loop it until the game ends, it makes each player have an indefinite amount of .Died events, which breaks the game.

1 Like

this wont work you need to create a new connection

you can get the new character from

local character = universePlayers[i].CharacterAppearanceLoaded:Wait()
1 Like

If you want to connect to the exact same function then you can do:

local deathevent

local function createDeathEvent(humanoid)
	deathevent = humanoid.Died:Connect(function()
		if not universePlayers[i] then
			return warn("Tracking remove.")
		end
		universeLives[universePlayers[i].Name] -= 1
		print(universePlayers[i].Name .. " has " .. universeLives[universePlayers[i].Name] .. " lives left.")

		if universeLives[universePlayers[i].Name] == 0 then
			--spectate(universeLives[i])
			print(universePlayers[i].Name .. " is out.")
			deathevent:Disconnect()

			local isTeamOut = 0
			if universeTeams[universePlayers[i].Name] == 1 then
				for i,v in pairs(universeTeams) do
					if v == 1 then
						if universeLives[i] == 0 then
							isTeamOut += 1
						end
					end
				end
			elseif universeTeams[universePlayers[i].Name] == 2 then
				for i,v in pairs(universeTeams) do
					if v == 1 then
						if universeLives[i] == 0 then
							isTeamOut += 1
						end
					end
				end
			end
			print("Team out check =" .. isTeamOut)
			if isTeamOut == 2 then
				if universeTeams[universePlayers[i].Name] == 1 then
					for i,v in pairs(universeTeams) do
						if v == 2 then
							local duelPlayerCharacter = workspace:FindFirstChild(i)
							local duelPlayer = Players:GetPlayerFromCharacter(duelPlayerCharacter)
							duelPlayer.leaderstats.Wins.Value = duelPlayer.leaderstats.Wins.Value + 1
							print(duelPlayer.Name .. " wins!")
							deathevent:Disconnect()
						end
					end
				else
					for i,v in pairs(universeTeams) do
						if v == 1 then
							local duelPlayerCharacter = workspace:FindFirstChild(i)
							local duelPlayer = Players:GetPlayerFromCharacter(duelPlayerCharacter)
							duelPlayer.leaderstats.Wins.Value = duelPlayer.leaderstats.Wins.Value + 1
							print(duelPlayer.Name .. " wins!")
							deathevent:Disconnect()
						end
					end
				end
			else
				return
			end

			gameEnd = true

		else
			print("Respawning")

			if #universePlayers == 2 then
				for player = 1, #universePlayers do
					print(universePlayers[player])
					respawnInformation(universePlayers[player])
				end
				fullRespawnShield()
			else
				print(universePlayers[i])
				warn(universePlayers[i].Name .. "respawn sequence started. This should not respawn other players.")

				universePlayers[i]:LoadCharacter()
				local character = universePlayers[i].CharacterAppearanceLoaded:Wait()
				respawnInformation(universePlayers[i])
				createDeathEvent(character.Humanoid)
				singleRespawnShield(universePlayers[i])
			end
		end
	end)
end

for i = 1, #universePlayers do
	createDeathEvent(workspace:FindFirstChild(universePlayers[i].Name).Humanoid)
end
1 Like

Starting rewriting the code before reading this in almost the exact same way. My version didn’t work, but I’ve done it slightly differently, will give this one a try now.

1 Like

Thank you so much. I still ended up doing it differently to this, but heavily inspired. I instead got the character/humanoid in the deathfunction itself, and had to script in the variables a bit different, but it works a charm.
Credited with solution. Will edit in my own code solution in my post.

1 Like

Regarding this, I’ve thought about it while trying to get the solution, I could have tried using this and comparing it to my plater table to see if the playeradded was in the arena, then fired the event if true.

This could be an alternative solution to this post, but would still require rewriting the function.

Thank you for the suggestion :slight_smile:

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.