Skip to content

Add EntityMut::components and EntityRef and EntityWorldMut equivalent #13127

@alice-i-cecile

Description

@alice-i-cecile

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

Some users (and applications) prefer a more game-object style of writing Bevy: fetching fat components directly from the ECS and quickly changing the data needed as their systems evolve.

This style can be comfortable and productive to write, but this path isn't adequately taught or supported.
In particular, accessing multiple components from a single entity in an ad hoc way is very useful for avatar-centric games like platformers or ARPGs, but is frustrating to do.

What solution would you like?

fn get_components<D: QueryData>(&mut self) ->Option<D::Item>

This proposed method takes any type that implements QueryData (like (&mut Transform, &Life) and returns the type that would be fetched by an equivalent query. Note that the type signature is actually messier, using as associated types and an as WorldQuery.

Both EntityMut and EntityWorldMut should have this method added as is. EntityRef requires an additional bound on D: it must instead be a ReadOnlyQueryData.

What alternative(s) have you considered?

There's various get methods which return a single component at a time. These are less flexible, as they return only a single component.

We could return a Result with a QueryItemError, like Query::get, but most of its variants will never be hit.

We could add a QueryFilter generic to these methods, but there's no point: we're already working on a single entity!

We could add a get_components_mut method, and have get_components as a way to fetch the read-only form. Given that this is a convenience API designed for handcrafted code, I don't think this is a useful transformation to expose here at the cost of ergonomics.

We could make this panicking by default or add a panicking equivalent, but as per #12660, this is likely to increase user suffering overall.

Additional context

I also think we should prioritize implementing let (mut transform, player) = entity.components::<(&mut Transform, &Player)>(), as I think it shores up a pretty big pain point.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-ECSEntities, components, systems, and eventsC-UsabilityA targeted quality-of-life change that makes Bevy easier to useD-ComplexQuite challenging from either a design or technical perspective. Ask for help!S-Needs-DesignThis issue requires design work to think about how it would best be accomplished

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions