#枚举 #变体 #bevy #过滤器 #查询 #语义

bevy_enum_filter

在Bevy查询中根据枚举变体进行过滤

4个版本 (2个破坏性更新)

0.3.0 2023年11月18日
0.2.0 2023年9月2日
0.1.1 2022年10月6日
0.1.0 2022年10月6日

#1158 in 游戏开发

每月26次下载

MIT/Apache

35KB
120 代码行

bevy_enum_filter

Crates.io Docs License

根据枚举变体过滤查询!

在Rust中,枚举变体不是类型。这意味着我们通常不能在Bevy Query中进行过滤。那么替代方案是使用一组“标记”组件。这足够好,但我们失去了使用枚举的语义(以及执行枚举特定操作的能力,例如match)。

这个crate允许我们根据枚举组件的特定变体进行查询

use bevy::prelude::*;
use bevy_enum_filter::prelude::*;

#[derive(Component, EnumFilter)]
enum ItemType {
  Equippable(usize),
  Weapon(usize),
  Potion(usize)
}

fn apply_potion(item_query: Query<(Entity, &ItemType), Added<Enum!(ItemType::Potion)>>) {
  // ...
}

fn main() {
  App::new()
    // ...
    .add_enum_filter::<ItemType>()
    .add_systems(Update, apply_potion)
    .run()
}

📲 安装

将以下内容添加到您的[dependencies]部分Cargo.toml

bevy_enum_filter = "0.3.0"

🤨 工作原理

惊喜!它只是标记结构体!

通过派生EnumFilter生成一个模块,每个变体都有一个标记结构体。模块名称使用枚举的名称(蛇形命名)后跟_filters。例如,我们的ItemType枚举生成以下模块

// Auto-generated!
mod item_type_filters {
  #[derive(bevy::prelude::Component)]
  pub struct Equippable;
  #[derive(bevy::prelude::Component)]
  pub struct Weapon;
  #[derive(bevy::prelude::Component)]
  pub struct Potion;
}

然后我们使用app.add_enum_filter注册我们的枚举时,我们添加了一个系统来监视与该枚举组件相关的更改(添加/更改)。然后系统将在有更改时添加或删除适当的标记结构体。

Enum!宏然后将给定的枚举路径获取相应的标记结构体。因此,Enum!(ItemType::Potion)对应于item_type_filters::Potion类型。

📢:这就是为什么您必须使生成的模块在作用域内!

注意事项

因为这基本上是在底层进行更改检测,因此记住过滤何时生效很重要。默认情况下,由app.add_enum_filter添加的系统在PostUpdate阶段运行。这意味着您将在该阶段完成之前看不到过滤效果。

请记住,在Update中更改的任何组件,由于我们需要跨阶段边界刷新命令,因此在PostUpdate之前都不会看到它们的过滤器工作。这意味着我们实际上只会失去一个阶段。

如果您需要在某个系统之后或某个阶段内运行它,您始终可以自己添加watch_for_enum系统。

🕊 Bevy 兼容性

bevy bevy_enum_filter
0.8.1 0.1.0
0.11.x 0.2.0
0.12.x 0.3.0

依赖项

~13MB
~220K SLoC