TextFits not correctly detecting

Hey everyone. I’ve once again encountered some problems with my dialog system so I need some more help. :sweat_smile:

I’ve revamped my dialog system, but I’ve noticed that TextFits does not detect whether or not the text actually fits correctly. TextFits only returns false after the text is already out of bounds.
Here’s a video of it happening:

return function(toad)
	local Players = game:GetService("Players")
	local TextService = game:GetService("TextService")

	local Dialog = toad.Class("Dialog")
	local Maid = toad.Maid

	function Dialog:__init()
		local _Maid = Maid.new()

		self.GUI = script:FindFirstChild("Dialog"):Clone()
		self.GUI.Parent = toad.PlayerGui

		local Shadow = toad.RoStrap:LoadLibrary("PseudoInstance").new("Shadow")
		Shadow.Elevation = 8
		Shadow.Parent = self.GUI.Back

		local label:TextLabel= toad.PlayerGui:WaitForChild("Dialog").Back.Text
		self.label = label
		local Params = Instance.new("GetTextBoundsParams")
		self.Params = Params
		self.Params.Text = label.Text
		self.Params.Font = label.FontFace
		self.Params.Size = label.TextSize
		self.Params.Width = label.AbsoluteSize.X

		function self.VerifyBounds(label, Text)
			self.Params.Text = Text
			self.Params.Font = label.FontFace
			self.Params.Size = label.TextSize
			self.Params.Width = label.AbsoluteSize

			return TextService:GetTextBoundsAsync(self.Params)
		end

		self._Maid = _Maid

		
		self.MouseEvent = game:GetService("Players").LocalPlayer:GetMouse().Button1Down
		
		_Maid:GiveTask(self.MouseEvent)

		label.MaxVisibleGraphemes = 0
		label.Text = ""

	end

	function Dialog:say(Text, ii)
		local GUI = self.GUI
		local _Maid = self._Maid
		local TextLabel : TextLabel = self.label

		local function removeTags(str)
			str = str:gsub("<br%s*/>", "\n")
			return (str:gsub("<[^<>]->", ""))
		end

		local Text = removeTags(Text)

		TextLabel.Text = "" --Text
		--[[
		local test = TextLabel:Clone()
		test.Text = ""
		test.Parent = TextLabel.Parent
		test.Visible = false
		test.MaxVisibleGraphemes = -1]]

		local incompleteWord = ""
		
		local SEQUENCE = {}
		
		local function Calculate()
			TextLabel.Visible = false
			for f, l in utf8.graphemes(Text) do
				local g = Text:sub(f, l) 
				TextLabel.Text = TextLabel.Text .. g
				
				if TextLabel.TextFits == false then
					--print(TextLabel.Text)
					if TextLabel.TextFits then
						-- yay!
						
						table.insert(SEQUENCE, TextLabel.Text)
						TextLabel.Text = ""
					else
						-- uh oh... 
						
						
						table.insert(SEQUENCE, TextLabel.Text)
						TextLabel.Text = ""
					end
				end
			end
		end
		Calculate()
		TextLabel.Text = Text
		TextLabel.Visible = true
		local function Write(S)
			TextLabel.Text = S
			TextLabel.MaxVisibleGraphemes = 0
			for f, l in utf8.graphemes(S) do
				TextLabel.MaxVisibleGraphemes = f
				toad.QuickWait(.02)
			end
		end
		for _, v in pairs(SEQUENCE) do
			Write(v)
		end

		
		print("reached!")
		_Maid:Destroy()
		return
	end

	return Dialog
end

What is it that I’m doing incorrectly?

You’re checking the TextFits value twice. The second if statement will only run if the first if statement is false, which means that the line if TextLabel.TextFits then will never be true

I revised my script, but there are still two problems. It’s really lag iducing and TextFits also doesn’t detect correctly.

Here’s my current script:

return function(toad)
	local Players = game:GetService("Players")
	local TextService = game:GetService("TextService")

	local Dialog = toad.Class("Dialog")
	local Maid = toad.Maid

	function Dialog:__init()
		local _Maid = Maid.new()

		self.MessageParts = {}

		self.GUI = script:FindFirstChild("Dialog"):Clone()
		self.GUI.Parent = toad.PlayerGui

		local Shadow = toad.RoStrap:LoadLibrary("PseudoInstance").new("Shadow")
		Shadow.Elevation = 8
		Shadow.Parent = self.GUI.Back

		local label:TextLabel= toad.PlayerGui:WaitForChild("Dialog").Back.Text
		self.label = label
		local Params = Instance.new("GetTextBoundsParams")
		self.Params = Params
		self.Params.Text = label.Text
		self.Params.Font = label.FontFace
		self.Params.Size = label.TextSize
		self.Params.Width = label.AbsoluteSize.X

		function self.VerifyBounds(label, Text)
			self.Params.Text = Text
			self.Params.Font = label.FontFace
			self.Params.Size = label.TextSize
			self.Params.Width = label.AbsoluteSize

			return TextService:GetTextBoundsAsync(self.Params)
		end

		self._Maid = _Maid


		self.MouseEvent = game:GetService("Players").LocalPlayer:GetMouse().Button1Down

		_Maid:GiveTask(self.MouseEvent)

		label.MaxVisibleGraphemes = 0
		label.Text = ""

	end

	function Dialog:say(Text, ii)
		local GUI = self.GUI
		local _Maid = self._Maid
		local TextLabel : TextLabel = self.label

		local function removeTags(str)
			str = str:gsub("<br%s*/>", "\n")
			return (str:gsub("<[^<>]->", ""))
		end

		local Text = removeTags(Text)
		print(Text)

		TextLabel.Text = "" --Text
		--[[
		local test = TextLabel:Clone()
		test.Text = ""
		test.Parent = TextLabel.Parent
		test.Visible = false
		test.MaxVisibleGraphemes = -1]]

		local SEQUENCE = {}

		local function Calculate()
			TextLabel.Visible = false
			local ind = 1
			while ind < utf8.len(Text) do

				local g = Text:sub(ind, ind) 
				TextLabel.Text = TextLabel.Text .. g
				if TextLabel.TextFits == false then
					--print(TextLabel.Text)
					local LastSpace = TextLabel.Text:match("^.*() ")
					if not LastSpace then
						warn("?")
					end
					TextLabel.Text = Text:sub(1, LastSpace - 1)
					

					if TextLabel.TextFits then
						-- yay!
						ind = LastSpace
						print("Fits")

						table.insert(SEQUENCE, TextLabel.Text)
						print(TextLabel.Text)
						TextLabel.Text = ""
						--ind += 1
					else
						-- uh oh...
						
						print("No..")

						table.insert(SEQUENCE, TextLabel.Text)
						TextLabel.Text = ""
					end
				else
					if ind + 1 == utf8.len(Text) then
						table.insert(SEQUENCE, TextLabel.Text .. Text:sub(ind+1, ind+1))
					end
					ind = ind + 1
				end
				
			end
		end
		Calculate()
		--TextLabel.Text = Text
		TextLabel.Visible = true
		local function Write(S)
			TextLabel.Text = S
			TextLabel.MaxVisibleGraphemes = 0
			for f, l in utf8.graphemes(S) do
				TextLabel.MaxVisibleGraphemes = f
				toad.QuickWait(.02)
			end
		end
		for _, v in pairs(SEQUENCE) do
			Write(v)
			self.MouseEvent:Wait()
		end


		print("reached!")
		--_Maid:Destroy()
		return
	end

	return Dialog
end

I suggest also using TextService:GetTextSize() to help detect whether the text will go out of bounds of your TextLabel. If TextFits is false and :GetTextSize() still results in a size larger than the size of the label then reduce the amount of characters in the text until TextFits changes to true

Couldn’t you just check that the Vector2 returned from GetTextBoundsAsync’s Y axis is larger than that of the TextLabel’s AbsoluteSize instead of checking textLabel.TextFits?

Just tried that, it returns the same Y everytime.

return function(toad)
	local Players = game:GetService("Players")
	local TextService = game:GetService("TextService")

	local Dialog = toad.Class("Dialog")
	local Maid = toad.Maid

	function Dialog:__init()
		local _Maid = Maid.new()

		self.MessageParts = {}

		self.GUI = script:FindFirstChild("Dialog"):Clone()
		self.GUI.Parent = toad.PlayerGui

		local Shadow = toad.RoStrap:LoadLibrary("PseudoInstance").new("Shadow")
		Shadow.Elevation = 8
		Shadow.Parent = self.GUI.Back

		local label:TextLabel= toad.PlayerGui:WaitForChild("Dialog").Back.Text
		self.label = label
		local Params = Instance.new("GetTextBoundsParams")
		self.Params = Params
		self.Params.Text = label.Text
		self.Params.Font = label.FontFace
		self.Params.Size = label.TextSize
		self.Params.Width = label.AbsoluteSize.X

		function self.VerifyBounds(label, Text)
			self.Params.Text = Text
			self.Params.Font = label.FontFace
			self.Params.Size = label.TextSize
			self.Params.Width = label.AbsoluteSize

			return TextService:GetTextBoundsAsync(self.Params)
		end

		self._Maid = _Maid


		self.MouseEvent = game:GetService("Players").LocalPlayer:GetMouse().Button1Down

		_Maid:GiveTask(self.MouseEvent)

		label.MaxVisibleGraphemes = 0
		label.Text = ""

	end

	function Dialog:say(Text, ii)
		local GUI = self.GUI
		local _Maid = self._Maid
		local TextLabel : TextLabel = self.label

		local function removeTags(str)
			str = str:gsub("<br%s*/>", "\n")
			return (str:gsub("<[^<>]->", ""))
		end

		local Text = removeTags(Text)

		TextLabel.Text = "" --Text
		--[[
		local test = TextLabel:Clone()
		test.Text = ""
		test.Parent = TextLabel.Parent
		test.Visible = false
		test.MaxVisibleGraphemes = -1]]

		local SEQUENCE = {}

		local function Calculate()
			TextLabel.Visible = false
			local ind = 1
			while ind < utf8.len(Text) do

				local g = Text:sub(ind, ind) 
				TextLabel.Text = TextLabel.Text .. g
				local v = self.VerifyBounds(TextLabel, TextLabel.Text) 
				print(v.Y)
				if v.Y >= TextLabel.AbsoluteSize.Y then
					
					local LastSpace = TextLabel.Text:match("^.*() ")
					if not LastSpace then
						warn("?")
					end
					TextLabel.Text = Text:sub(1, LastSpace - 1)
					

					if TextLabel.TextFits then
						-- yay!
						ind = LastSpace
						print("Fits")

						table.insert(SEQUENCE, TextLabel.Text)
						print(TextLabel.Text)
						TextLabel.Text = ""
						--ind += 1
					else
						-- uh oh...
						
						print("No..")

						table.insert(SEQUENCE, TextLabel.Text)
						TextLabel.Text = ""
					end
				else
					if ind + 1 == utf8.len(Text) then
						table.insert(SEQUENCE, TextLabel.Text .. Text:sub(ind+1, ind+1))
					end
					ind = ind + 1
				end
				
			end
		end
		Calculate()
		--TextLabel.Text = Text
		TextLabel.Visible = true
		local function Write(S)
			TextLabel.Text = S
			TextLabel.MaxVisibleGraphemes = 0
			for f, l in utf8.graphemes(S) do
				TextLabel.MaxVisibleGraphemes = f
				toad.QuickWait(.02)
			end
		end
		for _, v in pairs(SEQUENCE) do
			Write(v)
			self.MouseEvent:Wait()
		end


		print("reached!")
		--_Maid:Destroy()
		return
	end

	return Dialog
end