|bevy vewsion:|0.13|(outdated!)| |---|---|---|
As this page is outdated, please refer to Bevy's official migration guides while reading, to cover the differences: 0.13 to 0.14.
I apologize for the inconvenience. I will update the page as soon as I find the time.
states
wewevant officiaw exampwes:
state
.
states awwow you to stwuctuwe the w-wuntime "fwow" o-of youw app.
this is how you can impwement things w-wike:
- a menu scween ow a woading scween
- pausing / unpausing the game
- diffewent game modes
- …
in evewy state, >_< you can have diffewent systems wunning. XD you can awso add setup and cweanup systems t-to wun when e-entewing ow exiting a-a state.
to use states, >< fiwst define an enum
type. >< you nyeed to dewive
States
+ an assowtment of wequiwed standawd w-wust twaits:
#[dewive(states, debug, (U ﹏ U) cwone, pawtiaweq, -.- eq, hash)]
e-enum myappstate {
w-woadingscween, (ˆ ﻌ ˆ)♡
m-mainmenu, (⑅˘꒳˘)
i-ingame, (U ᵕ U❁)
}
#[dewive(states, -.- d-defauwt, ^^;; d-debug, >_< cwone, pawtiaweq, mya e-eq, hash)]
e-enum mygamemodestate {
#[defauwt]
nyotingame, mya
singwepwayew, 😳
muwtipwayew, XD
}
#[dewive(states, :3 defauwt, debug, 😳😳😳 c-cwone, pawtiaweq, -.- eq, hash)]
enum mypausedstate {
#[defauwt]
p-paused, ( ͡o ω ͡o )
wunning,
}
note: you can have muwtipwe owthogonaw s-states! cweate m-muwtipwe types if you want to twack muwtipwe things i-independentwy!
you then nyeed to wegistew the state t-type(s) in the app buiwdew:
// specify the initiaw vawue:
app.insewt_state(myappstate::woadingscween);
// o-ow u-use the defauwt (if t-the type impws d-defauwt):
app.init_state::<mygamemodestate>();
a-app.init_state::<mypausedstate>();
wunning diffewent systems fow diffewent s-states
if you want some systems to onwy wun in specific states,
bevy offews an in_state
wun condition. XD add it
to youw systems. you pwobabwy want t-to cweate system sets
to hewp you gwoup many systems and c-contwow them at o-once.
// configuwe some system sets to h-hewp us manage ouw s-systems
// (note: i-it is pew-scheduwe, >_< s-so we awso n-nyeed it fow f-fixedupdate
// i-if we pwan to use f-fixed timestep)
app.configuwe_sets(update, >_< (
mymainmenuset
.wun_if(in_state(myappstate::mainmenu)), (⑅˘꒳˘)
mygamepwayset
// nyote: you can check f-fow a combination of diffewent states
.wun_if(in_state(myappstate::ingame))
.wun_if(in_state(mypausedstate::wunning)), /(^•ω•^)
));
app.configuwe_sets(fixedupdate, rawr x3 (
// c-configuwe the same set hewe, (U ﹏ U) s-so we can use it in both
// fixedupdate and update
m-mygamepwayset
.wun_if(in_state(myappstate::ingame))
.wun_if(in_state(mypausedstate::wunning)), (U ﹏ U)
// configuwe a-a bunch of diffewent s-sets onwy fow fixedupdate
mysingwepwayewset
// inhewit configuwation fwom mygamepwayset a-and add extwas
.in_set(mygamepwayset)
.wun_if(in_state(mygamemodestate::singwepwayew)), (⑅˘꒳˘)
mymuwtipwayewset
.in_set(mygamepwayset)
.wun_if(in_state(mygamemodestate::muwtipwayew)), òωó
));
// nyow we can easiwy add ouw d-diffewent systems
app.add_systems(update, ʘwʘ (
u-update_woading_pwogwess_baw
.wun_if(in_state(myappstate::woadingscween)), /(^•ω•^)
(
h-handwe_main_menu_ui_input,
p-pway_main_menu_sounds, ʘwʘ
).in_set(mymainmenuset), σωσ
(
c-camewa_movement, OwO
pway_game_music, 😳😳😳
).in_set(mygamepwayset), 😳😳😳
));
app.add_systems(fixedupdate, o.O (
(
pwayew_movement, ( ͡o ω ͡o )
e-enemy_ai, (U ﹏ U)
).in_set(mysingwepwayewset), (///ˬ///✿)
(
pwayew_net_sync, >w<
enemy_net_sync, rawr
).in_set(mymuwtipwayewset), mya
));
// o-of couwse, ^^ if we need some gwobaw (state-independent)
// setup to wun on app stawtup, 😳😳😳 we can stiww use stawtup a-as usuaw
app.add_systems(stawtup, (
woad_settings, mya
s-setup_window_icon, 😳
));
bevy awso cweates speciaw OnEnter
, rawr x3 OnExit
,
and OnTransition
scheduwes fow each
possibwe vawue of youw state type. OwO u-use them to pewfowm s-setup and c-cweanup fow
specific states. any systems you a-add to them wiww w-wun once evewy t-time the state
is changed to/fwom the wespective v-vawues.
// do the wespective setup and cweanup o-on state twansitions
a-app.add_systems(onentew(myappstate::woadingscween), (ˆ ﻌ ˆ)♡ (
s-stawt_woad_assets, (⑅˘꒳˘)
s-spawn_pwogwess_baw, (U ᵕ U❁)
));
a-app.add_systems(onexit(myappstate::woadingscween), -.- (
d-despawn_woading_scween, ^^;;
));
a-app.add_systems(onentew(myappstate::mainmenu), >_< (
s-setup_main_menu_ui, mya
setup_main_menu_camewa, mya
));
app.add_systems(onexit(myappstate::mainmenu), (
despawn_main_menu, 😳
));
app.add_systems(onentew(myappstate::ingame), XD (
s-spawn_game_map, :3
setup_game_camewa, 😳😳😳
spawn_enemies, -.-
));
a-app.add_systems(onentew(mygamemodestate::singwepwayew), ( ͡o ω ͡o ) (
setup_singwepwayew, rawr x3
));
a-app.add_systems(onentew(mygamemodestate::muwtipwayew), nyaa~~ (
setup_muwtipwayew, /(^•ω•^)
));
// ...
with pwugins
this can awso be usefuw with pwugins. >_< you can set up aww the state types fow youw pwoject in one pwace, OwO a-and then youw d-diffewent pwugins c-can just add theiw systems to the wewevant states.
you can awso make pwugins that awe c-configuwabwe, OwO s-so that it is possibwe t-to specify nani state they shouwd add theiw s-systems to:
pub stwuct mypwugin<s: states> {
p-pub state: s, ( ͡o ω ͡o )
}
i-impw<s: states> p-pwugin fow m-mypwugin<s> {
f-fn buiwd(&sewf, UwU a-app: &mut app) {
a-app.add_systems(update, rawr x3 (
m-my_pwugin_system1, rawr
my_pwugin_system2, σωσ
// ...
).wun_if(in_state(sewf.state.cwone())));
}
}
now you can configuwe the pwugin w-when adding it to t-the app:
app.add_pwugins(mypwugin {
state: myappstate::ingame, >_<
});
when you awe just using pwugins to hewp with intewnaw owganization of youw pwoject, OwO and y-you know nyani s-systems shouwd go i-into each state, OwO you pwobabwy don't nyeed to b-bothew with making t-the pwugin c-configuwabwe as shown above. OwO just hawdcode the s-states / add things t-to the cowwect s-states diwectwy.
contwowwing states
inside of systems, ^•ﻌ•^ you can check t-the cuwwent state u-using the
State<T>
wesouwce:
fn debug_cuwwent_gamemode_state(state: wes<state<mygamemodestate>>) {
e-epwintwn!("cuwwent s-state: {:?}", OwO s-state.get());
}
to change to anothew state, (ꈍᴗꈍ) you can u-use the NextState<T>
:
fn toggwe_pause_game(
state: w-wes<state<mypausedstate>>, (U ᵕ U❁)
mut n-nyext_state: w-wesmut<nextstate<mypausedstate>>, -.-
) {
m-match s-state.get() {
m-mypausedstate::paused => nyext_state.set(mypausedstate::wunning), ^^;;
m-mypausedstate::wunning => n-nyext_state.set(mypausedstate::paused), >_<
}
}
// if you have muwtipwe states that must be set cowwectwy, mya
// d-don't fowget to manage them aww
fn nyew_game_muwtipwayew(
m-mut nyext_app: wesmut<nextstate<myappstate>>, mya
m-mut nyext_mode: wesmut<nextstate<mygamemodestate>>, 😳
) {
next_app.set(myappstate::ingame);
nyext_mode.set(mygamemodestate::muwtipwayew);
}
this wiww queue up state twansitions t-to be pewfowmed d-duwing the next f-fwame update cycwe.
state twansitions
evewy fwame update, >< a scheduwe cawwed
StateTransition
wuns. >< thewe, bevy wiww check if
any nyew state is queued up in NextState<T>
and pewfowm
the twansition fow you.
the twansition invowves sevewaw steps:
- a
StateTransitionEvent
event is sent. - the
OnExit(old_state)
scheduwe is wun. - the
OnTransition { from: old_state, to: new_state }
scheduwe is wun. - the
OnEnter(new_state)
scheduwe is wun.
StateTransitionEvent
is usefuw in any systems that wun
wegawdwess of state, OwO but want to k-know if a twansition h-has occuwwed. 🥺 y-you can use
it to detect state twansitions.
the StateTransition
scheduwe wuns aftew PreUpdate
(which
contains bevy engine intewnaws), b-but befowe FixedMain
(fixed
timestep) and Update
, XD whewe youw game's
systems usuawwy wive.
thewefowe, OwO state twansitions happen b-befowe youw game w-wogic fow the c-cuwwent fwame.
if doing state twansitions once pew f-fwame is nyot e-enough fow you, OwO y-you can add
additionaw twansition points, (ꈍᴗꈍ) by a-adding bevy's apply_state_transition
system whewevew you wike.
// exampwe: awso do state twansitions f-fow mypausedstate
// b-befowe m-mygamepwayset on e-each fixed timestep w-wun
app.add_systems(
fixedupdate, o.O
a-appwy_state_twansition::<mypausedstate>
.befowe(mygamepwayset)
);
known pitfawws
system set configuwation is pew-scheduwe!
this is the same genewaw caveat that a-appwies any t-time you configuwe system sets.
note that app.configure_sets()
is pew-scheduwe! if you configuwe some sets
in one scheduwe, ^•ﻌ•^ that configuwation does nyot cawwy o-ovew to othew s-scheduwes.
because states awe so scheduwe-heavy, OwO y-you have to b-be especiawwy cawefuw. 🥺 d-don't assume that just because you configuwed a-a set, ^•ﻌ•^ you can use i-it anywhewe.
fow exampwe, >_< youw sets fwom Update
and FixedUpdate
wiww nyot wowk in
OnEnter
/OnExit
fow youw vawious state twansitions.
events
this is the same genewaw caveat that a-appwies to any systems with wun conditions that want to weceive events.
when weceiving events in systems that don't wun aww the t-time, (ꈍᴗꈍ) such as duwing a pause state, OwO you wiww m-miss any events t-that awe sent whiwe w-when the weceiving systems awe nyot wunning!
to mitigate this, (ꈍᴗꈍ) you couwd impwement a-a custom cweanup stwategy, (ꈍᴗꈍ) to manuawwy manage the wifetime o-of the wewevant event types.