Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Why does my text changer script not work and leaves nothing in the console?

I made a script which changes the text in a screenGUI every second, but it doesn't work. (Also I know that my script isn't very efficient and copying and pasting the line is long but that's my way haha.)

local screen = script.Parent.Parent.Parent.AlphaWarheadScreen.SurfaceGui.TextLabel.Text
script.Parent.MouseClick:connect(function() 
	script.Parent.Parent.Parent.alphawarhead:Play() 
	
	screen = ("DETONATING IN: 90s")
	wait(1)
	screen = ("DETONATING IN: 89s")
	wait(1)
	screen = ("DETONATING IN: 88s")
	wait(1)
	screen = ("DETONATING IN: 87s")
	wait(1)
	screen = ("DETONATING IN: 86s")
	wait(1)
	screen = ("DETONATING IN: 85s")
	wait(1)
	screen = ("DETONATING IN: 84s")
	wait(1)
	screen = ("DETONATING IN: 83s")
	wait(1)
	screen = ("DETONATING IN: 82s")
	wait(1)
	screen = ("DETONATING IN: 81s")
	wait(1)
	screen = ("DETONATING IN: 80s")
	wait(1)
	
end)

1 answer

✓ Accepted answer

It seems like you have a LocalScript inside a ClickDetector. LocalScripts can only run in local environments, since ClickDetectors can only be present in the global environment workspace, the Script will not operate.


Here is a list of all local environments:

####A Player’s Character Rig -- acception to workspace ####A Player's Backpack ####The PlayerGui container ####StarterPlayerScripts ####ReplicatedFirst


You'll have to replace your LocalScript with a ServerScript to have your Lua thread properly run. This is also required as LocalScripts's cannot replicated changes to all users, meaning only the local Player will see the countdown active.


Since that is addressed, let's move on to the functionality of your code...

local screen = script.Parent.Parent.Parent.AlphaWarheadScreen.SurfaceGui.TextLabel.Text

There are a few issues with this line of code. Calling .Text when declaring a variable will allocate the current state of the Text property into it; if our Text holds "Hello world!" our variable will actually translate to the following:

local screen = "Hello world!"

This is a common mistake made by beginners, for further reference, know that you cannot allocate a property of an Object into a variable, it must be called within the respective line to modify it's state—this apply's to all Instances.

local screen = script.Parent.Parent.Parent.AlphaWarheadScreen.SurfaceGui.TextLabel
screen.Text = "New Text"

This will solve the issue with the TextLabel not changing, however, there is one last problem we shall solve... it is highly recommended that you do not use recursive .Parent climbs, as it makes the code difficult for readers to understand, and for the writer to debug.

If you wish to retrieve an Instance higher in the script's hierarchical chain, use the :FindFirstAncestor() method to climb upwards to the given Instance name:

local screen = script:FindFirstAncestor("AlphaWarheadScreen").SurfaceGui.TextLabel

As you can see, this cleans things up a bit.


Final Note:

You have to practice good scripting habits early on so that you get used to it. I see in your script that you're counting down from NINETY seconds. Are you seriously going to copy and paste the same 2 lines NINETY times?

No! You have to learn how to figure out ways to make your program more efficient. In this scenario, you can apply something called a for loop, this will allow you to iterate over a given set of instructions a specified number of times, fortunately, the loop will also return which iteration we're current at, supplying us a numerical variable. We can use this variable to concatenate the second(s) left from the 90 enumerations we traverse.

Here's an article from the wiki about loops to make that tech-savvy jargon a little bit easier to grasp!

Here is our revised program with all the changes applied:

local screen = script:FindFirstAncestor("AlphaWarheadScreen").SurfaceGui.TextLabel
local sound = script:FindFirstAncestor("alphawarhead")

local clickDetector = script.Parent

clickDetector.MouseClick:Connect(function() --// Lowercase 'c' is deprecated
	sound:Play()
	for i = 90, 1, -1 do
    	Screen.Text = "DETONATING IN: "..i..' '..(i > 1 and "seconds" or "second")
	wait(1) end
end)

If you're curious about the odd piece of code at the end of our textual concatenation, what I performed there is called a Ternary Statement. This will allow us to devise two different potential outcomes into the final text depending on one given input. We set our basis as to detect whether we're above 1 second, if so, attach the word "seconds" to the line, if we're not, attach "second". This will exclude the annoying "1 seconds" outcome.

2 comments

0

Thanks for the answer! Also, thanks for the trick with the counter, it worked well!

0

I hope you don't mind me making some changes, I wanted to ensure full efficiency is applied in this lesson, as well as some more tips and tricks! I also fixed up some issues that you would've caused him to run into, please read over this answer again to teach yourself some cool tricks too!

This discussion is preserved as it was. New answers, comments, and votes are closed.