Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Entity labeling #11897

Closed
Itsnotdone opened this issue Feb 16, 2024 · 9 comments
Closed

Entity labeling #11897

Itsnotdone opened this issue Feb 16, 2024 · 9 comments
Labels
A-ECS Entities, components, systems, and events C-Feature A new feature, making something new possible S-Duplicate This issue or PR already exists

Comments

@Itsnotdone
Copy link

What problem does this solve or what need does it fill?

Easier iterating over entities, you dont need to create multiple queries to distinguish entities. Currently you need to create two queries to get (for example) Enemy and Player, also it may be useful for future editor

What solution would you like?

Something like:

commands.spawn((transform, health).label("Player"));
commands.spawn((transform, health).label("Enemy"));

fn my_system(query: Query<(&Transform, &Health)>){
    let (e_transform, e_health) = query.label("Enemy").unwrap();
    let (p_transform, p_health) = query.label("Player").unwrap();
}

What alternative(s) have you considered?

Storing the Entity ID and using query.get(entity)

Additional context

@Itsnotdone Itsnotdone added C-Feature A new feature, making something new possible S-Needs-Triage This issue needs to be labelled labels Feb 16, 2024
@Adamkob12
Copy link
Contributor

I agree, I've been thinking about tagging / labeling entities lately and it makes sense.

@DasLixou
Copy link
Contributor

Seems like a duplicate of #6556 . I also made a crate for this which is linked to in this issue but it hasn't been updated since 0.10. if you want, you can fork or pr tho

@Veritius
Copy link

Veritius commented Feb 16, 2024

Can't you create a marker component and use With<T> to filter the query?

#[derive(Component)]
struct Player;

#[derive(Component)]
struct Enemy;

fn spawn_system(
    mut commands: Commands,
) {
    commands.spawn((transform, health, Player));
    commands.spawn((transform, health, Enemy));
}

fn my_system(
    player: Query<(&Transform, &Health), With<Player>>,
    enemy: Query<(&Transform, &Health), With<Enemy>>,
) {
    let (p_transform, p_health) = player.single();
    let (e_transform, e_health) = enemy.single();
}

If you don't want to use marker components, you could make a WorldQuery that filters by the Name component, but that's fallible (Name components do not guarantee that they are unique)

@alice-i-cecile
Copy link
Member

Yeah, I think this is functionally a duplicate. Not opposed, but just want to collect discussion.

@alice-i-cecile alice-i-cecile closed this as not planned Won't fix, can't repro, duplicate, stale Feb 16, 2024
@alice-i-cecile alice-i-cecile added S-Duplicate This issue or PR already exists A-ECS Entities, components, systems, and events and removed S-Needs-Triage This issue needs to be labelled labels Feb 16, 2024
@Itsnotdone
Copy link
Author

Can't you create a marker component and use With<T> to filter the query?

#[derive(Component)]
struct Player;

#[derive(Component)]
struct Enemy;

fn spawn_system(
    mut commands: Commands,
) {
    commands.spawn((transform, health, Player));
    commands.spawn((transform, health, Enemy));
}

fn my_system(
    player: Query<(&Transform, &Health), With<Player>>,
    enemy: Query<(&Transform, &Health), With<Enemy>>,
) {
    let (p_transform, p_health) = player.single();
    let (e_transform, e_health) = enemy.single();
}

If you don't want to use marker components, you could make a WorldQuery that filters by the Name component, but that's fallible (Name components do not guarantee that they are unique)

yes, but you need to create 2 queries, this example is simple but what if you had more complicated case?

@DasLixou
Copy link
Contributor

@Itsnotdone when there only exists one "player" or "enemy" at the same time, you can use entity markers. When there are multiple you won't get around multiple queries. Also note that the queries mustn't overlap, so you must add Without<Enemy/Player> to the queries

@Itsnotdone
Copy link
Author

Seems like a duplicate of #6556 . I also made a crate for this which is linked to in this issue but it hasn't been updated since 0.10. if you want, you can fork or pr tho

Not exactly, because in this proposal you need to add every tag to query which you are requesting, thats horrible if you have more tags (or am i wrong?)

@DasLixou
Copy link
Contributor

Seems like a duplicate of #6556 . I also made a crate for this which is linked to in this issue but it hasn't been updated since 0.10. if you want, you can fork or pr tho

Not exactly, because in this proposal you need to add every tag to query which you are requesting, thats horrible if you have more tags (or am i wrong?)

yes that's because it initially was meant to provide some parallelism hints but that wasn't done.

@DasLixou
Copy link
Contributor

Never the less, as alice says you are welcome to contribute your ideas to the open issue.
So what I think you want is a way to label entities and query them without much stuff inside the system params.
The reason why my crate does that is because every marker is stored inside a resource and modifing marker A shouldn't stop bevy from parallelizing a system which modifies marker B.
One thing I don't understand is whether you only want to mark/label one entity or multiple with the same label

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ECS Entities, components, systems, and events C-Feature A new feature, making something new possible S-Duplicate This issue or PR already exists
Projects
None yet
Development

No branches or pull requests

5 participants