This question was created in reference to: [Adding physics to Modular characters by “Leader Pose Component” [Content removed]
Hello, as recommended in my previous question, I am experimenting with control rig physics to implement a character with physicallized parts of clothing. In short, the goal is to use Leader Pose Component method to animate the clothing pieces based on the character mesh and then control rig (CR) to simulate their physicalized parts. I am using “Instantiate From Physics Asset” (IFPA) to construct the physics bodies from the physics assets ¶ - authored by artists - of the clothing and then simulate them in the rig. It seems promising so far, but there are issues with dynamically rebuilding the CR.
1) Can I set control rig variables used in Construction Event dynamically when the rig is part of animBP?
We want to set which PA to use dynamically (based on what clothes the character has on) -> I need to “parametrize” the Construction Event by the right PA to pass it on to the IFPA. Is it possible to somehow do this when CR is used as a node in animBP? Perhaps during the InitializeAnimation event of the animinstance? Anyway, even if possible, my next problem is that as the clothes can change during gameplay, I need to be able to re-initialize the rig. And that is not an option for animBP CR node, right? I would have to re-initialize the whole animinstance I suppose (which even if possible is not a great solution)?
2) How to use CR as a component for animation?
The next option is to have the CR as a component of the character actor. This allows me to use “Initialize” node on the CR component to re-trigger the construction and using the OnPreInitialize event + SetVariable on the CR to pass in the PA I want to the rig to use it in Construction Event. This works, but I have not found out how to setup the component to act basically the same way as when the CR is the last node in the anim graph of my skeletal mesh component (SMC). I can use the “Add Mapped Skeletal Mesh” node to set the CR as either the input or output of the SMC, but I would sort of like both: have the SMC process its animBP, send result to the CR and then read back from the CR and update bone positions accordingly. ChatGPT advised to use two SMCs, set one to be invisible, do the animation on it, map it as output to the CR and then have the second SMC be visible and mapped as input for CR and use that for rendering. Surprisingly, it sort of works, but feels very wrong and I can see it being a source of all kinds of issues, not to mention memory overhead. Is there some more reasonable way to achieve this “two way” mapping of the CR component?
3) How to reconstruct/remove only chosen physics bodies?
What I would actually like to do when clothes change is to only remove physics bodies that are no longer used and create new ones, but keep the solver and bodies that don’t need to be changed as they are (both for performance and also for visuals - e.g. so that physical motion of my coat is not reset because I put a new hat on my head). For that I would like two things:
- the ability to say that my CR custom user event can call construction-only nodes (like IFPA) - I assume there would have to be some restrictions on when such event can be triggered
- a node for despawn of physics body
Looking at the IFPA’s implementation in FRigUnit_HierarchyInstantiateFromPhysicsAsset_Execute(), I see new components can be added and removed by URigHierarchyController’s Add/Remove component, but what are the pitfalls of using this after construction? Likely it needs to not be done during animation update, are there other restrictions? I am ok with not having any collisions between assets from different PAs.
Note: I can think of an alternative approach using one CR for headwear, one for torso etc. This way I always have only 1 or 0 physics bodies per CR, so there is little to gain by doing this per-parts re-initializion and I could just reset it whole. But that means several rigs and several physics solvers instead of just one, would have to measure if it brings a significant performance overhead. And still would need question #2 resolved for that to work.

