this doesnt look good because the 2 chats are separated and stack separately ( the chat service is the bottom chat)
is there a way to make the chat look like its coming from the player?
i dont want it to be server sided or etc, i just want it to look like theyre chatting from my perspective
you can’t really fake a real player message on the default chat GUI without server authority
(and that’d be a huge exploit) so most people inject a system message that looks like it came from them;
local StarterGui = game:GetService("StarterGui")
local function fakeChat(name, msg)
StarterGui:SetCore("ChatMakeSystemMessage", {
Text = string.format("[%s]: %s", name, msg);
Color = Color3.fromRGB(255,255,255);
Font = Enum.Font.SourceSans;
TextSize = 18;
})
end
-- example
fakeChat("Player1", "Hello")
Wait, I forgot they use TextChatService now and LegacyChatService is deprecated even tho it still works, I’ll look up how to do it with the new TextChatService API and get back to you.
As far as I know, there is no offset property for the chat. The only solution I can think of is to have a part or other kind of instance above the player’s head. When making someone chat, use that instance instead of the character.
I didn’t know myself until I read through the docs on how we could achieve this, also watched this video,
I’ve simply just adapted the script to work with TextChatService.
local TextChatService = game:GetService("TextChatService")
local head = script.Parent.Head -- or whatever part you want the bubble above
task.wait(5)
TextChatService:DisplayBubble(head, "Hello")
when a real message and a fake message is sent they overlap, is there a way to make the fake messages stack with the real messages?
edit: if there isnt, this should work good, Thank u for helping
OK maybeeee, I believe I found something that could work, normal docs Bubble Chat TextChatService
Adornee is the part the bubble is attached to,
weird name I know lol, we should be able to do it by grabbing the generated BillboardGui and tweak its StudsOffset and, in theory, would serve as a fix.
We have to override the default bubble behavior,
we should be able to do that by hooking OnBubbleAdded
local TextChatService = game:GetService("TextChatService")
local head = script.Parent:WaitForChild("Head")
local stackIndex = 0
TextChatService.OnBubbleAdded = function(msg, adornee)
if adornee == head then
stackIndex += 1
local gui = adornee:FindFirstChildWhichIsA("BillboardGui", true)
if gui then
gui.StudsOffset = Vector3.new(0, 3 + (stackIndex-1) * 0.6, 0)
task.delay(gui:GetAttribute("Lifetime") or 5, function()
stackIndex = math.max(0, stackIndex - 1)
end)
end
end
end
TextChatService:DisplayBubble(head, "Hello")
local function KeybindPressed(Input, Gpe)
if not ChangingKeybind and Input.UserInputType == Enum.UserInputType.Keyboard and not Gpe and CurrentChatter then
for _, list in ScrollingFrameChildren do
if Input.KeyCode.Name == list.Text then
local textBox = list:FindFirstChild("TextBox")
--TextChat:Chat(CurrentChatter.HumanoidRootPart, textBox.Text)
TextChatService:DisplayBubble(CurrentChatter.Head, textBox.Text)
(i put onbubbleadded function and stackidnex variable above it)
Lmk if you notice if i did something wrong
idk if it doesnt work but, it should be fine without overlaying
thank u alot for the help
local TextChatService = game:GetService("TextChatService")
local npc = workspace:WaitForChild("NPC")
local head = npc:WaitForChild("Head")
local function sayStacked(lines, pause)
pause = pause or 1 -- wait in seconds
for _, text in ipairs(lines) do
TextChatService:DisplayBubble(head, text)
task.wait(pause) -- before next line
end
end
task.wait(2)
sayStacked({
"Hello, I am Tix",
"this line pops after 1 second",
"and another 1 second later"
}, 1)