How can I make text appear similarly to Undertale?

So im making a dialog system for my game, and im wondering how I could make the text appear similarly to the game below:


I honestly have no idea how to do this so any help is appreciated

1 Like

Tween/Lerp the MaxVisibleGraphemes property of the TextLabel/TextButton with utf8.len(STRING) as the value.

3 Likes

what about the sound? i cant figure out how id do that…

Well, if you plan on tweening it you could use the .Changed signal and watch for changes in the text and play a sound if the string length increases, but personally, I recommend using a loop or using any of the RunService signals so you can add small pauses as seen in the video when certain characters are about to be shown/or have been shown.

If this is still a vague answer I can submit 2 very old but usable sample codes I made 2-3 years back when I first started learning luau.

1 Like

It would be nice if you sent those samples because I havent really worked with doing stuff like this yet

You can take a crack at this one, please keep in mind they came from a very early project of mine when I first started developing so they will be buggy.
However, it should still be good enough for you to get an understanding and explore more creative options.

--local Script
local UserInputService = game:GetService("UserInputService")


UserInputService.InputBegan:Connect(function(Input,Gpe)
	if Gpe then return end
	if Input.UserInputType == Enum.UserInputType.Keyboard then
		if Input.KeyCode == Enum.KeyCode.Q then
			local DialogueModule = require(script.DialogueModule)

			DialogueModule.Method1(
				{
					Time = 10,
					Text = [[
	This is a test. <b>
	I've accepted this test to stand victorious against my past.
	A person grows once they are able to defeat their weaker self.
	Wouldn't you agree, Jean Pierre Polnareff</b>]],
					Sound = script.SpeechNoise,
					PitchRange = 0,
					SpeakingNoiseDelay = 0.075,
				}
			)
		end
	end
end)
--Module Script
> local RunService = game:GetService("RunService")
local Players = game:GetService("Players")

local LocalPlayer = Players.LocalPlayer
local PlayerGui = LocalPlayer:WaitForChild("PlayerGui")
local module = {}

function module.Method1(DialogueData)
	local ScreenGui,TextLabel,SpeakingSound = Instance.new("ScreenGui"),Instance.new("TextLabel"),(DialogueData.Sound or game.ReplicatedStorage.Sounds.TyperWriterClack):Clone()
	local ElaspedTime,DialogueRenderKey,LastSoundTick = 0,"DialogueRenderKey"..tick(),tick()

	ScreenGui.IgnoreGuiInset,TextLabel.RichText = true,true

	TextLabel.AnchorPoint,TextLabel.TextScaled = Vector2.new(.5,.5),true
	TextLabel.Position,TextLabel.Size = UDim2.fromScale(.5,.75),UDim2.fromScale(.45,.25)
	TextLabel.Text = DialogueData.Text
	TextLabel.MaxVisibleGraphemes = 0

	RunService:BindToRenderStep(DialogueRenderKey,Enum.RenderPriority.Camera.Value,function(DeltaTime)
		ElaspedTime+=DeltaTime
		local ClampResult = math.clamp(ElaspedTime/DialogueData.Time or 2.5,0,1)
		TextLabel.MaxVisibleGraphemes = utf8.len(DialogueData.Text) * ClampResult
		if tick()-LastSoundTick > DialogueData.SpeakingNoiseDelay then
			LastSoundTick = tick()
			SpeakingSound:Play()
			SpeakingSound.PlaybackSpeed = math.random(100-DialogueData.PitchRange,100+DialogueData.PitchRange)/100
		end
		if ClampResult >= 1 then RunService:UnbindFromRenderStep(DialogueRenderKey) task.wait(1) ScreenGui:Destroy()end
	end)
	ScreenGui.Parent,TextLabel.Parent,SpeakingSound.Parent = PlayerGui,ScreenGui,ScreenGui
end


return module

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.