local ChatEvent = game:WaitForChild("ReplicatedStorage"):WaitForChild("Events"):WaitForChild("ChatEvent")
local TextChatService = game:GetService("TextChatService")
local Channel = TextChatService:WaitForChild("TextChannels"):WaitForChild("RBXSystem")
ChatEvent.OnClientEvent:Connect(function(Type, Msg)
if Type == "Display" then
Channel:DisplaySystemMessage(Msg)
elseif Type == "Mute" then
if Msg then
TextChatService.OnIncomingMessage = function(Message)
Message.TextSource.CanSend = true
return Message
end
else
TextChatService.OnIncomingMessage = function(Message)
Message.TextSource.CanSend = false
return Message
end
end
end
end)
However whenever I fire the mute remote event to the client, I get this error.
Players.supercrash950.PlayerScripts.LocalChatHandler:16: attempt to index nil with ‘CanSend’
What am I wrong? and how could I make it display a system message using Channel:DisplaySystemMessage() everytime the player tries to chat while being muted.
This reply to my post about muting players server-side is a good solution for this. I see you’re already using a RemoteEvent which is fired by the server for muting, so perhaps muting people on the server in the first place is a better option for you.
You can probably adapt that code to still tell the client when they are muted, something like below:
-- SERVER SCRIPT
---> services
local players = game:GetService("Players")
local textChatService = game:GetService("TextChatService")
---> variables
local mutedPlayers = {}
---> functions
local function muteUserId(userId: number)
for _,d in textChatService:GetDescendants() do
if d:IsA("TextSource") then
if d.UserId == userId then
d.CanSend = false
end
end
end
local player = players:GetPlayerByUserId(userId)
if player then
player:SetAttribute("muted", true)
end
mutedPlayers[userId] = true
end
local function unmuteUserId(userId: number)
for _,d in textChatService:GetDescendants() do
if d:IsA("TextSource") then
if d.UserId == userId then
d.CanSend = true
end
end
end
local player = players:GetPlayerByUserId(userId)
if player then
player:SetAttribute("muted", false)
end
mutedPlayers[userId] = nil
end
---> main
-- listen for future muted TextSources
textChatService.DescendantAdded:Connect(function(descendant: Instance)
if descendant:IsA("TextSource") then
if mutedPlayers[descendant.UserId] then
descendant.CanSend = false
end
end
end)
You’d use the functions muteUserId and unmuteUserId within the server-sided script to mute and unmute players using their UserId. The code above uses an attribute to easily replicate whether the player is muted or not. To convey to the player that they are muted, you have a few options, though the one that makes most sense would be checking that attribute when they try to send a message.
-- LOCAL SCRIPT
---> services
local players = game:GetService("Players")
local textChatService = game:GetService("TextChatService")
---> variables
local localPlayer = players.LocalPlayer
local systemChannel = textChatService:WaitForChild("TextChannels"):WaitForChild("RBXSystem")
---> functions
local function onIncomingMessage(message: TextChatMessage)
if not message.TextSource then return end
if message.TextSource.UserId ~= localPlayer.UserId then return end
if message.TextSource.CanSend and not localPlayer:GetAttribute("muted") then return end
-- the local player tried to send a message and they are muted
systemChannel:DisplaySystemMessage("You are currently muted!")
end
---> main
textChatService.OnIncomingMessage = onIncomingMessage