Linking your custom chat to the roblox chat button

Previously I came across an issue where I would have a custom chat linked to some topbar button which worked fine but honestly made the entire top-left look weird because of the unibar.

After digging around the devforum a bit, I came across a few chat systems that somehow managed to link itself to the actual roblox chat button. This is exactly what I was looking for but trying to replicate this for myself was pretty challenging because I had to deal with a bunch of random issues I couldn’t figure out.

After an hour of tinkering around I eventually did manage to get it working, and now I’m sharing how I did it. Huge thanks to the posts linked below that helped me figure this out.

“SetActive” fix with support for events
Disabling the roblox chat window while keeping the button

So how did I do it? The way the script works is that it utilizes SetCore and GetCore of the StarterGui to actively check whether the chat button is active or not (ChatActive). I could’ve just called it quits there and used a loop to handle the opening/closing of the custom chat but I wasn’t sure how performant that was considering it runs a pcall every frame.

To get around that, we essentially create a BindableEvent that links itself to the roblox chat button (via SetCore) so we can track whenever something changes about it or the chat window. Then we can handle the logic from there by storing a boolean that checks whether the chat button is active or not for our custom chat to use.

But here comes another problem, the actual chat window. You see, the actual roblox chat doesn’t disappear, and if we disable it manually with SetCoreGuiEnabled, it will also hide the chat button. To work around this issue, just set the Enabled property of these instances to false. It’s important that you never disable the Chat CoreGui because it’ll also get rid of the button.

image

Here’s a simplified script of what it essentially does. In my case, I modified it into a ModuleScript for my game so my custom chat can easily access and get information from it.

-----------------------------------------------------------------------------------------------------
-- Dependencies

local TextChatService = game:GetService("TextChatService")
local StarterGui = game:GetService("StarterGui")

-----------------------------------------------------------------------------------------------------
-- Variables

local chatWindowConfiguration = TextChatService:WaitForChild("ChatWindowConfiguration")
local chatInputBarConfiguration = TextChatService:WaitForChild("ChatInputBarConfiguration")
local channelTabsConfiguration = TextChatService:WaitForChild("ChannelTabsConfiguration")

local chatWindowVisibilityChangedBindable = Instance.new("BindableEvent")
local chatWindowVisibilityBindable = Instance.new("BindableEvent")
local chatActiveChangedBindable = Instance.new("BindableEvent")

local chatWindowVisibilityChanged = chatWindowVisibilityChangedBindable.Event
local chatWindowVisibility = chatWindowVisibilityBindable.Event
local chatActiveChanged = chatActiveChangedBindable.Event

local chatActive: boolean

-----------------------------------------------------------------------------------------------------
-- Private Methods

local function setCore(name: string, value: any): ()
	repeat
		local success = pcall(function()
			StarterGui:SetCore(name, value)
		end)
		if not success then task.wait() end
	until success
end

local function getCore(name: string): any
	local value do
		repeat
			local success = pcall(function()
				value = StarterGui:GetCore(name)
			end)
			if not success then task.wait() end
		until success
	end

	return value
end

local function visibilityChanged()
	local active = getCore("ChatActive")
	chatWindowVisibilityBindable:Fire(active)
	
	if chatActive ~= active then
		chatActiveChangedBindable:Fire(active)
		chatActive = active
	end
end

local function setChatActive(active)
	setCore("ChatActive", active)
end

-----------------------------------------------------------------------------------------------------
-- Connections

do
	setCore("CoreGuiChatConnections", {
		["ChatWindow"] = {
			["ToggleVisibility"] = chatWindowVisibilityChangedBindable,
			["SetVisible"] = chatWindowVisibilityChangedBindable,
			["TopbarEnabledChanged"] = chatWindowVisibilityChangedBindable,
			["CoreGuiEnabled"] = chatWindowVisibilityChangedBindable,
			["VisibilityStateChanged"] = chatWindowVisibilityBindable
		}
	})

	chatWindowConfiguration.Enabled = false
	chatInputBarConfiguration.Enabled = false
	channelTabsConfiguration.Enabled = false
	
	chatWindowVisibilityChanged:Connect(visibilityChanged)
	visibilityChanged()
end

-----------------------------------------------------------------------------------------------------
-- Callback

return {
	ChatActive = chatActive,
	SetChatActive = setChatActive,
	ChatActiveChanged = chatActiveChanged
}

Like all of my other short tutorials, you should only really use this if you really really want to use the roblox chat button instead of your own. This is entirely optional and you shouldn’t rely on this hack since this could break in the future.

Most of the code I wrote above was a fork of the first post made above which was done by @TO_X2C so huge shout-out to them.

9 Likes