Why is this event firing randomly?

newRig.ChildRemoved:Connect(function(part)
	if part:IsA("BasePart") and part.Name == "HumanoidRootPart" and humanoid.RootPart == nil then
		print("respawn")
		plr:LoadCharacter()
	end
end)

You can add a sanity check, it may help:

newRig.ChildRemoved:Connect(function(part)
	if not newRig:IsDescendantOf(game) then return end 

	if part:IsA("BasePart") and part.Name == "HumanoidRootPart" and humanoid.RootPart == nil then
		print("respawn")
		plr:LoadCharacter()
	end
end)

Not sure how else to help you, can you provide any more context on what you’re trying to create?

what is your property inside workspace.RejectCharacterDeletion is set to?

It’s inside a morph function that triggers on respawn. The function destroys the players current character and sets the character to a rig. The point of checking if the HumanoidRootPart is removed is so that if you fall to the void you respawn/teleport instantly.


function self.morph(plr)
	if not plr.Team or plr.Neutral then return end
	local attribute

	local team = plr.Team.Name

	if team == "Attackers" then
		attribute = plr:GetAttribute("EquippedAttacker")
	elseif team == "Defenders" then
		attribute = plr:GetAttribute("EquippedDefender")
	end

	if not ssTeams[team]:FindFirstChild(attribute) then warn("Rig model does not exist for "..attribute) return end

	local newRig = ssTeams[team][attribute]:Clone()

	local map = ingameMapFolder.Map
	if map then
		local teamSpawns = map.TeamSpawns[plr.Team.Name]:GetChildren()
		newRig:PivotTo(teamSpawns[math.random(1,#teamSpawns)].CFrame*CFrame.new(0,4.5,0))
	else
		newRig:PivotTo(workspace.Map.SpawnLocation.CFrame*CFrame.new(0,4.5,0))
	end

	newRig.Parent = workspacePlayers[team]

	plr.Character:Destroy()
	plr.Character = newRig

	self.characters[plr.UserId] = shared.Character.new(plr, shared.Replication.behaviors[team][attribute], require(rsTeams[team][attribute].Config))

	self.MorphVFX:Fire(plr)
	
	for _, v in ipairs(newRig:GetDescendants()) do
		if not v:IsA("Part") then continue end
		v:SetNetworkOwner(plr)
	end
	
	local humanoid = newRig:WaitForChild("Humanoid")

	humanoid.Died:Once(function()
		characterDestroy(plr)
	end)

	newRig.ChildRemoved:Connect(function(part)
		if part:IsA("BasePart") and part.Name == "HumanoidRootPart" and humanoid.RootPart == nil then
			print("respawn")
			plr:LoadCharacter()
		end
	end)
end

players.PlayerAdded:Connect(function(player)
	player.CharacterRemoving:Connect(function(char)
		if self.characters[player.UserId] and self.characters[player.UserId].Character == char then
		characterDestroy(player)
		end
	end)

	player.CharacterAdded:Connect(function(char)
		if self.characters[player.UserId] or not workspace:GetAttribute("Respawning") then return end

		self.morph(player)
	end)
end)

Is there any specific reason you’re not using Humanoid.Died instead of detecting if the HumanoidRootPart is still present?

When the player falls in the void Humanoid.Died doesn’t trigger and you get stuck in the void forever.

I’m not sure about that.

No I meant that in the context of being morphed into the new character model. (the respawn time is 2 seconds)