UI is Glitchy When Using UIS or Something Else

Hello developers! I’ve been working on this game, and I struggle with scripting with user interface a lot. I recently encountered this problem while working on my game, Wake Up. When I use UIS to detect when a player presses a key, in this case “e”, and implement that UIS to a user interface, it turns out all glitched and stuff. I have no idea what the problem is but I’m assuming it has something to do with that. Here is evidence of the glitch (the background/text/dialogue going default) and my code.

local BG = script.Parent.Parent.Parent.BlackBG
local DialogueText = script.Parent.Parent.Text
local DialogueFrame = script.Parent.Parent
local Alarm = game.Workspace.Sounds.AlarmClock
local Button = game.Workspace.Sounds.Button
local AlarmStop = script.Parent.Parent.Parent.StopAlarm
local UIS = game:GetService("UserInputService")
local Plr = game.Players.LocalPlayer

wait(2.5)

local function typewrite(object,text,length)
	for i = 1,#text,1 do
		local sound = Instance.new("Sound")
		sound.Parent = game.Workspace
		sound.SoundId = "rbxassetid://9120299506"
		sound.Name = "DialogSound"
		sound:Play()
		object.Text = string.sub(text,1,i)
		wait(length)
	end
	for i,v in pairs(game.Workspace:GetChildren()) do
		if v.Name == "DialogSound" then
			v:Destroy()
		end
	end
end

typewrite(script.Parent, "Waking up.", 0.05)
wait(4)
typewrite(script.Parent, "It's the easiest thing to do, yet the hardest.", 0.05)
wait(4)
game:GetService("TweenService"):Create(BG, TweenInfo.new(1), {BackgroundTransparency = 1}):Play()
game:GetService("TweenService"):Create(DialogueText, TweenInfo.new(1), {Transparency = 1}):Play()
game:GetService("TweenService"):Create(DialogueFrame, TweenInfo.new(1), {BackgroundTransparency = 1}):Play()
wait(0.5)
game:GetService("TweenService"):Create(AlarmStop, TweenInfo.new(1), {TextTransparency = 0}):Play()
Alarm:Play() 
Alarm.Looped = true
Plr:GetMouse().KeyDown:Connect(function(E)
	if E == "e" and AlarmStop.TextTransparency == 0 then
		Alarm.Looped = false
		Button.Volume = 10
		Button:Play()
		wait(2)
		game:GetService("TweenService"):Create(AlarmStop, TweenInfo.new(0.2), {TextTransparency = 1}):Play()
		game:GetService("TweenService"):Create(DialogueText, TweenInfo.new(0.2), {Transparency = 0}):Play()
		game:GetService("TweenService"):Create(DialogueFrame, TweenInfo.new(0.2), {BackgroundTransparency = 0}):Play()
		wait(2)
			typewrite(script.Parent, "What time is it?", 0.05)
			wait(3)
			game:GetService("TweenService"):Create(DialogueText, TweenInfo.new(1), {Transparency = 1}):Play()
	end
end)

By the way, the background/text/dialogue is supposed to be the “What time is it?” and formatted the same as the previous texts/dialogues.

If there is anything wrong with my code, please let me know ASAP. Thank you so much I appreciate it.

There are a couple of things you could address in a more efficient way.

One of them being this typewrite function:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local sound = ReplicatedStorage:WaitForChild("DialogueSound")

local function typewrite(object, text, length)
    for i = 1, #text, 1 do
        -- Instead of creating a new instance each time,
        -- just clone an existing one
        local writeSound = sound:Clone()
        sound.Parent = workspace
        sound:Play()
        
        object.Text = string.sub(text, 1, i)

        -- task.wait() > wait()
        task.wait(length)
    end

    -- Here you could do your for loop and destroy all of the sounds in
    -- workspace like before, or, after every sound is parented to the workspace
    -- set Sound.PlayOnRemove to true then destroy it

    -- Pseudo-code for that:

    --[[
        local writeSound = sound:Clone()
        sound.Parent = workspace
        sound.PlayOnRemove = true
        sound:Destroy()
    ]]
end

Another thing, you defined UserInputService but never even used it. You opted for a deprecated .KeyDown on the player’s mouse instead. Try something along the lines of:

local UserInputService = game:GetService("UserInputService")
local initialKeyPress = false

local function onInputBegan(inputObject, gameProcessed)
    if gameProcessed then
        return
    end

    -- If you only want it to occur when the player presses 'E', change to:
    -- if inputObject.KeyCode == Enum.KeyCode.E and (not initialKeyPress) then
    if not initialKeyPress then
        initialKeyPress = true
        
        -- Code to run once the player presses *any* key (only runs once)
    end
end

UserInputService.InputBegan:Connect(onInputBegan)

Some concluding notes, since you’re using the same TweenInfo for every tween (it seems like, so far), you can define that as a variable at the top of your code:

local defaultTween = TweenInfo.new(1)

Same with TweenService,

local TweenService = game:GetService("TweenService")

Those changes are just for readability though and are not required, as you may have noticed.

1 Like

Thank you so much! And do you know how to fix the issue with the UI? @NoParamaters