bevy icon indicating copy to clipboard operation
bevy copied to clipboard

Rename `StateScoped` to `StateExitDespawn`, add the inverse variant `StateEntryDespawn`

Open Jaso333 opened this issue 1 year ago • 1 comments

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

The current naming of the StateScoped component is slightly misleading: it could be interpreted as "this entity will not exist outside of this state". Whereas in fact it merely despawns on exit of the given state, it doesn't care if you spawn an entity outside of the given state:

for (entity, binding) in &query {
    if binding.0 == *exited {
        #[cfg(feature = "bevy_hierarchy")]
        commands.entity(entity).despawn_recursive();
        #[cfg(not(feature = "bevy_hierarchy"))]
        commands.entity(entity).despawn();
    }
}

To me, this functionality is fine, I can't think of a situation where you would want to spawn something in a state it doesn't belong, only for it to be deleted instantly.

There is also no available inverse of this component: despawn an entity on entry to a state, which I recently found a need for, and have written a very similar mechanism to achieve the same thing.

What solution would you like?

  • Rename StateScoped to StateExitDespawn, or maybe a cleaner looking name than that.
  • Add the inverse version: StateEntryDespawn, having it operate during state transition, before OnEnter.

Here's a snippet of what I produced for my own game:

impl AppExtLifetime for SubApp {
    fn enable_state_entry_despawn<S: States>(&mut self) -> &mut Self {
        self.add_systems(
            StateTransition,
            state_entry_despawn::<S>
                .in_set(TransitionSchedules::<S>::default())
                .run_if(on_event::<StateTransitionEvent<S>>()),
        );
        self
    }
}

What alternative(s) have you considered?

No real alternatives.

Additional context

State transitions are such a powerful and flexible way to orchestrate game entity lifecyles and the flow of the game itself, it would be nice to see more features in this area.

Jaso333 avatar Oct 11 '24 12:10 Jaso333

IMO having entities "scoped to a particular state" is more simple concept than despawn-on-entry/exit. If StateScoped gets warning (or even instant despawn) against insertion during mismatched state, then these new components could be added to fill the gaps for advanced use.

akimakinai avatar Oct 12 '24 15:10 akimakinai

Note that this also opens the door to expanding the type into an enum as such (from pyri_state):

pub enum DespawnOnExit<S: State> {
    Single,
    #[default]
    Recursive,
    Descendants,
    #[doc(hidden)]
    _PhantomData(PhantomData<S>),
}

Also "despawn on enter", "hide on enter", "hide on exit", "disable on enter" (with entity disabling), etc. variants become very reasonable to add.

benfrankel avatar Nov 09 '24 01:11 benfrankel