Okay your best bet is to do what @mc7oof has suggested with yielding until the character loads
We can also use CollectionService to clean up the code and prevent large amounts of objects in the workspace from clogging up the loop
To use CollectionService
Open the tag editor in the View tab, create a tag, I named mine “Test”, then click on each proximity prompt and add the tag to each
local Players = game:GetService("Players")
local CollectionService = game:GetService("CollectionService")
local Player = Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
print(CollectionService:GetTagged("Test"))
local ContentProvider = game:GetService("ContentProvider")
local assets = workspace:GetDescendants()
ContentProvider:PreLoadAsync(assets)
-- alternatively, usw children
-- here comes your loop
Stuff on the client isn’t always guaranteed to be fully loaded in general, especially with streaming enabled.
What your code currently does is get all the proximity prompts under Workspace initially. This means if some are loaded in after the script starts, the code doesn’t catch them!
The way people handle this is using the Descendant added event. This code is the standard way of getting things like this on the client:
-- Works in a LocalScript in starter player scripts
local function instanceAdded(instance)
-- Check if it's the right instance
if instance:IsA("ProximityPrompt") then
-- Do your code is here
print(instance)
end
end
-- Process any instances initially in workspace
for _, instance in ipairs(workspace:GetDescendants()) do
onInstanceAdded(instance)
end
-- Process any instances that are loaded in later
workspace.DescendantAdded:Connect(onInstanceAdded) -- Run our function on DescendantAdded
This way, your code doesn’t just process the instances that are there initially, and can make sure to process any instances that are loaded or added later!
(If you are using streaming enabled, because the prompts can be loaded in and out, you also need to make sure you aren’t double counting them, in the case where they’re added, removed, then added again. You can do this with DescedantRemoving, or by checking if you already did something for that instance using a table.)
For more information, sleitnick has a great video on something similar that kind of explains why you should do this and how it works: