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.
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.