You can write your topic however you want, but you need to answer these questions:
What do you want to achieve? Keep it simple and clear!
I specifically got confused in my script. I need to find Proximity Prompts and BillboardsGui
What is the issue? Include screenshots / videos if possible!
9 : attempt to index nil with ‘FindFirstChild’; 11 : attempt to index nil with ‘GetChildren’;
What solutions have you tried so far? Did you look for solutions on the Developer Hub?
local Shafles = game.Workspace.Shafles
local prompts = {}
local Billboards = {}
for _, descedant in pairs(Shafles:GetDescendants()) do
if descedant:IsA("Model") then
local b = descedant:FindFirstChild("Shelf")
local a = b:FindFirstChild("ClickZone")
for _, billboard in pairs(a:GetChildren()) do
if billboard:IsA("BillboardGui") then
table.insert(Billboards, billboard)
end
end
for _, prompt in pairs(a:GetChildren()) do
if prompt:IsA("ProximityPrompt") then
table.insert(prompts, prompt)
end
end
end
end
prompts.PromptShown:Connect(function()
for _, billboard in pairs(Billboards) do
Billboards.Enabled = true
end
end)
prompts.PromptHidden:Connect(function()
for _, billboard in pairs(Billboards) do
Billboards.Enabled = false
end
end)
GetDescendants() doesn’t only loop through the children, but also the children’s children. The script will also loop through all models inside of models, such as Book and Shelf. These in themselves don’t contain Shelf, so a will be nil.
Not sure how your entire hierarchy looks, but changing GetDescendants() to GetChildren() on line 6 might fix your issue.
@Exarpo I tried to do this, but it was unsuccessful (I don’t see any errors, just nothing happens):
for _, prompt1 in pairs(prompts) do
prompt1.PromptShown:Connect(function()
for _, billboard in pairs(Billboards) do
prompt1.Enabled = true
Billboards.Enabled = true
end
end)
end
You mean that all billboards appear whenever you click any prompt? That’s because you’re looping through the entire Billboards table whenever any prompt is shown.
You need to keep track of which billboard is relevant for each prompt and only show that one.
Yes, right. As for the other, I’m already so confused that I don’t know how to do it as you explained. I will be very grateful if you can help a little!
Instead of having one table for prompts and another for billboards, have one table that holds tables with a prompt and a billboard each.
At the start declare your tables as one table. Each instance in the table will be a pair of prompt and its corresponding billboard.
local promptsAndBillboards = {
--Here is an example of what this would hold:
--{prompt, billboard}
}
Then, in your loop;
local b = descedant:FindFirstChild("Shelf")
local a = b:FindFirstChild("ClickZone")
--I replaced the loop with a cleaner way to find them...
local billboard = a:FindFirstChildWhichIsA("BillboardGui")
local prompt = a:FindFirstChildWhichIsA("ProximityPrompt")
table.insert(promptsAndBillboards, {billboard, prompt})
You will of course have to handle this differently afterwards when connecting your functions to the PromptsShown, but I hope this gets you on the right track.
The point of using FindFirstChild is for checking if an object exists. It is used redundantly here, because a can be nil, but it is not accounted for in your script. Index directly if you’re sure it’s there, or use WaitForChild if it has the potential to not be loaded yet.