Hello
In some cases I would like to reach a nested instance - for example Main.Model1.Model2.Part3
But I would like, if any of the instances in the path does not exist, to not trigger an error but the whole expression to return nil.
If I do Main:FindFirstChild(“Model1”):FindFirstChild(“Model2”) this will trigger an error if Model1 does not exist.
Is there some built-in expression which can be used or I have to make my own function?
Oh, I see what you mean, though you meant any instance with the given name. You will need your own function. Here’s one that requires a path as a string and a place to begin the search at. Currently it works with alphanumeric names but the pattern can be adjusted.
local function FindInstanceByPath(path: string, place: Instance): Instance?
local current = place
for level in string.gmatch(path, "%w+") do
current = current:FindFirstChild(level)
if not current then
return nil
end
end
return current
end
-- Test with an instance path A.B.C in workspace:
print(FindInstanceByPath("A.B", workspace)) --> B
print(FindInstanceByPath("A.B.C", workspace)) --> C
print(FindInstanceByPath("A.B.D", workspace)) --> nil
print(FindInstanceByPath("A.E", workspace)) --> nil
Edit.
Splitting the string works fine too (haven’t benchmarked the performance difference). I believe gmatch is more flexible in this case.
To allow whitespace in names you can build character sets like [%w%s]+ etc.
Edit 2.
@mooonc0w that’s right, thank you for noticing the typo, I corrected it.
local function findNested(start: Instance, sequence: string): Instance?
local current = start
for _, name in pairs(sequence:split(".")) do
current = current:FindFirstChild(name)
if not current then return nil end
end
return current
end
local model2 = findNested(Main, "Model1.Model2")
if model2 then
print("Model2 found:", model2)
else
print("Model2 not found")
end
You would run the referencing code in a PCall function, and if the function returns an error, you could set whatever variable you’re talking about to nil. If its a success, then you can run whatever code you planned on running.
local Success, Error = pcall(function()
Reference = workspace.Baseplate.SomethingThatDoesntExist
end)
if Success then
print("it exists!")
else
print("it doesnt exist!")
Reference = nil
end
print(Reference)
FindFirstChild recursive should be your solution, it should return nil by default if it doesn’t exist. If you only want to search for the child that is inside of Model2, you can check for the parent of the child.
I’m following up the original reply with a better function that takes a tuple of names consisting of any sort of characters, including the ones with emojis, whitespaces, additional dots etc… Those cases are hard to handle with string.split or string.gmatch. And it is 30% faster.
local function BetterFindInstanceByPath(place: Instance, ...: string | number): Instance?
local current = place
for i, level in {...} do
current = current:FindFirstChild(level)
if not current then return nil end
end
return current
end
print(BetterFindInstanceByPath(workspace, "A", "B", "C")) --> "C"
pcall looks promising because of the simplicity, except protected calls are a bit slower.