GUI That is Activated by a Proximity Prompt Only Works in Roblox Studio, not in the Actual Game

Ok, so I am embarrassingly new to scripting and don’t even know half of the Luau programming language, but I have been wanting to make a functional high quality game for a long time.

Anyways,
I have been trying to create a GUI for my horror game that is activated when a proximity prompt is triggered. I scripted it and from first glance in Roblox Studio, everything seemed fine and was working well.

Here is a video of the script in action on Roblox Studio:

So, the local script clearly functions well in Roblox Studio, but when I play the game and run the script on my PC and my mobile devices, it doesn’t work at all and the proximity prompt does nothing. (The script somehow works like 1/4 of the time on PC, however :unamused:)

Here is the local script I made:

-- --if there is any more efficent way to script this, please suggest ideas, im extremely new to scripting.😃

local t = script.Parent.Frame.TextLabel
local pp = game.Workspace.Teleport.ProximityPrompt
local sgui = script.Parent
local frame  = script.Parent.Frame
local sound = script.Parent.Frame.TextLabel.Sound
local sound1 = script.Parent.Frame.TextLabel.Sound1
local sound2 = script.Parent.Frame.TextLabel.sound
pp.Triggered:Connect(function()
	pp.Enabled = false
	task.wait(0.5)
	
--this creates a typewriter-like effect
    sgui.Enabled = true
	task.wait(2)
	t.Text = "C"
	sound1:Play()
	task.wait(0.1)
	t.Text = "CH"
	sound1:Play()
	task.wait(0.1)
	t.Text = "CHA"
	sound1:Play()
	task.wait(0.1)
	t.Text = "CHAP"
	sound1:Play()
	task.wait(0.1)
	t.Text = "CHAPT"
	sound1:Play()
	task.wait(0.1)
	t.Text = "CHAPTE"
	sound1:Play()
	task.wait(0.1)
	t.Text = "CHAPTER "
	sound1:Play()
	task.wait(0.1)
	t.Text = "CHAPTER T"
	sound1:Play()
	task.wait(0.1)
	t.Text = "CHAPTER TW"
	sound1:Play()
	task.wait(0.1)
	t.Text = "CHAPTER TWO"
	sound1:Play()
	
	task.wait(3.5)
	t.Text = "INSIDE"
	sound2:Play()
	sound:Play()
	task.wait(3)
	
	--this fades out the background
	frame.BackgroundTransparency = 1
	task.wait(1)
	t.TextTransparency = 0.1
	task.wait(0.1)
	t.TextTransparency = 0.2
	task.wait(0.1)
	t.TextTransparency = 0.3
	task.wait(0.1)
	t.TextTransparency = 0.4
	task.wait(0.1)
	t.TextTransparency = 0.5
	task.wait(0.1)
	t.TextTransparency = 0.6
	task.wait(0.1)
	t.TextTransparency = 0.7
	task.wait(0.1)
	t.TextTransparency = 0.8
	task.wait(0.1)
	t.TextTransparency = 0.9
	task.wait(0.1)
	t.TextTransparency = 1
	task.wait(0.1)
	sgui.Enabled = false
end)

Here is where I placed the local script:
Screenshot 2024-07-11 190745

I can’t tell if there is something wrong with my script that is prohibiting it from functioning properly outside of Roblox Studio or what, but I have been searching for answers across Youtube and previous DevForum posts and I still have no clue why it isn’t working outside of Roblox Studio.

P.S., if any of you have any tips to help me get better at the Luau language and how to script more efficiently, please tell me. If you have any Youtube videos or any sites that helped you get better, I am eager to know.

bro your typewriter effect is so cool lol

local t = script.Parent.Frame.TextLabel
local pp = game.Workspace.Teleport.ProximityPrompt
local sgui = script.Parent
local frame = script.Parent.Frame
local sound = script.Parent.Frame.TextLabel.Sound
local sound1 = script.Parent.Frame.TextLabel.Sound1
local sound2 = script.Parent.Frame.TextLabel.sound

local TweenService = game:GetService("TweenService")

local function typewriterEffect(text, delay, soundEffect)
    for i = 1, #text do
        t.Text = text:sub(1, i)
        soundEffect:Play()
        task.wait(delay)
    end
end

local function tweenTransparency(element, targetTransparency, duration)
    local tweenInfo = TweenInfo.new(duration, Enum.EasingStyle.Linear, Enum.EasingDirection.Out)
    local tween = TweenService:Create(element, tweenInfo, {TextTransparency = targetTransparency})
    tween:Play()
end

pp.Triggered:Connect(function()
    pp.Enabled = false
    task.wait(0.5)
    
    sgui.Enabled = true
    task.wait(2)
    
    typewriterEffect("CHAPTER TWO", 0.1, sound1)
    task.wait(3.5)
    
    t.Text = "INSIDE"
    sound2:Play()
    sound:Play()
    task.wait(3)
    
    frame.BackgroundTransparency = 1
    tweenTransparency(t, 1, 1)
    
    sgui.Enabled = false
end)

This works much more smoothly, but I’m still having the same issue that I had before where it only works in Roblox Studio.

Making your first game is very exciting, and I hope things go well for you!

The reason why it doesn’t always work is because the workspace loads dynamically with streaming. This means parts stream in and out as the player moves around depending on their connection to save on resources. This means that the Instances you are trying to access in the workspace will not always exist.

An easy way to get around this is using persistent models, meaning they will always be loaded in. If your Teleport instance is a Model, set the property to ModelStreamingMode to Persistence, then use workspace:WaitForChild("Teleport"):WaitForChild("ProximityPrompt") to wait until it loads.

Do be careful when using a lot of persistent models as they ruin the purpose of streaming.

The best method without relying on persistent models is to use CollectionService to listen for parts being streamed in and out. It works by using string tags that you can put in any Instance under the properties window, which you can then use to connect and disconnect your ProximityPrompts. It is a bit more complicated due to having to disconnect if it gets destroyed/streamed out to save on memory.

--!strict

local Players = game:GetService("Players")
local CollectionService = game:GetService("CollectionService")

local PROXIMITY_PROMPT_TAG = "ProximityPrompt"
local connections = {}

-- function whenever an instance gets added/streamed in
local function onInstanceAdded(instance)
	if instance.ClassName == "ProximityPrompt" and connections[instance] == nil then
		connections[instance] = instance.Triggered:Connect(function(player)
			if player == Players.LocalPlayer then
				-- example code. put your logic here.

				if instance.Name == "ProximityPrompt_Ladder01" then
					print("Moving on to chapter 2...")
				elseif instance.Name == "ProximityPrompt_Exit" then
					print("Finished story!")
				end
			end
		end)
	end
end

-- function whenever an instance gets removed/streamed out
local function onInstanceRemoved(instance)
	if connections[instance] ~= nil then
		connections[instance]:Disconnect()
		connections[instance] = nil
	end
end

-- listen for future instances being added and removed with the PROXIMITY_PROMPT_TAG
CollectionService:GetInstanceAddedSignal(PROXIMITY_PROMPT_TAG):Connect(onInstanceAdded)
CollectionService:GetInstanceRemovedSignal(PROXIMITY_PROMPT_TAG):Connect(onInstanceRemoved)

-- tag already existing instances that may have already loaded in before it connected
for _, instance in CollectionService:GetTagged(PROXIMITY_PROMPT_TAG) do
	task.spawn(onInstanceAdded, instance)
end
1 Like

Did u make sure to actually update the game?

Who mentioned the code being in the workspace? This is a client-sided code.

That is not me saying the code is in the workspace. That is me saying that accessing Instances on the client will not always exist due to streaming.

This fixed it! Thank you so much! :slightly_smiling_face:

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