#traits #query #bevy #plugin #gamedev #game-engine

bevy-trait-query-0-14-0

bevy游戏引擎的特质查询实现

4个版本

0.6.2 2024年8月11日
0.6.1 2024年8月11日
0.6.0 2024年8月11日
0.5.1 2024年8月11日

#147游戏开发

Download history 108/week @ 2024-08-05 110/week @ 2024-08-12

218 每月下载次数
bevy_dogoap 中使用

MIT/Apache

100KB
2K SLoC

bevy-trait-query

bevy游戏引擎特质查询的实现。

在使用此crate之前,您应该熟悉bevy: https://bevy.rust-lang.net.cn/

Bevy版本 crate版本
0.13 0.5
0.12 0.4
0.11 0.3
0.10 0.2
0.9 0.1
0.8 0.0.3
预览 主分支

关于可靠性的说明

尽管此crate已在世界上使用过并且尚未出现问题,但它仍然相当新颖且实验性。请谨慎使用(并且使用miri!)。

如果您发现错误,请 打开问题

概述

假设您有一个想要为某些组件实现的特质。

/// Components that display a message when hovered.
pub trait Tooltip {
    /// Text displayed when hovering over an entity with this trait.
    fn tooltip(&self) -> &str;
}

为了在bevy中实用,您将想要查询此特质。


// Just add this attribute...
#[bevy_trait_query::queryable]
pub trait Tooltip {
    fn tooltip(&self) -> &str;
}

// ...and now you can use your trait in queries.
fn show_tooltips_system(
    tooltips: Query<&dyn Tooltip>,
    // ...
) {
    // ...
}

由于Rust不幸缺乏任何类型的反射,当应用程序构建时必须注册每个组件与特质的关联。

#[derive(Component)]
struct Player(String);

#[derive(Component)]
enum Villager {
    Farmer,
    // ...
}

#[derive(Component)]
struct Monster;

/* ...trait implementations omitted for brevity... */

struct TooltipPlugin;

impl Plugin for TooltipPlugin {
    fn build(&self, app: &mut App) {
        // We must import this trait in order to register our components.
        // If we don't register them, they will be invisible to the game engine.
        use bevy_trait_query::RegisterExt;

        app
            .register_component_as::<dyn Tooltip, Player>()
            .register_component_as::<dyn Tooltip, Villager>()
            .register_component_as::<dyn Tooltip, Monster>()
            .add_systems(Update, show_tooltips);
    }
}

与具体类型的查询不同,实体可以具有多个与特质查询匹配的组件。


fn show_tooltips(
    tooltips: Query<&dyn Tooltip>,
    // ...
) {
    // Iterate over each entity that has tooltips.
    for entity_tooltips in &tooltips {
        // Iterate over each component implementing `Tooltip` for the current entity.
        for tooltip in entity_tooltips {
            println!("Tooltip: {}", tooltip.tooltip());
        }
    }

    // If you instead just want to iterate over all tooltips, you can do:
    for tooltip in tooltips.iter().flatten() {
        println!("Tooltip: {}", tooltip.tooltip());
    }
}

或者,如果您预期每个实体都只实现该特质的组件,您可以使用One过滤器。这比遍历所有特质实现具有显著的性能优势。

use bevy_trait_query::One;

fn show_tooltips(
    tooltips: Query<One<&dyn Tooltip>>,
    // ...
) {
    for tooltip in &tooltips {
        println!("Tooltip: {}", tooltip.tooltip());
    }
}

性能

特质查询的性能相当具有竞争力。以下是简单情况的一些基准测试

具体类型 One All
1个匹配 16.135 µs 31.441 µs 63.273 µs
2个匹配 17.501 µs - 102.83 µs
1-2个匹配 - 16.959 µs 82.179 µs

许可证

MITAPACHE-2.0

依赖关系

~11MB
~195K SLoC