#Send signals to specific entities

1 messages · Page 1 of 1 (latest)

shrewd kite
#

Hi, I am pretty new to bevy and I am wondering if I can send signals to specific entities.
Like if I have a grid of entities and would like for each of them to send a signal to their neighbors. If every entity had an Vec of their neighbors addresses (lik UUIDs?) could It send Information to it’s next, or is there another way of doing such things in bevy.

empty sedge
empty sedge
#

Your Event would contain Entity + the information you want to send

#

Then add a query for the entities in the grid to your eventlistener, so you can do something like let entity_or_components_we_want_to_affect = grid_query.get(my_event.source_entity)

green vault
#

This sounds a bit anti-ECS, entities are just IDs so how are they going to receive signals?

shrewd kite
#

Yea, I only programmed non ecs games and was wondering how to do this the ecs style

green vault
#

It has to happen in a system somehow. An entity could store its neighbouring entities in a MyComponentName<Vec<Entity>> component. then a system can read that and any other data it might need to perform the operation you want to happen, and perform that operation

#

or you could have a resource storing neighbours, I do that in my jigsaw, dunno if it's better

#

wait, no, I switched to the first model I remember now because I had to keep merging neighbours

shrewd kite
#

So I have an Entity, that has an Vec of Entities(neighbors), A query that for every entity,let’a this entity send a signal to its stored Entities(neighbors).

#

No, an entity can't recive an signal only systems can

green vault
#

There is no signal here, the system can just apply whatever behaviour the signal is supposed to trigger. if you do want it more indirectly, maybe each entity can have some other component to store these "signals" but it all depends on what exactly you're doing which I don't know

#

a system would still be applying the information to these other components

shrewd kite
#

Oh, yea, since the system isn't the enities system, but sort of an global on it can apply the change directly.

placid shuttle
#

Often times storing the events is clearner, especially if you have multiple causes for the events or multiple things that they trigger

#

Generally one-to-many and many-to-many things benefit from storing stuff on the entities

shrewd kite
#

So I would like to a little game where gras Blocks are spawend an you have to eat the gras, every timer, every eaten gras looks if it's neighbours has gras on it, if so I grows gras again.

green vault
#

Sounds like a spread grass system that looks at tiles, and if they have no grass, iterates over neighbours to find if any have grass, then mutates some has grass conponent to be true

placid shuttle
#

Store neighbors in a component, loop through blocks, for each block loop through neighbors

#

I'd probably add some components to distinguish between blocks with grass and without, could just be an empty struct (marker)

#

And then have two queries, one for those with grass and one for those without. Without grass query also contains the neighbor component

#

And then do something like if neighbors.iter().any(|e| grass_query.get(e).is_ok()) {/* regrow logic */ }

#

That way you also only iterate the blocks without grass and don't waste time on the ones that don't need to think about regrowing

#

And this specific approach also gets around the annoying fact that the iteration direction could matter

shrewd kite
#

Thanks, how could I get an vec of entities, I would spawn blocks like this:

pub fn spawn_blocks( mut commands: Commands, window_query: Query<&Window, With<PrimaryWindow>>, asset_server: Res<AssetServer>, ) { let window = window_query.get_single().unwrap(); let x_max: usize = 3; let y_max: usize = 3; for x in 0..x_max { for y in 0..y_max { commands.spawn(( SpriteBundle { transform: Transform::from_xyz( window.width() / 2.0 + (x as f32 * TEXTURESIZE), window.height() / 2.0 + (y as f32 * TEXTURESIZE), 0.0, ), texture: asset_server.load("sprites/Gras.png"), ..default() }, EnviromentBlock { location: Vec2 { x: x as f32, y: y as f32, }, block: components::Block::Gras, }, )); } } }

green vault
#

you could, as you spawn them, store the entities in a hashmap with (x, y) keys and entity values

#

then use that to loop again and apply neighbours

placid shuttle
#

If you use three backticks ` on either side, it gives you a code block that looks like this:

pub fn spawn_blocks(
    mut commands: Commands,
    window_query: Query<&Window, With<PrimaryWindow>>,
    asset_server: Res<AssetServer>,
) {
    let window = window_query.get_single().unwrap();
    let x_max: usize = 3;
    let y_max: usize = 3;
    for x in 0..x_max {
        for y in 0..y_max {
            commands.spawn((
                SpriteBundle {
                    transform: Transform::from_xyz(
                        window.width() / 2.0 + (x as f32 * TEXTURESIZE),
                        window.height() / 2.0 + (y as f32 * TEXTURESIZE),
                        0.0,
                    ),
                    texture: asset_server.load("sprites/Gras.png"),
                    ..default()
                },
                EnviromentBlock {
                    location: Vec2 {
                        x: x as f32,
                        y: y as f32,
                    },
                    block: components::Block::Gras,
                },
            ));
        }
    }
}

And if you put rs or rust after the first three it gives you syntax highlighting

#

Also hardly relevant but in general it's easier to adjust camera viewport size than to resize the sprites like that.

#

You could just choose that your view area is a certain size like 10 by 10 and set the camera to render that

#

By default 1 unit in the world gets rendered as 1 pixel I believe

#

But yeah what Haddock said