How do I make sure that the script only clones the UI whenever it isn't opened?

Whenever I touch a part I want it to only clone the UI into the player gui only if the UI isn’t already inside of the player gui.

If I step off and back onto the part it will clone the UI into the player gui even if the UI is already on screen.

I’ve tried adding a cooldown which slowed the cloning but it wasn’t really want I wanted. I’ve also looked at multiple other Topics that are similar but they just didn’t work.

here is my script for touching the part and cloning the UI

local debounce = false
local cooldown = 0

script.Parent.Touched:Connect(function(hit)
	if hit.Parent:FindFirstChild("Humanoid") then
		if debounce == false then
			debounce = true
			print("cloned")

			local gui = script.Parent.NpcDialogue:Clone()
			local player = game.Players:GetPlayerFromCharacter(hit.Parent)

			local guiStyle = Enum.EasingStyle.Quad
			local guiDirection = Enum.EasingDirection.Out

			local noTalking = "13834387600"

			gui.Frame.bloxGear.Visible = false
			gui.Frame.call.Visible = true
			
			gui.Frame.bloxGear.static2.Frame.guy.Image = string.format("rbxthumb://type=Asset&id=%s&w=420&h=420", noTalking)
			
			gui.Parent = player.PlayerGui
				
			gui.Frame.Size = UDim2.new(0,0,0,0)
			gui.Frame:TweenSize(UDim2.new(0.661,0,0.608,0), guiDirection, guiStyle, 0.25, false)
			
			wait(cooldown)
			debounce = false
		end
	end
end)
5 Likes

just do

if player.PlayerGui:FindFirstChild("NpcDialogue") then return end

OR

local debounce = false
local cooldown = 0
local alreadyCloned = {}

script.Parent.Touched:Connect(function(hit)
	if hit.Parent:FindFirstChild("Humanoid") then
		if debounce == false then
			debounce = true

            local player = game.Players:GetPlayerFromCharacter(hit.Parent)
			
            if alreadyCloned[player] then 
                return 
            else 
                alreadyCloned[player] = true
            end

			local gui = script.Parent.NpcDialogue:Clone()
			

			local guiStyle = Enum.EasingStyle.Quad
			local guiDirection = Enum.EasingDirection.Out

			local noTalking = "13834387600"

			gui.Frame.bloxGear.Visible = false
			gui.Frame.call.Visible = true
			
			gui.Frame.bloxGear.static2.Frame.guy.Image = string.format("rbxthumb://type=Asset&id=%s&w=420&h=420", noTalking)
			
			gui.Parent = player.PlayerGui
				
			gui.Frame.Size = UDim2.new(0,0,0,0)
			gui.Frame:TweenSize(UDim2.new(0.661,0,0.608,0), guiDirection, guiStyle, 0.25, false)
			
			wait(cooldown)
			debounce = false
		end
	end
end)
3 Likes

maybe add a “opened” bool with a default value of false that updates to true when it is opened and back to false when it is closed. when touching the part, only clone it if the aforementioned bool is set to false.

like this:

local opened = false

script.Parent.Touched:Connect(function(hit)
	if hit.Parent:FindFirstChild("Humanoid") then
		if opened == false then
			opened = true
			print("cloned")

			local gui = script.Parent.NpcDialogue:Clone()
			local player = game.Players:GetPlayerFromCharacter(hit.Parent)

			local guiStyle = Enum.EasingStyle.Quad
			local guiDirection = Enum.EasingDirection.Out

			local noTalking = "13834387600"

			gui.Frame.bloxGear.Visible = false
			gui.Frame.call.Visible = true
			
			gui.Frame.bloxGear.static2.Frame.guy.Image = string.format("rbxthumb://type=Asset&id=%s&w=420&h=420", noTalking)
			
			gui.Parent = player.PlayerGui
				
			gui.Frame.Size = UDim2.new(0,0,0,0)
			gui.Frame:TweenSize(UDim2.new(0.661,0,0.608,0), guiDirection, guiStyle, 0.25, false)
		end
	end
end)

from there you can add code to set opened to false when the GUI is closed.

2 Likes

Whenever I tried stepping onto the part for the second time it didn’t clone it. Is that something wrong with the placement of my script or the type of script or did I not make it correctly?

1 Like

I misread your post, do you mean to say you want the UI to clone when the UI isn’t visible?

1 Like

Oh my bad, yeah thats what I meant.

1 Like

But I don’t see any part where the UI is turned invisible

1 Like

Thats because I put it into another script because I didn’t really know what I was doing. I can show the script if you need it

1 Like

Yes, could you show it please? Also you want to destroy the existing copy before cloning again?

1 Like

I have two scripts that make them invisible one is if you don’t press the enter key and one is if you do the press the enter key

script 1:

local cooldown = 5

local gui = script.Parent
local guiStyle = Enum.EasingStyle.Quad
local guiDirection = Enum.EasingDirection.Out

wait(cooldown)
if gui.Frame.bloxGear.Visible == false then
	wait(1)
	gui.Frame.Size = UDim2.new(0.661,0,0.608,0)
	gui.Frame:TweenSize(UDim2.new(0,0,0,0), guiDirection, guiStyle, 0.25, false)
	wait(0.25)
	gui.Frame.Visible = false
	wait()
	gui:Destroy()
end
script 2:


local cooldown = 3
local UIS = game:GetService(“UserInputService”)

local Messages = {“in life there’s roblox”, “don’t let nothing stop you cause we ain’t stopping”}

UIS.InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.Keyboard then
if input.KeyCode == Enum.KeyCode.Return then
local gui = script.Parent
local dialogue = script:FindFirstChild(“dialogue”)
local openNoise = script:FindFirstChild(“open”)
local closeNoise = script:FindFirstChild(“close”)
local bloxGear = gui.Frame.bloxGear

		local guiStyle = Enum.EasingStyle.Quad
		local guiDirection = Enum.EasingDirection.Out

		local noTalking = "13834387600"
		local talking = "13833621044"

		bloxGear.Visible = false
		bloxGear.Visible = true
		bloxGear.static.Frame.Visible = false
		bloxGear.static2.Frame.Visible = false
		bloxGear.static.Frame.Size = UDim2.new(0,0,0,0)
		bloxGear.static2.Frame.Size = UDim2.new(0,0,0,0)

		wait(0.75)
		bloxGear.static.Frame.Visible = true
		bloxGear.static2.Frame.Visible = true
		bloxGear.static.Frame.Size = UDim2.new(1,0,0,0)
		bloxGear.static2.Frame.Size = UDim2.new(1,0,0,0)
		bloxGear.static.Frame:TweenSize(UDim2.new(1,0,1,0), guiDirection, guiStyle, 0.25, false)
		bloxGear.static2.Frame:TweenSize(UDim2.new(1,0,1,0), guiDirection, guiStyle, 0.25, false)
		dialogue:Play()
		openNoise:Play()
		wait(0.25)
		bloxGear.static.ImageTransparency = 1
		bloxGear.static2.ImageTransparency = 1
		bloxGear.static.Frame.BackgroundTransparency = 1
		bloxGear.static2.Frame.BackgroundTransparency = 1
		wait(1.75)
		for i, v in pairs(Messages) do
			for i = 1, string.len(v) do wait(0.045)
				gui.Frame.DialogueText.Text = string.sub(v, 1, i)
				bloxGear.static2.Frame.guy.Image = string.format("rbxthumb://type=Asset&id=%s&w=420&h=420", talking)
				wait(0)
				bloxGear.static2.Frame.guy.Image = string.format("rbxthumb://type=Asset&id=%s&w=420&h=420", noTalking)
			end
			wait(1)
		end
		bloxGear.static.ImageTransparency = 0
		bloxGear.static2.ImageTransparency = 0
		bloxGear.static.Frame.BackgroundTransparency = 0
		bloxGear.static2.Frame.BackgroundTransparency = 0
		wait(0.25)
		bloxGear.static.Frame.Size = UDim2.new(1,0,1,0)
		bloxGear.static2.Frame.Size = UDim2.new(1,0,1,0)
		bloxGear.static.Frame:TweenSize(UDim2.new(1,0,0,0), guiDirection, guiStyle, 0.25, false)
		bloxGear.static2.Frame:TweenSize(UDim2.new(1,0,0,0), guiDirection, guiStyle, 0.25, false)
		closeNoise:Play()
		wait(1)
		gui.Frame.Size = UDim2.new(0.661,0,0.608,0)
		gui.Frame:TweenSize(UDim2.new(0,0,0,0), guiDirection, guiStyle, 0.25, false)
		wait(0.25)
		gui.Frame.Visible = false
		wait()
		gui:Destroy()
	end
end

end)


the second one is kinda messy but the end is basically the same for both

(sorry for making it messy idk how to fix it)
1 Like
local debounce = false
local cooldown = 0
local alreadyCloned = {}

script.Parent.Touched:Connect(function(hit)
	if hit.Parent:FindFirstChild("Humanoid") then
		if not debounce then
			debounce = true

            local player = game.Players:GetPlayerFromCharacter(hit.Parent)
			
            if player.PlayerGui:FindFirstChild("NpcDialogue") then return end

			local gui = script.Parent.NpcDialogue:Clone()
			

			local guiStyle = Enum.EasingStyle.Quad
			local guiDirection = Enum.EasingDirection.Out

			local noTalking = "13834387600"

			gui.Frame.bloxGear.Visible = false
			gui.Frame.call.Visible = true
			
			gui.Frame.bloxGear.static2.Frame.guy.Image = string.format("rbxthumb://type=Asset&id=%s&w=420&h=420", noTalking)
			
			gui.Parent = player.PlayerGui
				
			gui.Frame.Size = UDim2.new(0,0,0,0)
			gui.Frame:TweenSize(UDim2.new(0.661,0,0.608,0), guiDirection, guiStyle, 0.25, false)
			
			wait(cooldown)
			debounce = false
		end
	end
end)
3 Likes

hm it didn’t work again maybe its because the removing of the UI and the cloning of the UI are in different scripts? Its probably also because its really messy but idk how to fix that part.

Lemme show you what its doing.

1 Like

It only allows me to do it once but not again not really sure what to do.

1 Like

Hey I’m on mobile and I’m going to bed here now but I wanted to put my two cents in, from briefly reading through the post if you are adding the gui in through server but destroying it on client even though client knows the gui no longer exist server still believes it’s an active member of your playergui, hopefully the person assisting you can help you out further with this so good luck and hope you figure it out :+1:

2 Likes

Does that mean I would have to switch it to make it so its only cilent or only server instead of both? Or should I try to make it so both know that its not active currently?

(thanks for the take btw)

1 Like

Just got it, thanks to @wallofgarlic for pointing it out, there are two approaches you can adopt, either:

A. Make the touched event server sided and fire a remote server which clones the gui after doing the gui existing check on the client side.

B. Make the touched event client sided and handle everything on the client side.

2 Likes

All my scripts are local scripts except the script to activate the UI so should I switch that script over to a local script aswell?

script showcase

(UI_Limit doesn’t have anything its just a script that I tried to use to fix this issue)
(also dont mind how messy it is lol)

Im thinking of choosing to make it all cilent sided because I only want the player who touched the part to see the UI. But im not really sure how to switch it over.

1 Like

Alright cool, then you don’t need a server script, but keep in mind that in this approach the client has full control over everything.

  • Create a LocalScript named TriggerUI and in it paste.
local Players = game:GetService("Players")
local debounce = true

script.Parent.Touched:Connect(function(hit)
	if hit.Parent:FindFirstChild("Humanoid") then
		if not debounce then
			debounce = true

            local player = Players:GetPlayerFromCharacter(hit.Parent)

            if player ~= Players.LocalPlayer then return end

	        local playerGui = player.PlayerGui

            if playerGui:FindFirstChild("NpcDialogue") then return end

			local gui = script.Parent.NpcDialogue:Clone()

			local guiStyle = Enum.EasingStyle.Quad
			local guiDirection = Enum.EasingDirection.Out

			local noTalking = "13834387600"

			gui.Frame.bloxGear.Visible = false
			gui.Frame.call.Visible = true
			
			gui.Frame.bloxGear.static2.Frame.guy.Image = string.format("rbxthumb://type=Asset&id=%s&w=420&h=420", noTalking)
			
			gui.Parent = playerGui
				
			gui.Frame.Size = UDim2.new(0,0,0,0)
			gui.Frame:TweenSize(UDim2.new(0.661,0,0.608,0), guiDirection, guiStyle, 0.25, false)
			
			debounce = false
		end
	end
end)
1 Like

Is it supposed to be inside of the part or the UI?

1 Like

Part

1 Like