I haven’t updated my game in about a year and I noticed animations are broken. I’ve used print() to narrow down the issue and it’s a strange one.
local nextFunction, allParts, index = pairs(model:GetChildren())
for i = 1, #allParts do
local part = allParts[i]
if part:IsA("BasePart") then
doAnimation(part)
end
if part:IsA("Model")then
for _, desc in pairs(part:GetChildren()) do
if desc:IsA("BasePart") then
doAnimation(desc)
end
end
end
end
This code passes a model in and does an animation up to two levels deep on BaseParts. The problem is, doAnimation() is never fired because BaseParts are ignored on GetChildren().
If I pass a model in that looks like:
-Model
-BasePart
The for loop will never run at all.
If I pass a model in that looks like:
-Model
-Model
-BasePart
The first for loop will run, but the 2nd for loop will not. GetChildren() is not returning any parts on models.
Does anyone have any ideas on what change to Roblox within the past year would be causing this?
I’m not surprised that GetDescendants() also does not get BaseParts. It seems to get other classes, like humanoids, but will not do BaseParts. Very puzzling.
I just noticed the model objects are cloned objects. I wonder if it has something to do with that.
Honestly I don’t understand you’re not just using a for i, v in pairs(model:GetDescendants()) do loop instead of
local nextFunction, allParts, index = pairs(model:GetChildren())
for i = 1, #allParts do
If the loop is working correctly, the only other possibility of your parts not existing inside of the model would be that they were created on the client and you’re looping on the server.
Could be a syntax error.
I’d do this to only go 2 levels deep:
for i, part in pairs(model:GetChildren()) do
if part:IsA("BasePart") then
doAnimation(part)
elseif part:IsA("Model") then
for _, desc in pairs(part:GetChildren()) do
if desc:IsA("BasePart") then
doAnimation(desc)
end
end
end
end
All the code is correct. I know it’s a weird way to do it, but it works. The problem lies in the model variable not containing the parts for some reason.
The model is cloned on the server and then passed to the client for this loop. I’m looking through a year of release notes to see if I can find anything, but it’s a lot.
Blockquote
Could be a syntax error.
I’d do this to only go 2 levels deep:
I did end up changing the code over to this simply because it’s cleaner and easier to maintain.
Providing more context…
The model is cloned in the workspace (server-side):
Objects[ThingMade.Name] = ThingMade:Clone()
Then sent to a remote in replicatedStorage to get it on the client-side:
local model = Objects[item.Object.Value]
local tycoonAnimation = replicatedStorage.Remote:WaitForChild("TycoonAnimation")
tycoonAnimation:FireClient(owner.Value, model, initialT)
Then the client-side does the for loop as mentioned above.
Again, this was all working fine, but an update has broke it. I appreciate all the help!
If you are finding children of a model’s children, you have to use GetDescendants Instead of GetChildren. Just replace those lines and you should be good.
Did you set the model’s parent to the Workspace? It’s a bit hard to understand the problem without all the code. Also are the parts in the model BaseParts or something else like MeshParts?
Thx for checking, but i actualy just found the solution, and it was really dumb.
This was the test code
local Children = game.workspace.Test:GetChildren()
print(Children)
It checked the model Test’s children, which are Part1 and Part2.
The problem was it was trying to check it before those parts were added to the workspace on load.
local function GetChildren(parent: Instance, layers: number, filterFn: ((child: Instance) -> boolean)?)
local Children = {}
local function Get(current: Instance, depth: number)
if depth <= 0 then return end
for _, child in next, current:GetChildren() do
if not filterFn or filterFn(child) then
table.insert(Children, child)
end
Get(child, depth - 1)
end
end
Get(parent, layers)
return Children
end
--// BaseParts (type-asserted manually)
local BaseParts = GetChildren(workspace, 2, function(child)
return child:IsA("BasePart")
end) :: { BasePart }