Spaces by username len not working :[

Hello Developers
This thread is a re-thread because I’m not sure if i should edit the other thread and make new one. Here’s the Original Thread. Well continuing on the topic. i got this problem where you add space depending on the name(like normal roblox chat). i fixed this last time by doing (Name len)+(Text Size) like the original thread i posted. so i assumed its now working so i continue doing other script needed for my game. Then i came to this, Multi-player test. i did the 2 player test then this happen to the chat. There’s an extended spaces on it. if there could be other script for this, please help me with the script.


Multi player test
image

Single player test
image


Thank you for helping me

You see, the thing with proportional fonts is that they have variable width. Most characters are wider than a space, but how much wider depends on the character.

What you need to do, and what the default Roblox ChatScripts do, is first:

  • Measure the width of a space. I’d do this by putting, say, 20 spaces in a label, then dividing its TextBounds.X by 20
  • Measure the width of whatever you’re trying to fill with spaces, then calculate how many spaces you need by math.ceil(desiredWidth / spaceWidth). Note the default ChatScripts use ceil but you may want to use round instead.

Or just use RichText (which wasn’t out at the time when the ChatScripts were first introduced). Here is the fastest way to escape a string for RichText, confirmed by benchmarks:

local escapes = {['&'] = '&amp;', ['<'] = '&lt;', ['>'] = '&gt;', ['"'] = '&quot;', ['\''] = '&apos;'}

local function __escape_gsub(match: string): string
	return escapes[match]
end

local function xmlEscape(text: string): string
	return string.gsub(text, '[&<>"\']', __escape_gsub)
end
1 Like

Is the Player name and the text chat box two separate elements or all apart of the same text box?

E.g.

Gui.Frame.PlayerName = player.Name
Gui.Frame.PlayerMessage = message

or

Gui.Frame.Message = player.Name..”: “..message

If the former, does the message box overlap the player name box or is it sized and positioned next to the Player name box?

i didn’t use rich text because users can just use “<b_>some text here</b_>” or change the rich text color making it destroy the game as there will be different color for each. like
Guessed the answer = green
User already answered = green
Kicked/ Banned = orange. That’s why i don’t use rich text

the username and the message are seperated.

That’s why I included xmlEscape - it makes <b> show up as the literal text <b> instead of actually making things bold. That’s because it replaces the brackets with &lt; and &gt;, which are special and show up as < and > without actually counting as a tag.

So what you’d do is something like:

line.Text = string.format('<b>%s:</b> %s', xmlEscape(speaker.DisplayName), xmlEscape(messageText))

Even if they tried to send <b>hi</b> for example, it would just show up as that instead of parsing as rich text.

2 Likes

does it also work with <font color="rgb(many combination)"> and <font color="#many combination>? because this is my first time doing that.

xmlEscape makes it so that no syntax at all works. To be perfectly clear, “escaping” converts a string into a different string that looks the same after being parsed by RichText. So for example, if someone sent <b>hi</b>, xmlEscape would convert it to &lt;b&gt;hi&lt;/b&gt;, which would then show up as <b>hi</b> in the GUI, without actually making anything bold.

Outside of xmlEscape, you can still use whatever syntax you want. So as long as you use '<b>' instead of xmlEscape('<b>'), it will show up as bold. Just make sure to put the username & chat message inside of xmlEscape.

'<b>' .. xmlEscape('<i>hi</i>') .. '</b>' would show up as <i>hi</i> in the GUI. Your <b> tag went through, but since the <i> was in the xmlEscape it didn’t apply. It’ll be the same if you use <font> instead of <b> - it’ll work outside the xmlEscape.

You can use TextService’s “:GetTextSize()” instance method to find the size of an area required to contain a single whitespace character of some font size & style. The same can be done for the player’s username with the same font size & style, then all you need to do is divide the latter by the former and math.ceil() the result in order to determine how many whole whitespace characters would be required to cover the length of the player’s username.

https://developer.roblox.com/en-us/api-reference/function/TextService/GetTextSize

This would be a more dynamic approach as opposed to using 20 whitespace characters (the maximum length of a username).

1 Like

image
well i tried your script but it makes it like this

well i made this script, im not kind of expert on it but

print(math.ceil(game:GetService('TextService'):GetTextSize(message, 26, Enum.Font.SourceSansBold,Vector2.new(1,1)) / game:GetService('TextService'):GetTextSize(" ", 26, Enum.Font.SourceSansBold,Vector2.new(1,1))))

this came the result,
image

Use Vector2.new(0, 0) and you need the X component of both returned Vector2 values.

could you elaborate more? because im so confused. my pea size brain is not currently working.

print(math.ceil(game:GetService('TextService'):GetTextSize(message, 26, Enum.Font.SourceSansBold,Vector2.new(0,0)).X / game:GetService('TextService'):GetTextSize(" ", 26, Enum.Font.SourceSansBold,Vector2.new(0,0)).X))

sorry for me taking too long to realize to use this and finally I figure it out. Thank you so much!

1 Like