Hello All,
I could use a little help with basic Lua coding language. It has to do with concatenation. I’m trying to concatenate the name of an object with text, which together spell out the name of another existing variable. I keep getting the error "attempt to index string with ‘Text’ ". I’m doing this to save time in my script as I have about 120 lines of code that will be condensed if this can work. But I can’t figure out the proper concatenation setup. Below is a very basic example of my setup.
Starting a new game with a baseplate add:
A part in the workspace named “RedBlock” with a StringValue inserted (called sValue) with a Value = “Basic”
A part in the workspace named “BlueBlock” with a StringValue inserted (called sValue) with a Value = “Basic”
A part in the workspace named “GreenBlock” with a StringValue inserted (called sValue) with a Value = “Basic”
Under StarterGui
- ScreenGui
- Frame
- LocalScript
- RedBlockTextLabel (each a text label)
- BlueBlockTextLabel
- GreenBlockTextLabel
----- LocalScript-------
local redBlock = game.Workspace.RedBlock
local blueBlock = game.Workspace.BlueBlock
local greenBlock = game.Workspace.GreenBlock
local RedBlockTextLabel = script.Parent.RedBlockTextLabel
local BlueBlockTextLabel = script.Parent.BlueBlockTextLabel
local GreenBlockTextLabel = script.Parent.GreenBlockTextLabel
local blockTable = {redBlock, blueBlock, greenBlock}
local function blockUpdate()
for i,v in pairs(blockTable) do
if v.sValue.Value == "Basic" then
-- Here's my problem.
--I want concatenate the v.Name with a String to form the name of a variable. Then, add .Text = to change the text of each TextLabel.
-- However, I get an error of "attempt to index string with 'Text'"
(v.Name .. "TextLabel").Text = "Horray" -- This is the error line (attempt to index string with 'Text')
end
end
end
blockUpdate()
Any suggestions on how to concatenate this properly?
2 Likes
You can’t concat strings into a variable, however you can do something like this:
local redBlock = game.Workspace.RedBlock
local blueBlock = game.Workspace.BlueBlock
local greenBlock = game.Workspace.GreenBlock
local Parent = script.Parent
local blockTable = {redBlock, blueBlock, greenBlock}
local function blockUpdate()
for i,v in pairs(blockTable) do
if v.sValue.Value == "Basic" then
Parent[v.Name .. "TextLabel"].Text = "Horray" --Indexes child with concated string.
end
end
end
blockUpdate()
You can also do this:
local redBlock = game.Workspace.RedBlock
local blueBlock = game.Workspace.BlueBlock
local greenBlock = game.Workspace.GreenBlock
local TextLabelTable = {
RedBlockTextLabel = script.Parent.RedBlockTextLabel
BlueBlockTextLabel = script.Parent.BlueBlockTextLabel
GreenBlockTextLabel = script.Parent.GreenBlockTextLabel
}
local blockTable = {redBlock, blueBlock, greenBlock}
local function blockUpdate()
for i,v in pairs(blockTable) do
if v.sValue.Value == "Basic" then
TextLabelTable[v.Name.."TextLabel"].Text = "Horray" --Concats string and uses it as a key inside TextLabelTable to get the value assigned to that key.
end
end
end
blockUpdate()
3 Likes
Clever! It works just as I’d hoped. Thanks a bunch!
(v.Name .. "TextLabel").Text = "Horray"
You cannot do this, it is not possible to dereference a local dynamically, and it is by design. You must access them from something that can be indexed/dynamically referenced, like a table.
@BenMactavsin’s answer above does that by getting the labels from script.Parent. Instances can be indexed.
A table can be indexed. You can do:
local blocks = {
RedBlockTextLabel = script.Parent.RedBlockTextLabel
BlueBlockTextLabel = script.Parent.BlueBlockTextLabel
GreenBlockTextLabel = script.Parent.GreenBlockTextLabel
}
blocks[v.Name .. "TextLabel"].Text = "Hooray!"
You can index the script’s global table, which can be accessed with getfenv
. Using it will make your script slower everywhere because it disables optimizations.
-- removed local, so it puts it in the global table
RedBlockTextLabel = script.Parent.RedBlockTextLabel
BlueBlockTextLabel = script.Parent.BlueBlockTextLabel
GreenBlockTextLabel = script.Parent.GreenBlockTextLabel
-- get global table
local blocks = getfenv() -- very bad
blocks[v.Name .. "TextLabel"].Text = "Hooray!"
Thank you for the further insights. My familiarization with these deeper concepts can be improved and I’m glad you’ve touched upon them. For Christmas I should receive the book “Programming in Lua, 4th Edition”. Hopefully it will be a good read to better understand the in’s and out’s of Lua. These responses will save me a couple hours of typing, what would have otherwise been a loooong script.