CharacterAdded Event firing more than once

Hi guys,

I’ve been struggling with this for a few days.
The problem I currently have goes like this:

  1. Player joins team, which has a team-only radio chat GUI
  2. They can send messages normally, when the radio is turned ON
  3. After the player: switches from Team 2 to Team 1 back to Team 2 (team with radio) or resets, the message is then sent twice
  4. Repeating step 3 results in 1 increment of how many message are sent at a time.

E.g: After player resets/changes teams back, the player sends “Hi” in the radio chat, the message is doubled, and so on.

I want the player to still send only 1 message even after they died or when they’ve switched back from another team.

I have tried disconnecting from the remote events but this obviously stops the player from sending messages after respawning/changing teams.

The radio GUI has ResetOnSpawn to true. Setting to false just keeps the previously sent messages on the radio but still duplicates the messages.

Client Module Script
local MetroRadioManager = {}

local Players = game:GetService("Players")
local UIS = game:GetService("UserInputService")
local TextService = game:GetService("TextService")
local LocalPlayer = Players.LocalPlayer
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RemoteEvent = ReplicatedStorage.Remotes.RemoteEvent
local switchToggle = false

function cloneGui(playergui)
	local clone = ReplicatedStorage:WaitForChild("GUI").MetroRadio:Clone()
	clone.Parent = playergui
end

function cloneText(foreignplayer, message, player)
	local playergui = player:WaitForChild("PlayerGui")
	local clone = ReplicatedStorage:WaitForChild("GUI").Msg.RadMSG:Clone()
	clone["1ColorCode"].BackgroundColor3 = foreignplayer.TeamColor.Color
	clone["2PlayerName"].Text = "<"..foreignplayer.Name..">"
	clone["2PlayerName"].TextColor = foreignplayer.TeamColor
	clone["3Message"].Text = message
	clone.Parent = playergui:WaitForChild("MetroRadio").Radio.Chat.MessagesFolder.TAC1
end

function biosignalLost(deadplayer, player)
	local playergui = player:WaitForChild("PlayerGui")
	local clone = ReplicatedStorage:WaitForChild("GUI").Msg.RadMSG:Clone()
	clone["1ColorCode"].BackgroundColor3 = Color3.fromRGB(255, 50, 50)
	clone["2PlayerName"].Text = "<OVERWATCH>"
	clone["2PlayerName"].TextColor3 = Color3.fromRGB(255, 50, 50)
	clone["3Message"].Text = "Lost bio-signal for Protection Team unit: "..deadplayer.Name..""
	clone.Parent = playergui:WaitForChild("MetroRadio").Radio.Chat.MessagesFolder.TAC1
end

function onDied(switch)
	switchToggle = false
	switch.TextColor3 = Color3.fromRGB(230, 0, 0)
	switch.Text = "OFF"
	RemoteEvent:FireServer("RadioOffEvent")
end

function ToggleRadio(switch)
	if switchToggle == false then
		switchToggle = true
		switch.TextColor3 = Color3.fromRGB(10, 230, 0)
		switch.Text = "ON"
		RemoteEvent:FireServer("RadioOnEvent")
	else
		switchToggle = false
		switch.TextColor3 = Color3.fromRGB(230, 0, 0)
		switch.Text = "OFF"
		RemoteEvent:FireServer("RadioOffEvent")
	end
end

function PlayerAdded(player)
	if player ~= LocalPlayer then return end
	local function CharacterAdded(char)
		if player.Team.Name ~= "Civil Protection" then return end
		local playergui = player:WaitForChild("PlayerGui")
		cloneGui(playergui)
		local MetroRadio = playergui:WaitForChild("MetroRadio")
		local switch = MetroRadio.Radio:WaitForChild("Switch")
		local chat = MetroRadio.Radio.Chat
		chat.CanvasPosition = Vector2.new(0, 296.617)
		MetroRadio.Enabled = false 
		switchToggle = false 
		RemoteEvent:FireServer("RadioOffEvent") 
		if MetroRadio.Enabled == false then
			MetroRadio.Enabled = true	
		end

		local humanoid = char:WaitForChild("Humanoid"):Wait()
		humanoid.Died:Connect(function()
			onDied(switch)
			local playergui = nil
			local MetroRadio = nil
			RemoteEvent:FireServer("BioSignalDeathEvent")
		end)

		switch.MouseButton1Click:Connect(function()
			ToggleRadio(switch)
		end)

		UIS.InputBegan:Connect(function(input, gpe)
			if not gpe then
				if input.KeyCode == Enum.KeyCode.T then
					ToggleRadio(switch)
					print("Pressed T")
				end
			end
		end)

		RemoteEvent.OnClientEvent:Connect(function(eventType, foreignplayer, data)
			if eventType == "CloneRadioMessageEvent" then
				if foreignplayer and data then
					cloneText(foreignplayer, data, player)
					ToggleRadio(switch)
				end
			end

			if eventType == "BioSignalAllClientsEvent" then
				if foreignplayer and player then
					biosignalLost(foreignplayer, player)
				end
			end
		end)
	end
	CharacterAdded(player.Character or player.CharacterAdded:Wait())
	player.CharacterAdded:Connect(CharacterAdded)	
end 

game.Players.PlayerAdded:Connect(PlayerAdded)
for _, player in pairs(game.Players:GetPlayers()) do
	spawn(function() PlayerAdded(player) end)
end

return MetroRadioManager
Server Module Script
local RadioChatService = {}

local TextService = game:GetService("TextService")
local chat = game:GetService("Chat")
local TextChatService = game:GetService("TextChatService")
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RemoteEvent = ReplicatedStorage.Remotes.RemoteEvent
local switchToggle = false 

local includeUserList = {}

function onChatted(player, message)
	if switchToggle == false then return end
	local filteredMsg
	for plr, v in includeUserList do
		if player.UserId == plr and v == true then
			local foreignplayer = player
			RemoteEvent:FireAllClients("CloneRadioMessageEvent", foreignplayer, message)
		end
	end
end

function onBiosignalLost(foreignplayer)
	RemoteEvent:FireAllClients("BioSignalAllClientsEvent", foreignplayer)
end

function removePlayer(player)
	for plr, v in includeUserList do
		if player.UserId == plr then
			includeUserList[plr] = nil 
			print(includeUserList)
			switchToggle = false
		end
	end
end

function PlayerAdded(player)
	player.Chatted:Connect(function(message)
		onChatted(player, message)
	end)
	local function CharacterAdded(char)
		local humanoid = char:WaitForChild("Humanoid")
		humanoid.Died:Connect(function()
			removePlayer(player)
		end)
	end
	CharacterAdded(player.Character or player.CharacterAdded:Wait())
	player.CharacterAdded:Connect(CharacterAdded)
end

local connection

connection = RemoteEvent.OnServerEvent:Connect(function(player, eventType)
	if not player then return end
	if eventType == "RadioOffEvent" then
		switchToggle = false
		removePlayer(player)
		--connection:Disconnect()
	end
	
	if eventType == "RadioOnEvent" then
		switchToggle = true
		includeUserList[player.UserId] = true
		print(includeUserList)
		--connection:Disconnect()
	end
	
	if eventType == "BioSignalDeathEvent" then
		removePlayer(player)
		onBiosignalLost(player)
		--connection:Disconnect()
	end
end)

game.Players.PlayerAdded:Connect(PlayerAdded)
for _, player in pairs(game.Players:GetPlayers()) do
	spawn(function() PlayerAdded(player) end)
end

return RadioChatService

Many thanks

Issue has been solved, I decided to restructure my code.

Please tell me why you have embedded a function into the PlayerAdded function?

Wait where else would you add them? Are you not suppost to have functions in player added?
Im a rookie so thanks

You can just move the function out of the PlayerAdded function then call it from outside of it. Every time a player joins the game, you create a new function.

Hi,
Yes that’s what I’ve done for my code, I’ve only left the Humanoid.Died() inside the CharacterAdded event. The rest of the code inside the client side module has been moved outside of the PlayerAdded event to prevent the duplications of messages

1 Like

You can have CharacterAdded inside PlayerAdded, but like what I’ve done, try not to add variables inside that scope as it causes problems. Just move variables, like PlayerGui and events, outside of Playeradded or CharacterAdded.

oh so like

local players = game:GetService('Players') or game:FindService('Players')

local function playername(player)
	print(player.Name)
end

players.PlayerAdded:Connect(function(player)
	playername(player)
end)

Pretty much

PlayerAdded only fires once, which is when the player first joins the game.

However, with my problem before, CharacterAdded fires when the player is killed/resets or changes teams.

So it’s fine to run functions inside PlayerAdded since it runs once, but if you use CharacterAdded to run your code it will fire multiple times as CharacterAdded passses a new character of the player every time.

Also you can just use GetService for most services, aside from a handful of services

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