#bevy-ecs #ecs #bevy #game

conditional_commands

Bevy命令扩展

7个版本 (破坏性更新)

0.7.0 2022年11月15日
0.6.0 2022年8月1日
0.5.0 2022年6月22日
0.4.0 2022年6月21日
0.1.0 2022年5月30日

#1783 in 游戏开发

MIT/Apache

18KB
136

条件命令

此crate实现了三个扩展特质,允许在无需中间 EntityCommandsEntityMut 绑定的情况下进行条件组件、捆绑和子插入。

  • ConditionalInsertBundleExt 用于 EntityCommandsEntityMut
    方法
    • insert_if
    • insert_if_else
    • insert_some
    • insert_some_or
  • ConditionalChildBuilderExt 用于 EntityCommands
    方法
    • with_children_if
  • ConditionalWorldChildBuilderExt 用于 EntityMut
    方法
    • with_children_if

支持Bevy 0.9

用法

要添加到项目中,可以使用以下方法之一:

cargo add conditional_commands

或手动添加到您的Cargo.toml中

[dependencies]
conditional_commands = "0.9.0"

一个激励性的但人为的ECS Fizz-Buzz示例

use bevy::prelude::*;
use conditional_commands::*;

#[derive(Component)]
struct FizzBuzzer;

#[derive(Component)]
struct Number(usize);

#[derive(Component)]
struct Fizz;

#[derive(Component)]
struct Buzz;

fn fizz_buzz<const N: usize>(
    mut commands: Commands
) {
    for n in 1 ..= N {
        let mut entity_commands = commands.spawn(FizzBuzzer);
        match (n % 3, n % 5) {
            (0, 0) => { entity_commands.insert((Fizz, Buzz)); },
            (0, _) => { entity_commands.insert(Fizz); },
            (_, 0) => { entity_commands.insert(Buzz); },
            _ => { entity_commands.insert(Number(n)); }
        }
    }
}

使用条件命令,不再需要中间的EntityCommands绑定。

fn fizz_buzz<const N: usize>(
    mut commands: Commands
) {
    for n in 1 ..= N {
        commands
        .spawn(FizzBuzzer)
        .insert_if(0 < n % 3 && 0 < n % 5, || Number(n))
        .insert_if(n % 3 == 0, || Fizz)
        .insert_if(n % 5 == 0, || Buzz);
    }
}

ConditionalInsertBundleExt 也为 EntityMut 实现了

#[derive(Component)]
struct Even;

#[derive(Component)]
struct Odd;

fn exclusive_system(world: &mut World) {
    for n in 0..10 {
        world.spawn_empty().insert_if_else(n % 2 == 0, || Even, || Odd);
    }
}    

传递给 _else/_or 方法的捆绑不需要是同一类型,如上例中的 EvenOdd 组件所示。

使用 insert_some 来插入可选捆绑的内部值,如果存在的话。

commands.spawn(MyBundle)
    .insert_some(Some(OtherBundle::default()))
    .insert_some_or(None::<MyThing>, AlternativeThing::default);

示例

cargo run --example exclusive
cargo run --example fizz_buzz
cargo run --example insert_if
cargo run --example insert_if_2
cargo run --example with_children_if

备注

  • 我还没有进行任何基准测试。对于性能关键的系统,最好一次生成整个捆绑。

  • 此crate的早期版本中每个插入方法都有急切和懒惰版本。我不确定急切版本有什么优势(除了没有 ||),所以它们已被移除。

  • 我无法很好地处理生命周期以获得适用于 EntityCommandsEntityMut 的单个泛型子构建器特质。

依赖项

~15–31MB
~483K SLoC