bevy icon indicating copy to clipboard operation
bevy copied to clipboard

generic component propagation

Open robtfm opened this issue 11 months ago • 5 comments

Objective

add functionality to allow propagating components to children. requested originally for RenderLayers but can be useful more generally.

Solution

  • add HierarchyPropagatePlugin<C, F=()> which schedules systems to propagate components through entities matching F
  • add Propagate<C: Component + Clone + PartialEq> which will cause C to be added to all children more niche features:
  • add PropagateStop<C> which stops the propagation at this entity
  • add PropagateOver<C> which allows the propagation to continue to children, but doesn't add/remove/modify a C on this entity itself

Testing

see tests inline

Notes

  • could happily be an out-of-repo plugin
  • not sure where it lives: ideally it would be in bevy_ecs but it requires a Plugin so I put it in bevy_app, doesn't really belong there though.
  • i'm not totally up-to-date on triggers and observers so possibly this could be done more cleanly, would be very happy to take review comments
  • perf: this is pretty cheap except for update_reparented which has to check the parent of every moved entity. since the entirety is opt-in i think it's acceptable but i could possibly use (Changed<Children>, With<Inherited<C>>) instead if it's a concern

robtfm avatar Jan 28 '25 13:01 robtfm

@viridia iirc you requested this originally. if you're not interested i think this pr is going to be stuck in limbo so i may as well close it (i'm using it out of repo which is fine).

robtfm avatar Feb 06 '25 14:02 robtfm

I have worked around the problem for now, but the solution isn't as elegant as I'd like.

The original motivation was to be able to spawn GLTF models on a render layer. Currently I manage this by using an observer and traversing the scene.

viridia avatar Feb 06 '25 14:02 viridia

in case it's unclear from the tests, the way to do that would be app.add_plugins(HierarchyPropagationPlugin::<RenderLayers>::default()); then commands.entity(gltf_root).insert(Propagate(your_renderlayer));.

it would have no effect on entities in other parts of the scene, and would set the renderlayer on the gltf_root and children (including removing it if they move out, adding it if they move in).

robtfm avatar Feb 06 '25 14:02 robtfm

I’ll see if I can do 3 over the weekend, and try and have a look at 4 as well

robtfm avatar May 29 '25 07:05 robtfm

i couldn't see much scope to remove trait bounds (just testing by trial and error), i removed them from PropagateStop and PropagateOver only. if there's something in particular that looks wrong please let me know.

robtfm avatar Jun 01 '25 22:06 robtfm

It looks like your PR has been selected for a highlight in the next release blog post, but you didn't provide a release note.

Please review the instructions for writing release notes, then expand or revise the content in the release notes directory to showcase your changes.

github-actions[bot] avatar Jul 14 '25 21:07 github-actions[bot]