Bevy version
Since 0.15.
What you did
use bevy::prelude::*;
use bevy_render::extract_component::{ExtractComponent, ExtractComponentPlugin};
use bevy_render::sync_world::RenderEntity;
use bevy_render::{Extract, RenderApp};
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins((
TestExtractPlugin,
ExtractComponentPlugin::<ComponentA>::default(),
ExtractComponentPlugin::<ComponentB>::default(),
))
.add_systems(Startup, setup)
.add_systems(Update, update)
.run();
}
#[derive(Component, ExtractComponent, Clone)]
struct ComponentA;
#[derive(Component, ExtractComponent, Clone)]
struct ComponentB;
/// set up a simple 3D scene
fn setup(mut commands: Commands) {
commands.spawn((ComponentA, ComponentB));
}
fn update(mut commands: Commands, mut query: Query<(Entity), With<ComponentB>>) {
for (entity) in query.iter() {
commands.entity(entity).remove::<ComponentA>();
commands.entity(entity).insert(ComponentA);
}
}
struct TestExtractPlugin;
impl Plugin for TestExtractPlugin {
fn build(&self, app: &mut App) {
let Some(render_app) = app.get_sub_app_mut(RenderApp) else {
return;
};
render_app
.add_systems(ExtractSchedule, extract);
}
}
fn extract(query: Extract<Query<RenderEntity, With<ComponentB>>>) {
for (entity) in query.iter() {
println!("Render entity id: {:?}", entity);
}
}
What went wrong
Adding ExtractComponentPlugin adds SyncComponentPlugin, which will cause the RenderEntity to be changed in entity_sync_system if the component is removed.
Unfortunately, this logic doesn't make sense, as it's possible for multiple components a main world entity to want to be extracted. Further, being removed doesn't mean that the main world entity necessarily needs to be de-synced from the render world, as it could be being extracted for other reasons. This leads to very confusing and hard to debug behavior and is generally just incorrect.
Bevy version
Since
0.15.What you did
What went wrong
Adding
ExtractComponentPluginaddsSyncComponentPlugin, which will cause theRenderEntityto be changed inentity_sync_systemif the component is removed.Unfortunately, this logic doesn't make sense, as it's possible for multiple components a main world entity to want to be extracted. Further, being removed doesn't mean that the main world entity necessarily needs to be de-synced from the render world, as it could be being extracted for other reasons. This leads to very confusing and hard to debug behavior and is generally just incorrect.