0

So I have this component called BulletSpawner which spawns bullets every once in a while. I want this component to be as versatile as possible for my Danmaku game so that I don't have to change it again later. So it has fields like a TrajectoryBuilder for the trajectory of the bullets. And I wanted to include a field to allow inserting components on the bullet. That way, I could have multiple BulletSpawner spawning bullet with different shapes, sprites, etc... track the bullets a specific BulletSpawner had spawned.

I first tried writing the field to_insert: Arc<dyn Bundle> but it messaged me that 'Bundle' couldn't be made into an object. So I tried to use a vector of components to_insert: Vec<Arc<Component<Storage=Table>>> and that way it accepted the field. but now I have issues writing the snippet of code to insert the components

for component: &Arc<dyn Component<Storage=Table>> in bullet_spawner.to_insert.iter() {
  new_bullet.insert(*Arc::borrow(component));
}

but now it's telling me that type annotation is needed, as it cannot infer the type for the type parameter 'impl Bundle' of the associated function insert.

These methods however feel like hacking so I would prefer an 'official' way.

E_net4
  • 27,810
  • 13
  • 101
  • 139

1 Answers1

1

I believe that what you have won't work in Bevy due to how it uses types for Components. When you store dyn Component there isn't a way back to the solid type that Bevy needs to work out which table to store it in.

Instead, you could change the design a little for the BulletSpawner so that it owns a function instead of instantiated components. e.g.

#[derive(Component)]
struct BulletSpawner {
    // e.g. bundle: Bullet,
    bundle_fn: Box<dyn Fn(&Commands) + Send + Sync>,
}

impl BulletSpawner {
    fn create_bullet(&self, cmds: &Commands) {
        (self.bundle_fn)(cmds);
    }
}

fn spawner_startup_system(cmds: Commands) {
    // Add new "spawner"
    cmds.spawn(BulletSpawner {
        bundle_fn: Box::new(|cmds| {
            cmds.spawn(FastBullet {});
        }),
    });
}

That said, this still feels a little off. Splitting the concept of the BulletSpawner into multiple Component's might make for a more understandable structure, e.g. FastBulletSpawner.

Michael
  • 507
  • 4
  • 11