[Open Sourced] Custom Bubble Chat

Where can we find the script for that?

image So if you type and stop typing this shows up and the loading bubbles keep on showing even though you stopped typing.

5 Likes

Amazing, I like it. Thank you for open-sourcing this!

1 Like

Amazing, I might actually use it in my games. Thanks.

1 Like

Also private chats show up with the bubble chat.

1 Like

I haven’t had time to update this Chat and I really apologize for that. Sorry for all the bugs occurring. From now, I would recommend using this as a learning resource instead of a game asset(especially since you can see private messages) and I don’t think I will have time to fix these bugs. If I do manage to find time to update it, I will let you all know. Thanks.

7 Likes

Very useful, its been helping me understand the chat system a lot. Looks good but there is a lot of bugs ^^^. If the bugs get fixed there is a lot of people that would pay some robux for it. :slight_smile:

1 Like

I rather let people learn from it for free instead of myself having to sell it as an asset.

1 Like

Can you help me out on making this custom bubble chat able to be used for only Bubble Chat? So it doesn’t show up the classic chat (I tried enabling bubble chat only and it shows both ROBLOX’s and your bubble).

1 Like

I don’t know if the creator will respond but on mobile it says your typing for forever. When walking around if still has the typing icon and the afk timer takes down your keyboard when typing on mobile every 5 seconds, requiring u to type your message in less than 5 seconds.

Oh man really wish u fixed the bug when u r not typing it keeps going

did you do everything correct?

ReplicatedStorage → Modules → Chat

Code:

ModuleScript

local Chat = {
Players = {}
}

– // Services \ –
local ReplicatedStorage = game:GetService(“ReplicatedStorage”)
local ServerStorage = game:GetService(“ServerStorage”)
local TweenService = game:GetService(“TweenService”)
local TextService = game:GetService(“TextService”)

– // Main \ –
function UpdateMessageNames(Player)
local Character = Player.Character
local BubbleChatUI = Character.Head.BubbleChatUI

for _, MessageLabel in pairs(BubbleChatUI:GetChildren()) do
	if MessageLabel.Name ~= "TypingLabel" then
		MessageLabel.Name = tostring(tonumber(MessageLabel.Name) + 1)
	end
end

end

function Chat:GetMessageIndex(Player, Time)
local Messages = Chat.Players[Player.Name].Messages
for i,Message in pairs(Messages) do
if Message.Time == Time then
return i
end
end

return nil

end

function Chat:DeleteMessage(Player, messageLabel) – // Deletes message from the given index.
local Character = Player.Character
if Character == nil then return end
local Messages = Chat.Players[Player.Name].Messages
local MessageIndex = nil

if typeof(messageLabel) == "number" then -- // Checks if the paramater is an messageLabel(instance) or the index(number).
	MessageIndex = messageLabel
	messageLabel = Messages[MessageIndex].Instance
else
	if Character.Head.BubbleChatUI:FindFirstChild(messageLabel.Name) == nil then
		return 
	end
	if messageLabel:FindFirstChild("Time") == nil then
		return 
	end
	
	MessageIndex = Chat:GetMessageIndex(Player, messageLabel.Time.Value)
end 

print("Deleting: "..MessageIndex)

local FadeOutMessage = TweenService:Create(messageLabel, TweenInfo.new(0.5), {
	ImageTransparency = 1,
})
local FadeOutText = TweenService:Create(messageLabel.TextBox, TweenInfo.new(0.5), {
	TextTransparency = 1,
})

table.remove(Messages, MessageIndex)

if #Messages == 0 then -- // If message == 0 then we will delete the player from Chat.Players.
	Chat.Players[Player.Name] = nil
end 

FadeOutMessage:Play()
FadeOutText:Play()
FadeOutMessage.Completed:Wait()
messageLabel:Destroy()

end

function Chat:FilterContent(Player, str) – // Filter message.
local Success, FilteredStr = pcall(TextService.FilterStringAsync, TextService, str, Player.UserId, Enum.TextFilterContext.PublicChat)

if Success then
	return FilteredStr:GetChatForUserAsync(Player.UserId)
else
	return ""
end

end

function Chat:PushMessages(Player, direction)
local Character = Player.Character
local BubbleChatUI = Character.Head.BubbleChatUI

for i = 1, 4 do
	local MessageLabel = BubbleChatUI:FindFirstChild(tostring(i))
	if MessageLabel then
		local LastMessage = BubbleChatUI:FindFirstChild(tostring(i-1))
		local MessageYSize =  math.floor(MessageLabel.Size.Y.Scale * 100) / 100
		local MessageYChange = (MessageYSize == 0.2 and 0.75 or 0.85)
		local LMessageYSize 
		local MessageYChange2
		
		if LastMessage then
			LMessageYSize = math.floor(LastMessage.Size.Y.Scale * 100) / 100
			MessageYChange2 = LMessageYSize == 0.1 and 0.1 or 0.2
		end
		
		MessageLabel.YPos.Value = LastMessage ~= nil 
		and (LastMessage.YPos.Value - 0.1 - (MessageYSize == 0.1 and 0 or 0.1)) --and (MessageYSize == 0.2 and 0.1 or 0) or 0))
		or (direction == 1 and (MessageYChange - 0.1)
	    or (MessageYChange))
		
	    TweenService:Create(MessageLabel, TweenInfo.new(0.3), {
	        Position = UDim2.new(
	            MessageLabel.Position.X.Scale, 
	            0,
	            MessageLabel.YPos.Value,
	            0
	        ) 
	    }):Play()
	end
end

end

function Chat:Typing(Player, IsTyping)
local Messages = nil
local Character = Player.Character
local BubbleChatUI = Character.Head.BubbleChatUI
if Chat.Players[Player.Name] ~= nil then Messages = Chat.Players[Player.Name].Messages end

if IsTyping and BubbleChatUI:FindFirstChild("TypingLabel") == nil then
    local TypingLabel = ReplicatedStorage.Assets.BubbleChat.TypingLabel:Clone()
    TypingLabel.Position = UDim2.new(0.15, 0, 1.1, 0)
	TypingLabel.Parent = BubbleChatUI
	
    Chat:PushMessages(Player, 1)

    TweenService:Create(TypingLabel, TweenInfo.new(0.3), {
        Position = UDim2.new(0.15, 0, 0.85, 0)
    }):Play()

    repeat 
        wait(0.05)
		for i = 1, 3 do
			local Dot = TypingLabel:FindFirstChild("Dot"..i)
			if TypingLabel:FindFirstChild("Dot"..i) == nil then break end
			
			local DotTween = TweenService:Create(Dot.UIScale, TweenInfo.new(0.3, Enum.EasingStyle.Sine, Enum.EasingDirection.In, 0, true, 0), {
       			Scale = 2
			})
			DotTween:Play()
			DotTween.Completed:Wait()
		end
    until TypingLabel == nil
else
	if BubbleChatUI:FindFirstChild("TypingLabel") == nil then return end
	
	local TweenOut = TweenService:Create(BubbleChatUI.TypingLabel, TweenInfo.new(0.3), {
		Position = UDim2.new(0.15, 0, 1.1, 0)
	})
		
	if #Messages > 0 and (tick()-Messages[#Messages].Time) >= 1.5 then 
		Chat:PushMessages(Player, 0) 
	elseif #Messages == 0 then
		TweenOut:Play()
		TweenOut.Completed:Wait()
	end
	
	BubbleChatUI.TypingLabel:Destroy()
end

end

function Chat:CreateMessageLabel(bubblechatUI, content)
local LabelHeight = #content >= 30 and 0.2 or 0.1

local MessageLabel = ReplicatedStorage.Assets.BubbleChat.MessageLabel:Clone()
MessageLabel.TextBox.Text = content
MessageLabel.Size = UDim2.new(0.7, 0, LabelHeight, 0)
MessageLabel.Position = UDim2.new(0.15, 0, LabelHeight == 0.1 and 0.85 or 0.75, 0)
MessageLabel.Parent = bubblechatUI

return MessageLabel

end

function Chat:SendMessage(Player, str)
local Character = Player.Character
local FilteredContent = Chat:FilterContent(Player, str)

if Character == nil then return end -- // Doesn't run if character doesn't exist.

if not Chat.Players[Player.Name] then
    Chat.Players[Player.Name] = {
		Spamming = nil,
		Messages = {}
	}
end

local PlayerStuff = Chat.Players[Player.Name]

local Messages = PlayerStuff.Messages
UpdateMessageNames(Player)
local MessageLabel = Chat:CreateMessageLabel(Character.Head.BubbleChatUI, FilteredContent)

local Message = {}
Message.Content = FilteredContent
Message.Time = tick()
Message.Instance = MessageLabel
MessageLabel.Name = 1
MessageLabel.Time.Value = Message.Time
MessageLabel.YPos.Value = MessageLabel.Position.Y.Scale

Chat:PushMessages(Player, 0)

table.insert(Messages, Message)

if #Messages >= 4 then
	Chat:DeleteMessage(Player, 1)
	print("Too many messages--deleting messsage 1.")
end

wait(10)
Chat:DeleteMessage(Player, MessageLabel)
print("Done deleting message " .. MessageLabel.Name)

end

return Chat

maybe that’s the problem

is very good :+1: :slight_smile:

Hi! I deeply apologize for that big mobile typing bug. I went ahead and fixed that and also did minor changes to the Chat module. I know I’ve avoided working on this project again because it’s a whole mess and like I said before, I wouldn’t use this for production but rather as a learning resource. But you are free to do what you want with it. If you feel like putting it in a game, go for it!

Anyways you can get the latest updates from the model here: Custom Bubble Chat By Alphexus - Roblox

I have an error trying to use this custom chat. When I say something in chat the custom bubble appears but the default Roblox bubble appears too. How can I fix it?

If you enabled the default bubble chat by going to Chat and in the properties enabled BubbleChatEnabled then just disable it. But if you used the old way and enabled it by pasting the scripts into Chat then just delete those scripts.

1 Like