Closed12

作業メモ:bevy 0.10 → 0.11

hyoihyoi

add_plugin()add_plugins()に変わった。

0.10
App::new()
    .add_plugin( InitApp )
    .run();
0.11
App::new()
    .add_plugins( InitApp )
    .run();
hyoihyoi

enum KeyCodeのバリアントで、名称変更あり。
LXxxXxxLeftに、RXxxXxxRrightになった。

0.10
pub const _KEY_ALT_RIGHT: KeyCode = KeyCode::RAlt;
pub const _KEY_ALT_LEFT : KeyCode = KeyCode::LAlt;
0.11
pub const _KEY_ALT_RIGHT: KeyCode = KeyCode::AltRight;
pub const _KEY_ALT_LEFT : KeyCode = KeyCode::AltLeft;
hyoihyoi

Stylepositionがなくなった。その代わりtopleftが追加された。

0.10
let style = Style
{   position: UiRect { left, top, ..default() },
    size: Size { width, height },
    ..default()
};
0.11
let style = Style
{   left,
    top,
    width,
    height,
    ..default()
};
hyoihyoi

現在のStateを取得する際state.0とするのではなく、state.get()になった。
なお、0.10ではstate.0に対して書き込みできたが、0.11ではできない。
(state.0 = MyState::Pause;のような使い方だが、元々0.10でも非公式だったかもしれない)

以下の例ではnow_stateを直接書き換えているが、普通はnext_state.set()を使う。
このような書き方をしている理由は、PAUSE処理の要件上、Stateの切り替えでOnEnterOnExitが実行されない必要があるため。(next_state.set()だと実行される)

0.11
use bevy::prelude::*;

#[allow( dead_code )]
#[derive( Clone, Copy, Eq, PartialEq, Hash, Debug, Default, States )]
enum MyState
{   #[default] InitApp, InitGame,
    TitleDemo, DemoLoop,
    GameStart, StageStart, MainLoop, StageClear, GameOver,
    EventCheck, EventLoop,
    Pause, Debug,
}

fn main()
{   App::new()
    .add_plugins( DefaultPlugins )
    .add_state::<MyState>()
    .add_systems( Update, pause_with_esc_key )
    .run();
}

fn pause_with_esc_key
(   mut now_state: ResMut<State<MyState>>,
    // mut next_state: ResMut<NextState<MyState>>,
    mut backup_state: Local<MyState>,
    mut inkey: ResMut<Input<KeyCode>>,
)
{   //入力がないなら
    if ! inkey.just_pressed( KeyCode::Escape ) { return }

    //debug write
    dbg!( now_state.get() );

    //PAUSE⇔その他 切り替え
    if *now_state.get() == MyState::Pause
    {   //PAUSEから復帰
        // next_state.set( *backup_state );
        *now_state = State::new( *backup_state );
    }
    else
    {   //PAUSEする
        *backup_state = *now_state.get();
        // next_state.set( MyState::Pause );
        *now_state = State::new( MyState::Pause );
    }

    //NOTE: https://bevy-cheatbook.github.io/programming/states.html#with-input
    inkey.reset( KeyCode::Escape );
}
hyoihyoi

ECSのAPIに大掛かりな変更がある。
0.10で強化されたECSのAPIに対し、暗黙の動作が多い点と記述が複雑になりがちな点が見直され、明示的で単一の文法(=読みやすい)に変更された。

  • app.add_system()app.add_systems()に統一された。
  • ステージを前置で明示してSystemを登録するようになった。
0.10
app
.add_systems
(   (   spawn_camera.on_startup(), //登録するステージを .on_startup() で指定
        pause_with_esc_key,        //暗黙にUpdateステージに登録される
    )
)
.add_systems
(   (   spawn_game_frame,
        spawn_info.run_if( || cfg!( debug_assertions ) ),
    )
    .in_schedule( OnEnter ( MyState::InitApp ) )
)
;
0.11
app
.add_systems( Startup, spawn_camera       )
.add_systems( Update , pause_with_esc_key )
.add_systems
(   OnEnter ( MyState::InitApp ),
    (   spawn_game_frame,
        spawn_info.run_if( || cfg!( debug_assertions ) ),
    )
)
;

ただUpdateStateを指定したい場合は少し戸惑う。
0.10にあったOnUpdate ( MyState::Xxxx )が0.11にはない。
.run_if( in_state( MyState::Xxxx ) )を後置するが、統一感がなくて読みにくいように感じる。

0.10
app
.add_system( syetem_a.in_schedule( OnEnter  ( MyState::InitApp ) ) )
.add_system( system_b.in_set     ( OnUpdate ( MyState::InitApp ) ) )
.add_system( system_c.in_schedule( OnExit   ( MyState::InitApp ) ) )
;
0.11
app
.add_systems( OnEnter ( MyState::InitApp ), syetem_a )
.add_systems( Update, system_b.run_if( in_state( MyState::InitApp ) ) )
.add_systems( OnExit  ( MyState::InitApp ), system_c )
;
hyoihyoi

Eventの型には#[derive( Event )]を付けるようになった。

0.10
struct EventOver;
0.11
#[derive( Event )]
struct EventOver;
hyoihyoi

前述のStylepositionと同様にsizeもなくなった。代わりにwidthheightが追加された。

0.10
let per100 = Val::Percent( 100.0 );
let width  = Val::Px( SCREEN_PIXELS_WIDTH  );
let height = Val::Px( SCREEN_PIXELS_HEIGHT );

let style_a = Style { size: Size::new( per100, per100 ), ..default() };
let style_b = Style { size: Size::new( width, height ), ..default() };
0.11
let per100 = Val::Percent( 100.0 );
let width  = Val::Px( SCREEN_PIXELS_WIDTH  );
let height = Val::Px( SCREEN_PIXELS_HEIGHT );

let style_a = Style { width: per100, height: per100, ..default() };
let style_b = Style { width, height, ..default() };
hyoihyoi

実行時のpanicのメモ。
TextSection.value"\n ".to_string()をセットしたら実行時にpanicすることがあった。
半角空白文字を削除したら(つまり"\n".to_string()にしたら)解消した。
" ".to_string()でもpanicしたので、何か不具合があるのかもしれない。

エラーメッセージ
thread 'Compute Task Pool (5)' panicked at 'min > max, or either was NaN. min = 677.75183, max = 672.0', /rustc/90c541806f23a127002de5b4038be731ba1458ca\library\core\src\num\f32.rs:1394:9 
hyoihyoi

FPSの表示に使っていたDiagnosticsDiagnosticsStoreに名称変更されていた。

0.10
    diag: Res<Diagnostics>,
0.11
    diag: Res<DiagnosticsStore>,
hyoihyoi

音量の指定がf32からVolumeに変わった。

0.10
let volume = VOLUME_SOUND_BEEP; //f32
audio.play_with_settings
(   asset_svr.load( ASSETS_SOUND_BEEP ),
    PlaybackSettings::ONCE.with_volume( volume )
);
0.11
use bevy::audio::*;

let volume = Volume::Relative( VolumeLevel::new( VOLUME_SOUND_BEEP ) );
audio.play_with_settings
(   asset_svr.load( ASSETS_SOUND_BEEP ),
    PlaybackSettings::ONCE.with_volume( volume )
);
hyoihyoi

.run_if()を使うときのメモ
in_state()not()以外にもConditionトレイトを実装した関数がいろいろある。
0.11工事中ドキュメント(2023/7/9現在)によると下表のとおり。
https://dev-docs.bevyengine.org/bevy/ecs/schedule/common_conditions/index.html

common_conditions DeepL先生訳
any_component_removed::<Component>() 与えられた型のコンポーネントが取り除かれたエンティティがあれば真を返す、条件を満たすクロージャを生成します。
any_with_component::<Component>() 指定された型のコンポーネントを持つエンティティが存在する場合にtrueを返す条件を満たすクロージャを生成します。
in_state(State::Variant) ステートマシンが現在ステートにある場合に真を返す、コンディションを満たすクロージャを生成します。
not(bool) 渡されたコンディションの結果を反転するコンディションを生成します。
on_event(Event) 最後に呼び出されてから、指定されたタイプの新しいイベントがあれば真を返す、条件を満たすクロージャを生成します。
resource_added::<Resource>() この条件が最後にチェックされてから、指定された型のリソースが追加された場合にtrueを返す条件を満たすクロージャを生成します。
resource_changed::<Resource>() 指定された型のリソースが、最後にチェックされたときから値が変更された場合に真を返す、条件を満たすクロージャを生成します。
resource_changed_or_removed::<Resource>() 指定された型のリソースが、最後にチェックされたときから値が変更された場合に真を返す、条件を満たすクロージャを生成します。
resource_equals(Resource(Value)) リソースが値と等しい場合に真を返す、条件を満たすクロージャを生成します。
resource_exists::<Resource>() リソースが存在する場合に真を返す、条件を満たすクロージャを生成します。
resource_exists_and_changed::<Resource>() 指定された型のリソースが、最後にチェックされたときから値が変更された場合に真を返す、条件を満たすクロージャを生成します。
resource_exists_and_equals(Resource(Value)) リソースが存在し、値と等しい場合にtrueを返す、条件を満たすクロージャを生成します。
resource_removed::<Resource>() 指定された型のリソースが最後にチェックされたときから削除された場合に真を返す、条件を満たすクロージャを生成します。
run_once() 条件が最初に実行されたときに真を、それ以降は毎回偽を返す、条件を満たすクロージャを生成します。
state_changed::<State>() ステートマシンが状態を変更した場合に真を返す、条件を満たすクロージャを生成します。
state_exists::<State>() ステートマシンが存在する場合に真を返す、条件を満たすクロージャを生成します。
state_exists_and_equals(State::Variant) ステートマシンが存在し、現在ステートにある場合に真を返す、条件を満たすクロージャを生成します。
hyoihyoi

3Dの影が表示されない現象の対応メモ。
現象を確認した環境は、Windows11 & Bevy0.11。(Bevy0.10でも見た記憶が‥‥)
WebGPU の backend として DX12 を明示すると現象を回避できた。
Windows11&DX12Windows11 & backend: DX12
Windows11&VulkanWindows11 & backend: Vulkan
backend の変更は DefaultPlugins の RenderPlugin を使う。

use bevy::{prelude::*, render::*, render::settings::*};

fn main()
{   let backends = Some ( Backends::DX12 );
    let wgpu_settings = WgpuSettings { backends, ..default() };

    App::new()
        .add_plugins( DefaultPlugins.set( RenderPlugin { wgpu_settings } ) )
        .run();
}

情報ソース

このスクラップは2023/08/15にクローズされました