Closed Architector4 closed 3 months ago
So if I understood correctly, the main issue is that some systems currently use RemovedComponents<T>
, but if the engine is configured to run in FixedUpdate
with a slow enough timestep, it frequently misses component removals.
I think one way to fix this could be to have a RemovedColliders
resource that is cleared at the end of the PhysicsSchedule
. To avoid removals being missed, the removed colliders would be added to the list in Last
. This way, the collider removals would be detected correctly and only cleared after they have been handled in PhysicsSchedule
. Would that be enough to address your issue?
Note that I believe all the collider removal workarounds like ColliderStorageMap
should become redundant once Bevy has component lifecycle hooks (bevyengine/bevy#10756), since the component data would be accessible when responding to the removals.
So if I understood correctly, the main issue is that some systems currently use
RemovedComponents<T>
, but if the engine is configured to run inFixedUpdate
with a slow enough timestep, it frequently misses component removals.
Yes, basically.
To avoid removals being missed, the removed colliders would be added to the list in
Last
.
In my particular case, some removals happen in a custom schedule I designate that runs every single frame right before FixedUpdate
, and I'd like the physics engine run in FixedUpdate
to be able to respond to them immediately, if the FixedUpdate
schedule runs right after that custom schedule in the same frame. This is the case that is handled perfectly by the engine right now, as it trivially detects the remove.
That doesn't sound like it would be handled by using a list that is only updated in Last
, but I guess this could work if the current and proposed removal detections are used together.
...But then that might introduce difficulties, as both the current detection will respond to removals immediately, and they would also be added to the proposed removed colliders list and handled again on the next frame, which might wreck havoc in case some game logic adds the collider back to an entity in the very next frame, which would then be added and erroneously removed.
I assume that would be fixed by first handling the removals from the list, which would also handle the duplicate removals as a no-op, and only then add colliders.
That's suboptimal, but it might be a good workaround until the component lifecycle hooks are added.
Edit: or maybe not, the above logic could break the more general case of when an entity has had a collider added and then immediately removed, in the same frame, both right before the physics engine is run. Or maybe if a collider was added, then removed, then added back, or removed then added then removed. I'll be completely honest, I'm unsure how bevy_xpbd handles this even now, but I felt like this is also something worth noting.
Sorry, this has turned into a bit of a mind dump lol
Probably blocked by Take note of https://github.com/bevyengine/bevy/issues/7836
I'm doing a bunch of logic before, within, and after the
FixedUpdate
schedule in Bevy, on the fixed timestep. I'd like to run XPBD physics within theFixedUpdate
schedule, to ensure that I can record all entity transforms how they are before the physics step, and record them after they have been adjusted by the physics step after it, so that I can catch the difference and do my own logic with that.Unfortunately, that doesn't seem to be doable. The
Time<Physics>
resource could be adjusted to useTimestepMode::FixedOnce
right before the physics step, but there doesn't appear to be a way to ensure the physics engine is notified of removals of various components it tracks.ComponentRemovals<T>
only gives info about removals that happened in the same or previous app update, and so they are frequently missed inFixedUpdate
if the fixed timestep is slow enough. As such, it'd be nice to be able to run XPBD's systems that use that data in a schedule I designate that I run every update, but it's not possible because it's hardcoded.In particular, the detection only happens in
PhysicsSchedule
, which is used to step the entire simulation forward:https://github.com/Jondolf/bevy_xpbd/blob/088facfe3761235f0b297bc1493927a12a6fe21b/src/plugins/prepare.rs#L96-L97
These systems themselves are private, and so they can't be run individually outside of the crate without stepping the simulation. The resource that
handle_collider_storage_removals
system uses,ColliderStorageMap
, is also private, so it can't be notified of removals manually either.I assume there may be other roadblocks that prevent my use case from being possible, but this is the one that I noticed.