I need help with Dialog system Text spacing

  1. What do you want to achieve? I’m trying to make animated text for my dialog system and I’m making it by creating a text label for each letter and making the position of the textlabel tween to the position with EasingStyle.Back to make a bounce effect.

  2. What is the issue? The line spacing is really broken right now, for example: Hello, World! = H e l lo , W or l d !

  3. What solutions have you tried so far? I looked everywhere, I tried finding any similar posts, and found nothing.

local TweenService = game:GetService("TweenService")
local TextService = game:GetService("TextService")

task.wait(1) -- so studio can load

local function animateLetter(letterLabel, targetPosition)
	local tweenInfo = TweenInfo.new(0.2, Enum.EasingStyle.Back, Enum.EasingDirection.Out)
	local positionTween = TweenService:Create(letterLabel, tweenInfo, { Position = targetPosition })
	positionTween:Play()
end

local function animateText(text, letterDelay, textSize)
	local startPosition = Vector2.new(0, 25)
	local lineHeight = 20
	local lineWidth = 0

	for i = 1, #text do
		local letter = string.sub(text, i, i)

		if letter ~= " " then
			local letterLabel = Instance.new("TextLabel")
			letterLabel.Parent = TextFrame
			letterLabel.Size = UDim2.new(0, 20, 0, 20)
			letterLabel.Font = Enum.Font.FredokaOne
			letterLabel.Text = letter
			letterLabel.TextSize = textSize
			letterLabel.TextColor3 = Color3.new(1, 1, 1)
			letterLabel.BackgroundTransparency = 1

			letterLabel.Position = UDim2.new(0, startPosition.X + lineWidth, 0, startPosition.Y)
			lineWidth = lineWidth + 3 * (textSize / 6)

			if lineWidth > TextFrame.AbsoluteSize.X * 2 then
				startPosition = Vector2.new(0, startPosition.Y + lineHeight)
				lineWidth = 0
			end

			animateLetter(letterLabel, letterLabel.Position)
		else
			lineWidth = lineWidth + textSize / 2
			if lineWidth > TextFrame.AbsoluteSize.X * 2 then
				startPosition = Vector2.new(0, startPosition.Y + lineHeight)
				lineWidth = 0
			end
		end

		task.wait(letterDelay)
	end
end

animateText("Welcome to my shop! I'm the fisherman! If you would like to buy a fishing rod they are $50 Tix each!", 0.05, 25) -- example use of the function, when its finished im going to use a bindable function for this.
1 Like

Hi. It appears that the spacing between the letters is uneven, resulting in the broken appearance of the text. This is likely due to how you’re calculating the lineWidth variable and positioning the letters. Here’s how you could fix it

local TweenService = game:GetService("TweenService")
local TextService = game:GetService("TextService")

task.wait(1) -- so studio can load

local function animateLetter(letterLabel, targetPosition)
	local tweenInfo = TweenInfo.new(0.2, Enum.EasingStyle.Back, Enum.EasingDirection.Out)
	local positionTween = TweenService:Create(letterLabel, tweenInfo, { Position = targetPosition })
	positionTween:Play()
end

local function animateText(text, letterDelay, textSize)
	local startPosition = Vector2.new(0, 0) 
	local lineHeight = textSize * 1.5 
	local lineWidth = 0

	for i = 1, #text do
		local letter = string.sub(text, i, i)

		if letter ~= " " then
			local letterLabel = Instance.new("TextLabel")
			letterLabel.Parent = TextFrame
			letterLabel.Size = UDim2.new(0, 20, 0, 20)
			letterLabel.Font = Enum.Font.FredokaOne
			letterLabel.Text = letter
			letterLabel.TextSize = textSize
			letterLabel.TextColor3 = Color3.new(1, 1, 1)
			letterLabel.BackgroundTransparency = 1

			local textDimensions = TextService:GetTextSize(letter, textSize, letterLabel.Font, Vector2.new(math.huge, math.huge))
			letterLabel.Position = UDim2.new(0, startPosition.X + lineWidth, 0, startPosition.Y)

			lineWidth = lineWidth + textDimensions.X + 5  -- Add spacing between letters

			if lineWidth > TextFrame.AbsoluteSize.X then
				startPosition = Vector2.new(0, startPosition.Y + lineHeight)
				lineWidth = 0
			end

			animateLetter(letterLabel, letterLabel.Position)
		else
			lineWidth = lineWidth + textSize / 2
			if lineWidth > TextFrame.AbsoluteSize.X then
				startPosition = Vector2.new(0, startPosition.Y + lineHeight)
				lineWidth = 0
			end
		end

		task.wait(letterDelay)
	end
end

animateText("Welcome to my shop! I'm the fisherman! If you would like to buy a fishing rod they are $50 Tix each!", 0.05, 25)

It didn’t really fix the issue, I’m currently debugging to see if I can find it… Here is an image if this helps (Sorry for replying so late, I didn’t realize someone was going to respond so fast)

Maybe we could try taking the letter size to make it all good? “TextService:GetTextSize()”

local TweenService = game:GetService("TweenService")
local TextService = game:GetService("TextService")

local TextFrame = 

task.wait(1) -- so studio can load

local function animateLetter(letterLabel, targetPosition)
    local tweenInfo = TweenInfo.new(0.2, Enum.EasingStyle.Back, Enum.EasingDirection.Out)
    local positionTween = TweenService:Create(letterLabel, tweenInfo, { Position = targetPosition })
    positionTween:Play()
end

local function animateText(text, letterDelay, textSize)
    local startPosition = Vector2.new(0, 0) 
    local lineHeight = textSize * 1.5 
    local lineWidth = 0

    for i = 1, #text do
        local letter = string.sub(text, i, i)

        if letter ~= " " then
            local letterLabel = Instance.new("TextLabel")
            letterLabel.Parent = TextFrame
            letterLabel.Size = UDim2.new(0, 20, 0, 20)
            letterLabel.Font = Enum.Font.FredokaOne
            letterLabel.Text = letter
            letterLabel.TextSize = textSize
            letterLabel.TextColor3 = Color3.new(1, 1, 1)
            letterLabel.BackgroundTransparency = 1

            local textDimensions = TextService:GetTextSize(letter, textSize, letterLabel.Font, Vector2.new(math.huge, math.huge))
            letterLabel.Position = UDim2.new(0, startPosition.X + lineWidth, 0, startPosition.Y)

            lineWidth = lineWidth + textDimensions.X 

            if lineWidth > TextFrame.AbsoluteSize.X then
                startPosition = Vector2.new(0, startPosition.Y + lineHeight)
                lineWidth = 0
            end

            animateLetter(letterLabel, letterLabel.Position)
        else
            lineWidth = lineWidth + textSize / 2
            if lineWidth > TextFrame.AbsoluteSize.X then
                startPosition = Vector2.new(0, startPosition.Y + lineHeight)
                lineWidth = 0
            end
        end

        task.wait(letterDelay)
    end
end

animateText("Welcome to my shop! I'm the fisherman! If you would like to buy a fishing rod they are $50 Tix each!", 0.05, 25)

It didn’t work, I’m really confused as I don’t see any issue in the code so far, this is the result of the code you made btw. (also the frame variable in a different part of the script I just didn’t copy it when sending the code, here is the part of the code i didn’t send)
local gui = script.Parent
local mainframe = gui.Frame
local viewportFrame = mainframe.ViewportFrame
local TextFrame = mainframe.TextFrame
image

I don’t see anything that could possibly create an error: if you keep looking, you’ll eventually find the error.

I’ll keep looking, there is no errors in console by the way, it may be a problem with the TextService:GetTextSize() function, let me read over the documentation again and make sure it’s not deprecated or something.

okay let me know if you get there

I figured out 2 things, firstly the word I’m looking for is not “text spacing” its “Kerning” Lol. Also I got the system to work much better (still not perfect as you can see with the “l” and the “d” in “World!”)