插件

Bevy 的核心原则之一是模块化。所有 Bevy 引擎功能都以插件的形式实现——修改 App 的代码集合。这包括渲染器之类的内部功能,但游戏本身也是作为插件实现的!这使开发人员能够选择他们想要的特性。不需要 UI?不要注册 UiPlugin。想构建一个无头服务器?不要注册 RenderPlugin.

这也意味着您可以自由地替换任何您不喜欢的组件。如果您需要,您可以构建自己的 UiPlugin,但如果您认为它有用,请考虑 将其贡献回 Bevy

那些没有贡献回 Bevy,而是单独发布的,是第三方插件。这些是由其他开发人员创建的有用且易于使用的补充,可以帮助您避免重复造轮子。要使用它们,您所要做的就是

  1. 找到一个第三方 Bevy 插件(例如 资源页面 上的那些)。
  2. 在您的 Cargo.toml 中将其添加为 [dependencies] 下的 crate。
  3. 导入代码定义(如 use third_party::prelude::*;)来自 crate 以将项目添加到您的工作区。
  4. 将插件添加到您的应用程序中(如 app.add_plugins(third_party_plugin))。

但是,大多数开发人员不需要自定义体验,他们只是想要“完整引擎”体验,无需任何麻烦。为此,Bevy 提供了一组 DefaultPlugins.

Bevy 的默认插件 #

让我们通过添加 Bevy 的 DefaultPlugins 来使我们的应用程序更有趣,这些插件是包含核心引擎功能的 PluginGroup。(对于那些需要最少功能的人,MinimalPlugins 存在)。add_plugins(DefaultPlugins) 添加了大多数人期望引擎拥有的功能,例如 2D/3D 渲染器、资产加载、UI 系统、窗口和输入。

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, add_people)
        .add_systems(Update, (hello_world, (update_people, greet_people).chain()))
        .run();
}

再次运行 cargo run

您应该注意到两件事

  • 应该弹出一个窗口。这是因为我们现在有了 WindowPlugin,它定义了窗口界面(但实际上不知道如何创建窗口),以及 [WinitPlugin],它使用 winit 库 使用您操作系统的本机窗口 API 创建窗口。
  • 您的控制台现在充满了“hello”消息:这是因为 DefaultPlugins 将“事件循环”添加到我们的应用程序中。我们的应用程序的 ECS 调度现在每“帧”运行一次循环。我们将在稍后解决控制台垃圾邮件问题。

创建您的第一个插件 #

为了更好地组织,让我们将所有“hello”逻辑移动到一个插件中。要创建插件,我们只需要实现 Plugin 接口。将以下代码添加到您的 main.rs 文件中

pub struct HelloPlugin;

impl Plugin for HelloPlugin {
    fn build(&self, app: &mut App) {
        // add things to your app here
    }
}

然后像这样在您的应用程序中注册插件

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_plugins(HelloPlugin)
        .add_systems(Startup, add_people)
        .add_systems(Update, (hello_world, (update_people, greet_people).chain()))
        .run();
}

请注意,add_plugins 可以通过传递一个元组来添加任意数量的插件(或插件组,例如 DefaultPlugins)。现在剩下的就是将我们的系统移到 HelloPlugin 中,这只是一个剪切和粘贴的问题。我们插件的 build() 函数中的 app 变量与我们在 main() 函数中使用的构建器类型相同

impl Plugin for HelloPlugin {
    fn build(&self, app: &mut App) {
        app.add_systems(Startup, add_people);
        app.add_systems(Update, (hello_world, (update_people, greet_people).chain()));
    }
}

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_plugins(HelloPlugin)
        .run();
}

尝试再次运行应用程序。它应该与之前完全一样。在下一节中,我们将使用资源修复“hello”垃圾邮件。