Skip to content

Commit 6006e8d

Browse files
committed
Fix modules remaining in world if cycling through modules too fast
1 parent 476f05b commit 6006e8d

File tree

3 files changed

+74
-38
lines changed

3 files changed

+74
-38
lines changed

src/main.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,7 @@ fn spawn_text(mut commands: Commands, asset_server: Res<AssetServer>) {
5757
"Cycle through heads with Q and W\n\
5858
Cycle through bodies with E and R\n\
5959
Cycle through heads with T and Y\n\
60-
Cycle through heads with U and I\n\
61-
Do not press the buttons too fast",
60+
Cycle through heads with U and I",
6261
TextStyle {
6362
font: asset_server.load("fonts/FiraMono-Medium.ttf"),
6463
font_size: 24.,
@@ -85,22 +84,22 @@ fn spawn_modular(
8584
Name::new("Modular"),
8685
ModularCharacterHead {
8786
id: 0,
88-
instance_id: scene_spawner.spawn(asset_server.load(modular::HEADS[0])),
87+
instance_id: Some(scene_spawner.spawn(asset_server.load(modular::HEADS[0]))),
8988
entities: vec![],
9089
},
9190
ModularCharacterBody {
9291
id: 0,
93-
instance_id: scene_spawner.spawn(asset_server.load(modular::BODIES[0])),
92+
instance_id: Some(scene_spawner.spawn(asset_server.load(modular::BODIES[0]))),
9493
entities: vec![],
9594
},
9695
ModularCharacterLegs {
9796
id: 0,
98-
instance_id: scene_spawner.spawn(asset_server.load(modular::LEGS[0])),
97+
instance_id: Some(scene_spawner.spawn(asset_server.load(modular::LEGS[0]))),
9998
entities: vec![],
10099
},
101100
ModularCharacterFeet {
102101
id: 0,
103-
instance_id: scene_spawner.spawn(asset_server.load(modular::FEET[0])),
102+
instance_id: Some(scene_spawner.spawn(asset_server.load(modular::FEET[0]))),
104103
entities: vec![],
105104
},
106105
))

src/modular/components.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ use bevy::{
55

66
pub trait ModularCharacter: Component {
77
fn id_mut(&mut self) -> &mut usize;
8-
fn instance_id_mut(&mut self) -> &mut InstanceId;
8+
fn instance_id_mut(&mut self) -> &mut Option<InstanceId>;
99
fn entities_mut(&mut self) -> &mut Vec<Entity>;
1010
fn id(&self) -> &usize;
11-
fn instance_id(&self) -> &InstanceId;
11+
fn instance_id(&self) -> Option<&InstanceId>;
1212
fn entities(&self) -> &Vec<Entity>;
1313
}
1414

@@ -18,15 +18,15 @@ macro_rules! create_modular_segment {
1818
#[derive(Debug, Component)]
1919
pub struct [<ModularCharacter $name>] {
2020
pub id: usize,
21-
pub instance_id: InstanceId,
21+
pub instance_id: Option<InstanceId>,
2222
pub entities: Vec<Entity>,
2323
}
2424
impl ModularCharacter for [<ModularCharacter $name>] {
2525
fn id_mut(&mut self) -> &mut usize {
2626
&mut self.id
2727
}
2828

29-
fn instance_id_mut(&mut self) -> &mut InstanceId {
29+
fn instance_id_mut(&mut self) -> &mut Option<InstanceId> {
3030
&mut self.instance_id
3131
}
3232

@@ -38,8 +38,8 @@ macro_rules! create_modular_segment {
3838
&self.id
3939
}
4040

41-
fn instance_id(&self) -> &InstanceId {
42-
&self.instance_id
41+
fn instance_id(&self) -> Option<&InstanceId> {
42+
self.instance_id.as_ref()
4343
}
4444

4545
fn entities(&self) -> &Vec<Entity> {

src/modular/mod.rs

Lines changed: 63 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use bevy::{
1212
entity::Entity,
1313
event::{EventReader, EventWriter},
1414
query::Changed,
15+
schedule::IntoSystemConfigs,
1516
system::{Commands, Query, Res, ResMut},
1617
},
1718
hierarchy::{BuildChildren, Children, DespawnRecursiveExt, HierarchyQueryExt, Parent},
@@ -70,14 +71,46 @@ impl Plugin for ModularPlugin {
7071
.add_systems(Update, update_modular::<ModularCharacterBody>)
7172
.add_systems(Update, update_modular::<ModularCharacterLegs>)
7273
.add_systems(Update, update_modular::<ModularCharacterFeet>)
73-
.add_systems(Update, cycle_modular_segment::<ModularCharacterHead, 0>)
74-
.add_systems(Update, cycle_modular_segment::<ModularCharacterBody, 1>)
75-
.add_systems(Update, cycle_modular_segment::<ModularCharacterLegs, 2>)
76-
.add_systems(Update, cycle_modular_segment::<ModularCharacterFeet, 3>)
77-
.add_systems(Update, reset_changed::<ModularCharacterHead>)
78-
.add_systems(Update, reset_changed::<ModularCharacterBody>)
79-
.add_systems(Update, reset_changed::<ModularCharacterLegs>)
80-
.add_systems(Update, reset_changed::<ModularCharacterFeet>);
74+
.add_systems(
75+
Update,
76+
cycle_modular_segment::<ModularCharacterHead, 0>
77+
.after(update_modular::<ModularCharacterHead>),
78+
)
79+
.add_systems(
80+
Update,
81+
cycle_modular_segment::<ModularCharacterBody, 1>
82+
.after(update_modular::<ModularCharacterBody>),
83+
)
84+
.add_systems(
85+
Update,
86+
cycle_modular_segment::<ModularCharacterLegs, 2>
87+
.after(update_modular::<ModularCharacterLegs>),
88+
)
89+
.add_systems(
90+
Update,
91+
cycle_modular_segment::<ModularCharacterFeet, 3>
92+
.after(update_modular::<ModularCharacterFeet>),
93+
)
94+
.add_systems(
95+
Update,
96+
reset_changed::<ModularCharacterHead>
97+
.after(cycle_modular_segment::<ModularCharacterHead, 0>),
98+
)
99+
.add_systems(
100+
Update,
101+
reset_changed::<ModularCharacterBody>
102+
.after(cycle_modular_segment::<ModularCharacterBody, 1>),
103+
)
104+
.add_systems(
105+
Update,
106+
reset_changed::<ModularCharacterLegs>
107+
.after(cycle_modular_segment::<ModularCharacterLegs, 2>),
108+
)
109+
.add_systems(
110+
Update,
111+
reset_changed::<ModularCharacterFeet>
112+
.after(cycle_modular_segment::<ModularCharacterFeet, 3>),
113+
);
81114
}
82115
}
83116

@@ -100,7 +133,10 @@ fn update_modular<T: components::ModularCharacter>(
100133
mut writer: EventWriter<ResetChanged>,
101134
) {
102135
for (entity, mut modular) in &mut changed_modular {
103-
if scene_spawner.instance_is_ready(*modular.instance_id()) {
136+
let Some(scene_instance) = modular.instance_id().copied() else {
137+
continue;
138+
};
139+
if scene_spawner.instance_is_ready(scene_instance) {
104140
// Delete old
105141
bevy::log::trace!("Deleting old modular segment.");
106142
if !modular.entities().is_empty() {
@@ -112,7 +148,7 @@ fn update_modular<T: components::ModularCharacter>(
112148

113149
// Get MeshPrimitives
114150
let mesh_primitives = scene_spawner
115-
.iter_instance_entities(*modular.instance_id())
151+
.iter_instance_entities(scene_instance)
116152
.filter(|node| mesh_primitives_query.contains(*node))
117153
.collect::<Vec<_>>();
118154

@@ -198,8 +234,9 @@ fn update_modular<T: components::ModularCharacter>(
198234
modular.entities_mut().push(mesh_entity);
199235
commands.entity(entity).add_child(mesh_entity);
200236
}
201-
202-
scene_spawner.despawn_instance(*modular.instance_id());
237+
if let Some(instance) = modular.instance_id_mut().take() {
238+
scene_spawner.despawn_instance(instance);
239+
}
203240
} else {
204241
writer.send(ResetChanged(entity));
205242
}
@@ -219,22 +256,22 @@ fn cycle_modular_segment<T: ModularCharacter, const ID: usize>(
219256
(KeyCode::KeyU, KeyCode::KeyI),
220257
];
221258
const MODULES: [&[&str]; 4] = [&HEADS, &BODIES, &LEGS, &FEET];
222-
if key_input.just_pressed(KEYS[ID].0) {
223-
let Ok(mut module) = modular.get_single_mut() else {
224-
bevy::log::error!("Couldn't get single Head.");
225-
return;
226-
};
227-
*module.id_mut() = module.id().wrapping_sub(1).min(MODULES[ID].len() - 1);
228-
*module.instance_id_mut() =
229-
scene_spawner.spawn(asset_server.load(MODULES[ID][*module.id()]));
259+
let Ok(mut module) = modular.get_single_mut() else {
260+
bevy::log::error!("Couldn't get single module.");
261+
return;
262+
};
263+
*module.id_mut() = if key_input.just_pressed(KEYS[ID].0) {
264+
module.id().wrapping_sub(1).min(MODULES[ID].len() - 1)
230265
} else if key_input.just_pressed(KEYS[ID].1) {
231-
let Ok(mut head) = modular.get_single_mut() else {
232-
bevy::log::error!("Couldn't get single Head.");
233-
return;
234-
};
235-
*head.id_mut() = (head.id() + 1) % MODULES[ID].len();
236-
*head.instance_id_mut() = scene_spawner.spawn(asset_server.load(MODULES[ID][*head.id()]));
266+
(module.id() + 1) % MODULES[ID].len()
267+
} else {
268+
return;
269+
};
270+
if let Some(instance) = module.instance_id() {
271+
scene_spawner.despawn_instance(*instance);
237272
}
273+
*module.instance_id_mut() =
274+
Some(scene_spawner.spawn(asset_server.load(MODULES[ID][*module.id()])));
238275
}
239276

240277
fn reset_changed<T: ModularCharacter>(

0 commit comments

Comments
 (0)