I have Gun entity, I'd like it to spawn Bullets but in a decoupled way. I've used Events to store information about the location muzzle velocity etc, which then get picked up by a system that does the actual spawning. This means I have to encode a lot of information in the spawn event which feels like it should be in a scene. Would instancing a DynamicScene for each bullet be a sensible approach? If so, how does one set the position of a scene instance after it's been instanced? My current best guess is to spawn it as a child of a dummy entity with a position, then moving it out of the dummy next frame.
#Idiomatic way to spawn?
25 messages · Page 1 of 1 (latest)
I'd first try an approach where you basically only store a reference to the Gun entity in the event (somethin like gun: Entity) and then in the system that does the spawning you can query for all the information you need from the Gun entity itself. Would that work?
Interesting! That sounds like a good idea, certainly better than stuffing the event with more and more info. I can't quite see how that will work out, so I will experiment.
I'd very much like to use DynamicScene, but it looks like it's not really designed for spawning individual objects.
Yea I haven't used DynamicScene before but I heard it's mostly needed for loading and saving things, which won't be necessary for bullets most likely
DynamicScene seems like it would be perfect for decoupled spawning if it were not for the setup issue. Can't have bullets spawning at (0, 0), staying there for a frame then moving to the muzzle. Perhaps if code could execute immediately after SceneSpawner does its stuff, but it's not clear to me when this occurs!
You should be able to move it within the same frame if you put a system after it
But I'm curious, what's the issue with spawning the bullet normally?
Back in Godot, I'd use a PackedScene (Godot's equivalent to DynamicScene) to store the 'blueprint' of a bullet (or whatever needs spawning) then instantiate it upon firing, setting position, velocity, originator fields before adding it to the world. This is very convenient because you can switch up what a spawner spawns just by replacing the PackedScene.
I think you may be right on the 'put a system after it' idea. I've found the schedule that SceneSpawner uses, and as long as the new-instanced-scene-configurator system goes after that and before the collision detection it should work.
Just putting it in PostUpdate might work?
I think in Bevy the way to do something like this is with a normal commands.spawn() and then define your own bundles so you can set those properties easily. Or look into using custom commands: https://taintedcoders.com/bevy/custom-commands/
I was thinking something like (spawn_system, move_system).chain() but I'm not sure if that would work in the context of DynamicScenes
Are you on 0.13 btw?
yes
Alright good
With custom commands you could even skip events completely if you prefer
Right, I have a lot of experimenting to do, thank you for the ideas and for the taintedcoders link, that looks like an amazing resource
No problem! Let us know if you get stuck
Here's what I ended up with
works pretty nicely although not mega flexible
use like this
fn click_to_spawn_dynamic_scene(
bs: Res<BulletScene>,
mut spawn: Spawn,
mut ev_in: EventReader<WorldMouseDownEvent>,
) {
for ev in ev_in.read() {
spawn.spawn(
bs.0.clone(),
EntityConfig {
transform: Transform::from_translation(ev.0.extend(0.0)),
..default()
},
);
}
}```
This is the final form of my DynamicScene configuration, it allows you to spawn a dynamic scene then configure it by applying a bundle instance, which will overwrite any existing components.
Some XPBD components do not reflect, so I've ended up using 'spawnfuncs' for now which work in much the same way.