How to make typing for the new TextChatService

While i now that i’m still a intermediate programmer going onto semi-professional, i guess this a good tutorial,

So, i’ve been searching on this tutorial for ages now, but i managed to improve it myself,

So this tutorial is about: How to make “Typing” in the new TextChatService, now this is something that nobody talks about as most of the games didn’t change because all scripts tend to lean to the Chat service more. But i created one for TextChatService, now this is Inaccurate because Roblox is still working on the scripts and somethings are still under development so i made this tutorial to help you!

Lets Get Started!,

First we get out typing billboardgui, Done? lets move on

we create a event in ReplicatedStorage and name it “Typing” or whatever you want, Done? lets go cmon!

we create 2 scripts, 1st is LocalScript in StarterPlayer → StarterPlayerScripts
2nd is ServerScript in ServerScriptService or Workspace, Done? lets move on!

in the Client Script:

local ChatBar = game:GetService("TextChatService").ChatInputBarConfiguration

while wait(0.3) do
	if ChatBar.IsFocused then
		game.ReplicatedStorage.Typing:FireServer(true)
	else
		game.ReplicatedStorage.Typing:FireServer(false)
	end
end

Only this!
(Now this is the innaccurate Part as if you put ChatBar.Changed, it won’t work as the IsFocused property is locked and wait(0.3) is the greatest checkrate i used)

and in the Server Script:

game.ReplicatedStorage.Typing.OnServerEvent:Connect(function(plr, Bool)
	
	if Bool then
		
		local clone = script.typingChat:Clone()
		clone.Parent = plr.Character:WaitForChild("Head")
		clone.Enabled = true
	else
		
		if plr.Character:WaitForChild("Head"):FindFirstChild("typingChat") then
			local clone = plr.Character:WaitForChild("Head"):FindFirstChild("typingChat")
			clone:Destroy()
		end
	end
	
	plr.Chatted:Connect(function()
		if plr.Character:WaitForChild("Head"):FindFirstChild("typingChat") then
			local clone = plr.Character:WaitForChild("Head"):FindFirstChild("typingChat")
			clone:Destroy()
		end
	end)
end)

and its only this!

(it is good if we keep the plr.Chatted i think for more accuracy)

And it turns out as:

https://gyazo.com/9ddbb55fed6757b304527e1b09de7038

Not as smooth but its only thing i managed to get out of this,
if you think you can do better don’t hesitate improve the script and share it with us, i could learn something too! Thanks for looking at my thread :sparkling_heart:

3 Likes

Nice tutorial, but your scripts can be improved in a few areas:

Instead of a loop, you can connect a GetPropertyChangedSignal connection to the property:

local ChatBar = game:GetService("TextChatService").ChatInputBarConfiguration

-- this only fires if the property is changed or updated
ChatBar:GetPropertyChangedSignal("IsFocused"):Connect(function()
	game.ReplicatedStorage.Typing:FireServer(ChatBar.IsFocused)
end)

Even if a property is locked, Changed events will still fire since the event waits for the value of the properties changing, not if the developer writes to it. The only properties that won’t fire the Changed event are properties that are related to physics (CFrames, Positions, etc)


This creates a memory leak since new event connections are created each time the RemoteEvent is fired to, you should disconnect old events before creating new ones:

local playerListeners = {} -- table to hold all the Player.Chatted listeners
game.ReplicatedStorage.Typing.OnServerEvent:Connect(function(plr, Bool)
	if Bool then
		
		local clone = script.typingChat:Clone()
		clone.Parent = plr.Character:WaitForChild("Head")
		clone.Enabled = true
	else
		
		if plr.Character:WaitForChild("Head"):FindFirstChild("typingChat") then
			local clone = plr.Character:WaitForChild("Head"):FindFirstChild("typingChat")
			clone:Destroy()
		end

        return -- stop the function since there's no need to create a new listener
	end

    -- remove old event listener first
	local listener = playerListeners[plr]
    if listener then
        listener:Disconnect()
    end

    -- add a new event listener
	playerListeners[plr] = plr.Chatted:Connect(function()
		if plr.Character:WaitForChild("Head"):FindFirstChild("typingChat") then
			local clone = plr.Character:WaitForChild("Head"):FindFirstChild("typingChat")
			clone:Destroy()
		end

        -- since the player chatted, disconnect the event and remove it from the list
        playerListeners[plr]:Disconnect()
        playerListeners[plr] = nil
	end)
end)
4 Likes