AuraHeartbeat.Add only works on first clone, not after re-cloning aura

I’m having an issue with AuraHeartbeat.Add.

Local script

local AuraHeartbeat = require(game.ReplicatedStorage.Shared.Controllers.AuraHeartbeat)

for _, object in pairs(script.Parent:GetDescendants()) do
    if not object:IsA("Attachment") then continue end

    local anglePerSecond = object:FindFirstChild("AnglePerSecond")
    if not anglePerSecond then continue end

    AuraHeartbeat.Add(object, function(dt)
        object.CFrame *= CFrame.Angles(0, math.rad(dt * anglePerSecond.Value), 0)
    end)
end

This works the first time the aura is cloned onto the character. However, after I destroy the aura objects and clone them again, the newly cloned attachments no longer rotate because AuraHeartbeat.Add is never called for them.

Here’s how I attach the aura: (Server Script)

for _, bodyFolder in ipairs(pathToVFX:GetChildren()) do
    local bodyPart = character:FindFirstChild(bodyFolder.Name)

    if bodyPart then
        for _, object in ipairs(bodyFolder:GetChildren()) do
            local clone = object:Clone()
            clone.Parent = bodyPart
            clone:SetAttribute("AuraObject", true)
        end
    end
end

Also, here’s a screenshot of what the aura folder looks like:

I have multiple scripts that vary depending on the aura, so I keep the scripts inside each aura. I could use RunService on a server to animate them whenever they attach to a character, but I don’t want to handle animations on the server. It would be better to keep everything on the client.

What’s the best way to handle this?

I would just listen to the GetInstanceAddedSignal of CollectionService service and give each aura attachment unique name. Based on its name I would run aura function belongs to it. Easiest way to automate this is to just create a module script for each aura and store them in a folder that contains them all, then I would just check if module for aura exists, if it does I would call function inside the module. For preventing mess of cleaning after a destroyed aura I would make it so said functions type of functions that you would run inside heartbeat call. Then I would store all the auras inside a table with their function so its in pairs {aura, function} this way I don’t have to perform expensive FindFirstChildren calls every frame for each aura in the table. As you might predicted I would iterate through the table and call the aura functions.

So, basically, I should create a ModuleHandler that listens for newly added children with CollectionService tags. Then make a separate module for the auras and probably add an attribute to certain aura objects that need scripts, and call it something like Behavior. If I find that behavior name in the aura module under the ModuleHandler, I call it for each corresponding object?

I just updated my previous reply, you should give it a read. And yes if you prefer attributes over name you can replace my suggestion of using names with attributes.

But wouldn’t that get really messy, especially with tags, if you have, say, over 100 auras that requires different script animations?

just Tag your Object with “AuraObject” and not Attributes, and Listen to CollectionService:GetInstanceAddedSignal whenever aura object is initialized and call ur Add function in there

Yes and I was suggesting using single general tag like “Aura” and then checking instance’s name and determining what aura module to run.