Skip to content

Make Option<T> a component where T implements Component #19568

@Freyja-moth

Description

@Freyja-moth

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

When trying to spawn an optional component currently the only way to do it is with an if let

fn spawn_optional(mut commands: Commands, option: Option<TextFont>) {
    if let Some(font) = option {
        commands.spawn(font);
    } 
}

But this can be awkward when trying to spawn other things along it

fn spawn_optional(mut commands: Commands, option: Option<TextFont>) {
    if let Some(font) = option {
        commands.spawn((
            font,
            Text::new("Hello there"),
        ));
    } else {
        commands.spawn(
            Text::new("Hello there");
        );
    }
}

What solution would you like?

Either implement Component for Option<T> where T: Component and make it such that the component is only added when the option is some.

Or add a new method insert_optional that takes an optional component and only spawns it when the option is Some.

pub fn insert_optional<T: Bundle>(&mut self, bundle: Option<T>) -> &mut Self
where
    T: Component,
{
    if let Some(bundle) = bundle {
        self.spawn(bundle);
    }
    self
}

I'm personally partial to the first method as it means that all previous methods, such as insert_if and insert_if_new, work with it.

What alternative(s) have you considered?

The old method, but that is quite clumsy, especially for multiple optional components.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-ECSEntities, components, systems, and eventsC-FeatureA new feature, making something new possible

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions