bevy the book 20140118翻译(全)

发布时间:2024年01月18日

源自:Bevy Book: Introduction

主要用 有道 翻译。


Introduction 介绍

If you came here because you wanted to learn how to make 2D / 3D games, visualizations, user interfaces, or other graphical applications with Bevy ... you came to the right place! If not, stick around anyway. I promise it will be fun.

如果你来这里是因为你想学习如何用Bevy制作2D / 3D游戏、可视化、用户界面或其他图形应用程序……你来对地方了!如果没有,那还是留下来吧。我保证会很有趣。

what's a bevy?

A bevy is a group of birds!? ? ?bevy就是一群鸟!

But Bevy is also a refreshingly simple data-driven game engine built in Rust. It is?free and open-source?forever.

但Bevy也是一个用Rust构建的简单数据驱动游戏引擎。它永远是免费和开源的。

Bevy has the following design goals:

Bevy的设计目标如下:

  • Capable: Offer a complete 2D and 3D feature set? ? ? ?功能:提供完整的2D和3D功能集
  • Simple: Easy for newbies to pick up, but infinitely flexible for power users? ? ? ?简单:对新手来说很容易上手,但对高级用户来说却无限灵活
  • Data Focused: Data-oriented architecture using the Entity Component System paradigm? ? ? ? ?以数据为中心:使用实体组件系统范例的面向数据的体系结构
  • Modular: Use only what you need. Replace what you don't like? ? ? ? ? ?模块化:只使用你需要的。替换你不喜欢的东西
  • Fast: App logic should run quickly, and when possible, in parallel? ? ? ? ?快速:应用程序逻辑应该快速运行,如果可能的话,并行运行
  • Productive: Changes should compile quickly ... waiting isn't fun? ? ? ? ? 高效:更改应该编译得很快……等待并不有趣

Bevy is?built in the open by volunteers?using the?Rust programming language. The code is free and open-source because we believe developers should fully own their tools. Games are a huge part of our culture and humanity is investing?millions?of hours into the development of games. Why are we continuing to build up the ecosystems of closed-source monopolies that take cuts of our sales and deny us visibility into the tech we use daily? We believe that the developer community can do so much better.

Bevy是由志愿者使用Rust编程语言公开构建的。代码是免费和开源的,因为我们相信开发人员应该完全拥有他们的工具。游戏是我们文化的重要组成部分,人类在游戏开发中投入了大量时间。为什么我们要继续建立封闭源垄断的生态系统,这些生态系统会削减我们的销售额,并让我们无法了解日常使用的技术?我们相信开发者社区可以做得更好。

For a more in-depth introduction, check out the?Introducing Bevy?blog post.

要了解更深入的介绍,请查看介绍Bevy博客文章。

Stability Warning 稳定的警告

Bevy is still in the early stages of development. Important features are missing. Documentation is sparse. A new version of Bevy containing breaking changes to the API is released?approximately once every 3 months. We provide?migration guides, but we can't guarantee migrations will always be easy. Use only if you are willing to work in this environment.

Bevy仍处于开发的早期阶段。缺少重要的功能。文档很少。Bevy的新版本包含对API的重大更改,大约每3个月发布一次。我们提供了迁移指南,但我们不能保证迁移总是很容易。只有当你愿意在这种环境中工作时才使用。

If you are currently trying to pick an engine for your Next Big Project?, we recommend that you check out?Godot Engine. It is currently much more feature-complete and stable. And it is also free, open-source, and?scriptable with Rust!

如果您目前正在尝试为您的Next Big Project?选择一个引擎,我们建议您选择Godot engine。它目前的功能更加完整和稳定。它也是免费的、开源的,并且可以用Rust编写脚本!

This official book is still very incomplete. It will help you get started with the setup and learning the basics, but it does not yet cover most of Bevy's features. See the?Next Steps?page for links to other, more exhaustive, learning resources you can use.

这本正式的书还很不完整。它将帮助您开始设置和学习基础知识,但它还没有涵盖Bevy的大部分功能。请参阅Next Steps页面,以获得可以使用的其他更详尽的学习资源的链接。

Phew! If you haven't been scared away yet, let's move on to learning some Bevy!

唷!如果你还没有被吓走,让我们继续学习一些贝弗!

NEXT 下一个

Getting Started 开始


Getting Started 开始

This section will help you get started on your Bevy journey as quickly as possible. It will walk you through setting up your development environment and writing a simple Bevy app.

本节将帮助您尽快开始您的Bevy之旅。它将引导您设置开发环境并编写一个简单的Bevy应用程序。

Quick Start 快速启动

If you want to dive in immediately and you already have a working Rust setup, feel free to follow this "quick start" guide. Otherwise, move on to the next page.

如果你想立即开始,并且你已经有了一个可以工作的Rust设置,请随意遵循这个“快速开始”指南。否则,转到下一页。

Note: the "fast compiles" setup is on the next page, so you might want to read that section first.

注意:“快速编译”设置在下一页,因此您可能需要先阅读该部分。

Try the Examples? ? ?试试这些例子

  1. Clone the?Bevy repo:? ? ?克隆Bevy代码库:

    gitclone https://github.com/bevyengine/bevy 
    
  2. Navigate to the new "bevy" folder? ? ?导航到新的“bevy”文件夹

    cd bevy
    
  3. Switch to the correct Bevy version (as the default is the git main development branch) 切换到正确的Bevy版本(默认是git主开发分支)

    #use the latest Bevy release   # 使用最新的Bevy版本
    git checkout latest   # 签出最新
    #or a specific version   # 或者一个特定的版本
    git checkout v0.12.1   # 当前最新版本
    
  4. Try the examples in the?examples folder? ? ? 尝试示例文件夹中的示例

    cargo run --example breakout
    

Add Bevy as a Dependency? ? ?将Bevy添加为依赖项

Bevy is?available as a library on crates.io.

Bevy是一个库,可以在crate .io上找到。

The easiest way to add it to your project is to use?cargo add:

将其添加到项目中最简单的方法是使用cargo add:

cargo add bevy

Alternatively, you can manually add it to your project's Cargo.toml like this:

或者,您可以手动将其添加到项目的Cargo.toml 中,象这样:

# 依赖关系
[dependencies]
bevy = "0.12"   # make sure this is the latest version # 确保这是最新版本

Make sure to use the latest?bevy ?crate version

确保使用最新版本?bevy crate ( Crate版本 0.12.1)

NEXT 下一个

Setup 设置


Setup 设置

I know you are itching to start making games, but we need to do a?small?amount of setup first.

我知道你渴望开始制作游戏,但我们需要先做一些准备工作。

Rust Setup? ? ?rust的设置

All Bevy app and engine code is written in Rust. This means that before we begin, we need to set up our Rust development environment.

所有Bevy应用程序和引擎代码都是用Rust编写的。这意味着在开始之前,我们需要设置Rust开发环境。

Installing Rust? ? ?安装rust

Bevy relies heavily on improvements in the Rust language and compiler. As a result, the Minimum Supported Rust Version (MSRV) is "the latest stable release" of Rust.

Bevy在很大程度上依赖于Rust语言和编译器的改进。因此,最小支持Rust版本(MSRV)是Rust的“最新稳定版本”。

Install Rust by following the?Rust Getting Started Guide.

按照Rust入门指南安装Rust。

Once this is done, you should have the?rustc?compiler and the?cargo?build system installed in your path.

完成此操作后,您应该在路径中安装了rustc编译器和cargo构建系统。

Install OS dependencies? ? ?安装操作系统依赖项

Linux?

Follow the instructions at?Linux Dependencies?

按照Linux Dependencies中的说明进行操作

Windows?
  • Run the?Visual Studio 2019 build tools installer? ? ?运行Visual Studio 2019构建工具安装程序
  • For easy setup, select the?Desktop development with C++?workload in the installer.? ? ? ? 为了便于安装,请在安装程序中选择使用C++工作负载的桌面开发。
  • For a minimal setup, follow these steps:? ? ?要进行最小设置,请遵循以下步骤:
    1. In the installer, navigate to? Individual components.? ??在安装程序中,导航到Individual components 单个组件
    2. Select the latest MSVC?for your architecture and version of Windows? ? 选择最新的 适用于您的体系结构和Windows版本的MSVC
    3. Select the latest 选择最新的Windows SDK?for your version of Windows 用于您的Windows版本
    4. Select the latest?Windows SDK?for your version of Windows? ? ?选择用于Windows组件的C++CMake工具
    5. Install the components? ? ?安装组件
MacOS?

Install the Xcode command line tools with?xcode-select --install?or the?Xcode app

使用Xcode select--Install或Xcode应用程序安装Xcode命令行工具

Code Editor / IDE? ? ? ? ? 代码编辑器/ IDE

You can use any code editor you want, but we highly recommend one that has a?rust-analyzer?plugin. It's still in development, but it already provides top-tier autocomplete and code intelligence.?Visual Studio Code?has an officially supported?rust-analyzer extension.

您可以使用任何您想要的代码编辑器,但我们强烈建议使用带有rust-analyzer rust分析器插件的代码编辑器。它仍在开发中,但它已经提供了顶级的自动补全和代码智能。Visual Studio Code有一个官方支持的rust分析器扩展。

Rust Learning Resources? ? ?Rust学习资源

The goal of this book is to learn Bevy, so it won't serve as a full Rust education. If you would like to learn more about the Rust language, check out the following resources:

这本书的目标是学习Bevy,所以它不会作为一个完整的Rust教育。如果您想了解更多关于Rust语言的信息,请查看以下资源:

  • The Rust Book: the best place to learn Rust from scratch? ? ? ? ? Rust Book:从头开始学习Rust的最佳场所
  • Rust by Example: learn Rust by working through live coding examples? ? ? ? ? ? ? ? ? ?通过示例学习Rust:通过现场编码示例学习Rust

Create a new Bevy Project? ? ? ? 创建一个新的Bevy项目

Now we are ready to set up a Bevy project! Bevy is just a normal Rust dependency. You can either add it to an existing Rust project or create a new one. For completeness we will assume you are starting from scratch.

现在我们已经准备好创建一个Bevy项目了!Bevy只是一个普通的Rust依赖项。您可以将它添加到现有的Rust项目中,也可以创建一个新项目。为了完整起见,我们将假设您从头开始。

Create a new Rust executable project? ? ? ? ? 创建一个新的Rust可执行项目

First, navigate to a folder where you want to create your new project. Then, run the following command to create a new folder containing our rust executable project:

首先,导航到要在其中创建新项目的文件夹。然后,运行以下命令创建一个包含rust可执行项目的新文件夹:

cargo new my_bevy_game
cd my_bevy_game

Now run?cargo run?to build and run your project. You should see?Hello, world!?printed to your terminal. Open the?my_bevy_game?folder in your code editor of choice and take some time to look through the files.

现在运行cargo run来构建和运行项目。你应该看看Hello, world!打印到您的终端。在您选择的代码编辑器中打开my_bevy_game文件夹,并花一些时间查看这些文件。

main.rs?is the entry point of your program:? ? ? ? ? ?main.rs?是程序的入口点:

fn main() {
    println!("Hello, world!");
}

Cargo.toml?is your "project file". It contains metadata about your project such as its name, dependencies, and build configuration.

Cargo.toml?是你的“project file 项目文件”。它包含有关项目的元数据,例如项目的名称、依赖项和构建配置。

[package]
name = "my_bevy_game"
version = "0.1.0"
edition = "2021"

[dependencies]

Add Bevy as a dependency? ? ? 添加Bevy作为依赖项

Bevy is?available as a library on crates.io, the official Rust package repository.

Bevy可以作为crates.io板条箱上的库使用。官方的Rust包存储库。

The easiest way to add it to your project is to use?cargo add:

将其添加到项目中最简单的方法是使用cargo add:

cargo add bevy

Alternatively, you can manually add it to your project's Cargo.toml like this:

或者,您可以手动将其添加到项目的 Cargo.toml中,象这样:

[package]
name = "my_bevy_game"
version = "0.1.0"
edition = "2021" # this needs to be 2021, or you need to set "resolver=2"
                 # 这需要是2021,否则您需要设置“resolver=2”

[dependencies]
bevy = "0.12" # make sure this is the latest version # 确保这是最新版本

Make sure to use the latest??bevy ?crate version ( Crate版本0.12.1)

确保使用最新的?bevy?板条箱版本(0.12.1)

Cargo Workspaces? ? ? ?Cargo工作区

If you are using?Cargo Workspaces, you will also need to add the resolver to your Cargo.toml file in the root directory:

如果您正在使用Cargo工作区,您还需要将解析器添加到根目录下的 Cargo.toml文件:

[workspace]
resolver = "2" # Important! wgpu/Bevy needs this!
               # 重要!wgpu/Bevy需要这个!

Compile with Performance Optimizations? ? ? ? ? 使用性能优化进行编译

While it may not be an issue for simple projects, debug builds in Rust can be?very slow?- especially when you start using Bevy to make real games.

虽然对于简单的项目来说这可能不是问题,但在Rust中调试构建可能非常缓慢——尤其是当你开始使用Bevy制作真正的游戏时。

It's not uncommon for debug builds using the default configuration to take multiple minutes to load large 3D models, or for the framerate for simple scenes to drop to near-unplayable levels.

使用默认配置的调试构建需要花费数分钟来加载大型3D模型,或者简单场景的帧率下降到几乎无法播放的水平,这并不罕见。

Fortunately, there is a simple fix, and we don't have to give up our fast iterative compiles! Add the following to your?Cargo.toml:

幸运的是,有一个简单的修复方法,我们不必放弃快速迭代编译器!将以下内容添加到您的Cargo.toml中:

# Enable a small amount of optimization in debug mode
# 在调试模式下启用少量优化
[profile.dev]
opt-level = 1

# Enable high optimizations for dependencies (incl. Bevy), but not for our code:
# 为依赖项(包括Bevy)启用高度优化,但不为我们的代码启用:
[profile.dev.package."*"]
opt-level = 3

You might think to simply develop in release mode instead, but we recommend against this as it can worsen the development experience by slowing down recompiles and disabling helpful debug symbols and assertions.

您可能会认为只需在发布模式下进行开发,但我们不建议这样做,因为它会减慢重新编译的速度,并禁用有用的调试符号和断言,从而恶化开发体验。

Enable Fast Compiles (Optional)? ? ? ?启用快速编译(可选)

Bevy can be built just fine using default configuration on stable Rust. However for maximally fast iterative compiles, we recommend the following configuration:

在稳定的Rust上使用默认配置可以很好地构建Bevy。然而,为了最大限度地快速迭代编译,我们建议使用以下配置:

  • Enable Bevy's Dynamic Linking Feature: This is the most impactful compilation time decrease! If?bevy?is a dependency, you can compile the binary with the "dynamic_linking" feature flag (enables dynamic linking).?Important!?On Windows you?must?also enable the?perfomance optimizations?or you will get a?too many exported symbols?error.? ? ? ? ? ? ? ? ? ? ? ?启用Bevy的动态链接功能:这是最有效的编译时间减少的方法!如果bevy是一个依赖项,你可以编译带有"dynamic_linking"特性标志的二进制文件(启用动态链接)。重要!在Windows上,你还必须启用性能优化,否则你会得到太多的导出符号的错误。

    cargo run --features bevy/dynamic_linking

    If you don't want to add the?--features bevy/dynamic_linking?to each run, this flag can permanently be set via?Cargo.toml:? ? ? ? ?如果你不想在每次运行时都添加--features bevy/dynamic_linking,这个标志可以通过Cargo.toml永久设置:

    [dependencies]
    bevy = { version = "0.12.0", features = ["dynamic_linking"] }

    NOTE: Remember to revert this before releasing your game! Otherwise you will need to include?libbevy_dylib?alongside your game if you want it to run. If you remove the "dynamic" feature, your game executable can run standalone.? ? ? ? ? ? 注意:在发布游戏之前,请务必恢复此设置!否则,如果你想让游戏运行,你就需要在游戏中包含libbevy_dylib。如果你移除“动态”功能,你的游戏可执行文件就可以独立运行了。

  • LLD linker: The Rust compiler spends a lot of time in the "link" step. LLD is?much faster?at linking than the default Rust linker. To install LLD, find your OS below and run the given command:? ? ? ? ? ? ? ? ? LLD链接器:Rust编译器在“链接”步骤上花费了大量时间。LLD的链接速度比默认的Rust链接器快得多。要安装LLD,请找到下面的操作系统并运行给定的命令:

    • Ubuntu:?sudo apt-get install lld

    • Fedora:?sudo dnf install lld?

    • Arch:?sudo pacman -S lld?

    • Windows: Ensure you have the latest?cargo-binutils?as this lets commands like?cargo run?use the LLD linker automatically.? ? ? ? ?Windows:确保您有最新的cargo-binutils,因为这允许像cargo run这样的命令自动使用LLD链接器。

      cargo install -f cargo-binutils
      rustup component add llvm-tools-preview
      
    • MacOS: You can follow these?instructions?to install lld manually or install llvm through brew which includes lld:?brew install llvm? ? ? ? ?MacOS:您可以按照以下说明手动安装lld或通过brew安装llvm,其中包括lld: brew install llvm

  • Alternative - mold linker: mold is?up to 5× (five times!) faster?than LLD, but with a few caveats like limited platform support and occasional stability issues. To install mold, find your OS below and run the given command:? ? ? ? ? ? ? ? 可选的模具连接器:模具比LLD快5倍(5倍!),但有一些注意事项,如有限的平台支持和偶尔的稳定性问题。要安装模具,找到下面的操作系统并运行给定的命令:

    • Ubuntu:?sudo apt-get install mold clang

    • Fedora:?sudo dnf install mold clang

    • Arch:?sudo pacman -S mold clang?

    • Windows: currently not planned for support?See this tracking issue?for more information.? ? ? ? ? ? Windows:目前未计划支持,请参阅此跟踪问题以获取更多信息。

    • MacOS: is available commercially with?sold?MacOS:? ? ? ?已在市面上出售

      You will also need to add the following to your Cargo config at?YOUR_WORKSPACE/.cargo/config.toml:? ? ? ? ? ? ?您还需要在YOUR_WORKSPACE/.cargo/config.toml的Cargo配置中添加以下内容:

      [target.x86_64-unknown-linux-gnu]
      linker = "clang"
      rustflags = ["-C", "link-arg=-fuse-ld=/usr/bin/mold"]
      

      NOTE: Disabling?bevy/dynamic?may improve the performance of this linker.? ? ? ? ? ? 注意:禁用bevy/dynamic可以提高此链接器的性能。

  • Nightly Rust Compiler: This gives access to the latest performance improvements and "unstable" optimizations? ? ? ? ? 夜间版Rust编译器:这提供了访问最新的性能改进和“不稳定”优化

    Create a?rust-toolchain.toml?file in the root of your project, next to?Cargo.toml.? ? ? ? ? ? ? ? ?在项目的根目录中,在Cargo.toml旁边创建一个rust-tolchain.toml文件。

    [toolchain]
    channel = "nightly"

    For more information, see?The rustup book: Overrides.? ? ? ? ? ? ? 有关更多信息,请参阅rust手册:Overrides。

  • Generic Sharing: Allows crates to share monomorphized generic code instead of duplicating it. In some cases this allows us to "precompile" generic code so it doesn't affect iterative compiles. This is only available on nightly Rust.? ? ? ? ? ? ?泛型共享:允许crate共享单态泛型代码,而不是复制它。在某些情况下,这允许我们“预编译”泛型代码,这样它就不会影响迭代编译。这只适用于夜间版Rust

To enable fast compiles, install the nightly rust compiler and LLD. Then copy the contents of?this file?to?YOUR_WORKSPACE/.cargo/config.toml. For the project in this guide, that would be?my_bevy_game/.cargo/config.toml.

要启用快速编译,请安装夜间版rust编译器和LLD。然后将该文件(上边的链接)的内容复制到YOUR_WORKSPACE/.cargo/config.toml。对于本指南中的项目,它将是my_bevy_game/.cargo/config.toml。

If something went wrong, check out our?troubleshooting section?or?ask for help on our Discord.

如果出现问题,请查看我们的故障排除部分或在我们的Discord上寻求帮助。

Build Bevy 编译Bevy

Now run?cargo run?again. The Bevy dependencies should start building. This will take some time as you are essentially building an engine from scratch. You will only need to do a full rebuild once. Every build after this one will be fast!

现在再运行cargo run。Bevy依赖项应该开始构建。这需要一些时间,因为你基本上是从零开始构建一个引擎。您只需要进行一次完整的重建。这之后的每一个构建都会很快!

Now that we have our Bevy project set up, we're ready to start making our first Bevy app!

现在我们已经设置了Bevy项目,我们准备开始制作我们的第一个Bevy应用程序!

NEXT 下一个

Apps 应用程序


Apps 应用程序

Bevy programs are referred to as?Apps. The simplest Bevy app looks like this:

Bevy程序被称为应用程序。最简单的Bevy应用程序是这样的:

use bevy::prelude::*;

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

Nice and simple right? Copy the code above into your?main.rs?file, then run:

很简单,对吧?将上面的代码复制到main.rs文件代码中,然后运行:

cargo run

in your project folder. You will notice that ... nothing happens. This is because we haven't told our app to do anything yet! Apps are just empty shells capable of running our application logic. Let's add some logic to our App using Bevy ECS.

在您的项目文件夹中。你会注意到……什么也不会发生。这是因为我们还没有告诉我们的应用做任何事情!应用程序只是能够运行我们的应用程序逻辑的空壳。让我们使用Bevy ECS向应用程序添加一些逻辑。

NEXT 下一个

ECS


ECS

All app logic in Bevy uses the Entity Component System paradigm, which is often shortened to ECS. ECS is a software pattern that involves breaking your program up into?Entities,?Components, and?Systems.?Entities?are unique "things" that are assigned groups of?Components, which are then processed using?Systems.

Bevy中的所有应用逻辑都使用实体组件系统范式,通常简称为ECS。ECS是一种软件模式,它将程序分解为实体、组件和系统实体是分配给组件组的唯一“事物”,然后使用系统处理组件组

For example, one entity might have a?Position?and?Velocity?component, whereas another entity might have a?Position?and?UI?component. Systems are logic that runs on a specific set of component types. You might have a?movement?system that runs on all entities with a?Position?and?Velocity?component.

例如,一个实体可能有位置和速度组件,而另一个实体可能有位置和UI组件。系统是运行在一组特定组件类型上的逻辑。你可能有一个运行在所有带有位置和速度组件的实体上的移动系统。

The ECS pattern encourages clean, decoupled designs by forcing you to break up your app data and logic into its core components. It also helps make your code faster by optimizing memory access patterns and making parallelism easier.

ECS模式通过强迫你将应用数据和逻辑分解到核心组件中,从而鼓励干净、解耦的设计。它还通过优化内存访问模式简化并行性来帮助您的代码更快。

Bevy ECS? ? ? ? bevy ECS

Bevy ECS is Bevy's implementation of the ECS pattern. Unlike other Rust ECS implementations, which often require complex lifetimes, traits, builder patterns, or macros, Bevy ECS uses normal Rust datatypes for all of these concepts:

Bevy ECS是Bevy对ECS模式的实现。与其他Rust ECS实现不同,这些实现通常需要复杂的生命周期、特征、构建器模式或宏,Bevy ECS使用普通的Rust数据类型来实现所有这些概念:

  • Components: Rust structs that implement the?Component?trait? ? ? ? ? ? ? 组件:实现Component特性的Rust结构

    #[derive(Component)]
    struct Position { x: f32, y: f32 }
    
  • Systems: normal Rust functions? ? ? ? ? 系统:普通的Rust函数

    fn print_position_system(query: Query<&Position>) {
        for position in &query {
            println!("position: {} {}", position.x, position.y);
        }
    }
  • Entities: a simple type containing a unique integer? ? ? 实体:包含唯一整数的简单类型

    struct Entity(u64);
    

Now let's see how this works in practice!

现在让我们看看它在实践中是如何工作的!

Your First System? ? ? ?你的第一个系统

Paste the following function into your?main.rs?file:

将以下函数粘贴到main.rs文件中:

fn hello_world() {
    println!("hello world!");
}

This will be our first system. The only remaining step is to add it to our?App!

这是我们的第一个系统。唯一剩下的步骤是将其添加到我们的应用程序!

use bevy::prelude::*;

fn main() {
    App::new()
        .add_systems(Update, hello_world)
        .run();
}

The?add_systems()?function adds the system to your App's?Update?Schedule, but we'll cover that more later.

add_systems()函数将系统添加到应用程序的Update Schedule中,但我们稍后会详细介绍。

Now run your app again using?cargo run. You should see?hello world!?printed once in your terminal.

现在使用cargo run再次运行应用程序。你应该看到hello world!在终端中打印一次。

Your First Components? ? ?你的第一个组件

Greeting the whole world is great, but what if we want to greet specific people? In ECS, you would generally model people as entities with a set of components that define them. Let's start simple with a?Person?component.

和全世界的人打招呼很好,但如果我们想和特定的人打招呼呢?在ECS中,您通常会将人建模为具有一组定义他们的组件的实体。让我们从简单的Person组件开始。

Add this struct to your?main.rs?file:

将这个结构体添加到main.rs文件:

#[derive(Component)]
struct Person;

But what if we want our people to have a name? In a more traditional design, we might just tack on a?name: String?field to?Person. But other entities might have names too! For example, dogs should probably also have a name. It often makes sense to break datatypes up in to small pieces to encourage code reuse. So let's make?Name?its own component:

但如果我们想让我们的人有个名字呢?在更传统的设计中,我们可能只是给Person添加一个name: String字段。但其他实体也可能有名字!例如,狗可能也应该有一个名字。将数据类型分解成小块鼓励代码重用通常是有意义的。让我们让Name成为它自己的组件:

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

We can then add people to our?World?using a "startup system". Startup systems are just like normal systems, but they run exactly once, before all other systems, right when our app starts. Let's use?Commands?to spawn some entities into our?World:

然后我们可以使用“启动系统”向我们的World添加人员。启动系统就像普通系统一样,但它们只运行一次,在所有其他系统之前,就在我们的应用程序启动时。让我们使用命令来生成(spawn)一些实体到我们的世界:

fn add_people(mut commands: Commands) {
    commands.spawn((Person, Name("Elaina Proctor".to_string())));
    commands.spawn((Person, Name("Renzo Hume".to_string())));
    commands.spawn((Person, Name("Zayna Nieves".to_string())));
}

Now register the startup system like this:

现在像这样注册启动系统:

fn main() {
    App::new()
        .add_systems(Startup, add_people)
        .add_systems(Update, hello_world)
        .run();
}

Your First Query? ? ? ? ?你的第一个查询

We could run this now and the?add_people?system would run first, followed by?hello_world. But our new people don't have anything to do yet! Let's make a system that properly greets the new citizens of our?World:

我们现在可以运行这个,add_people系统将首先运行,然后是hello_world。但是我们的新员工还没有任何事情可做!让我们建立一个系统,恰当地迎接我们世界的新公民:

fn greet_people(query: Query<&Name, With<Person>>) {
    for name in &query {
        println!("hello {}!", name.0);
    }
}

The parameters we pass into a "system function" define what data the system runs on. In this case,?greet_people?will run on all entities with the?Person?and?Name?component.

我们传递给“system function 系统函数”的参数定义了系统运行的数据。在本例中,greet_people将在具有Person和Name组件的所有实体上运行。

You can interpret the?Query?above as: "iterate over every?Name?component for entities that also have a?Person?component".

您可以将上面的查询解释为:“遍历每个Name组件,以查找也具有Person组件的实体”。

Now we just register the system in our?App. Note that you can pass more than one system into an?add_systems?call by using a tuple!

现在我们只需在App中注册系统。注意,你可以通过使用元组将多个系统传递给add_systems调用!

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

Running our app will result in the following output:

运行我们的应用程序将得到以下输出:

hello world!
hello Elaina Proctor!
hello Renzo Hume!
hello Zayna Nieves! 

Marvelous!

不可思议的!

Quick Note: "hello world!" might show up in a different order than it does above. This is because systems run in parallel by default whenever possible.

快速提示:“hello world!”可能以与上面不同的顺序出现。这是因为系统在默认情况下尽可能并行运行

Your First mutable Query? ? ?你的第一个可变查询

If we want to change the names of some people (perhaps they got married!), for example, we can do this using a mutable query:

例如,如果我们想改变一些人的名字(也许他们结婚了!),我们可以使用一个可变查询:

fn update_people(mut query: Query<&mut Name, With<Person>>) {
    for mut name in &mut query {
        if name.0 == "Elaina Proctor" {
            name.0 = "Elaina Hume".to_string();
            break; // We don’t need to change any other names
                   // 我们不需要更改任何其他名称
        }
    }
}

We need to make?query?mutable, and use a mutable reference (&mut) to the components we want to change.

我们需要使可变查询,并对我们想要更改的组件使用可变引用(&mut)。

Don’t forget to add the system to the?Update?schedule:

不要忘记将系统添加到更新计划中:

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

Note that we have used?.chain()?on the two systems. This is because we want them two to run in exactly the order they're listed in the code: with?update_people?occurring before?greet_people. If they weren’t, the name might change after we greet the people.

注意,我们在两个系统上使用了.chain()。这是因为我们希望它们两个按照代码中列出的顺序运行:update_people出现在greet_people之前。如果他们不喜欢,在我们和人们打招呼之后,名字可能会改变。

But we don’t add the?hello_world?system to the chain, because it doesn’t matter when it runs. This way, Bevy can run?hello_world?in parallel while the other systems are running.

但是我们没有将hello_world系统添加到链中,因为它何时运行并不重要。通过这种方式,Bevy可以在其他系统运行时并行运行hello_world。

NEXT 下一个

Plugins 插件


Plugins? ?插件

One of Bevy's core principles is modularity. All Bevy engine features are implemented as plugins. This includes internal features like the renderer, but games themselves are also implemented as plugins! This empowers developers to pick and choose which features they want. Don't need a UI? Don't register the?UiPlugin. Want to build a headless server? Don't register the?RenderPlugin.

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

This also means you are free to replace any components you don't like. If you feel the need, you are welcome to build your own?UiPlugin, but consider?contributing it back to Bevy?if you think it would be useful!

这也意味着您可以自由更换任何您不喜欢的组件。如果你觉得有必要,欢迎你构建自己的UiPlugin,而且如果你认为它有用的话,可以考虑把它贡献给Bevy !

However, most developers don't need a custom experience and just want the "full engine" experience with no hassle. For this, Bevy provides a set of "default plugins".

然而,大多数开发者并不需要实现自定义的体验,他们只想要“完整的引擎”体验。为此,Bevy提供了一组“默认插件”。

Bevy's Default Plugins? ? ? ?Bevy的默认插件

Let's make our app more interesting by adding the "default Bevy plugins".?add_plugins(DefaultPlugins)?adds the features most people expect from an engine, such as a 2D / 3D renderer, asset loading, a UI system, windows, and input.

让我们通过添加“默认Bevy插件”来使我们的应用程序更有趣。add_plugins(DefaultPlugins)添加了大多数人期望从引擎中获得的功能,如2D / 3D渲染器、资产加载、UI系统、窗口和输入。

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

Once again run?cargo run.? ? ?

再次运行cargo run

You should hopefully notice two things:

你应该注意到两件事:

  • A window should pop up. This is because we now have?WindowPlugin, which defines the window interface (but doesn't actually know how to make windows), and?WinitPlugin?which uses the?winit library?to create a window using your OS's native window API.? ? ? ? ? ? ? ? ? ? ? ? 应该弹出一个窗口。这是因为我们现在有了WindowPlugin,它定义了窗口接口(但实际上不知道如何创建窗口),以及WinitPlugin,它使用winit库使用操作系统的本机窗口API创建窗口。
  • Your console is now full of "hello" messages: This is because?DefaultPlugins?adds an "event loop" to our application. Our App's ECS Schedule now runs in a loop once per "frame". We will resolve the console spam in a moment.? ? ? ? ? ? ? ? ? ?你的控制台现在充满了“hello”消息:这是因为DefaultPlugins在我们的应用程序中添加了一个“事件循环”。我们的应用程序的ECS Schedule现在每“帧”循环运行一次。我们稍后将解决控制台垃圾邮件问题。

Creating your first plugin? ? ? 创建自己的第一个插件

For better organization, let's move all of our "hello" logic to a plugin. To create a plugin we just need to implement the?Plugin?interface. Add the following code to your?main.rs?file:

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

pub struct HelloPlugin;

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

Then register the plugin in your App like this:

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

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

Note?add_plugins?can add any number of plugins (or plugin groups like?DefaultPlugins) by passing in a tuple of them. Now all that's left is to move our systems into?HelloPlugin, which is just a matter of cut and paste. The?app?variable in our plugin's?build()?function is the same builder type we use in our?main()?function:

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

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

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

Try running the app again. It should do exactly what it did before. In the next section, we'll fix the "hello" spam using Resources.

尝试再次运行应用程序。它应该像以前那样做。在下一节中,我们将使用参考资料修复“hello”垃圾邮件。

NEXT 下一个

Resources 资源


Resources? ? ? ?资源

Entities?and?Components?are great for representing complex, query-able groups of data. But most Apps will also require "globally unique" data of some kind. In Bevy ECS, we represent globally unique data using?Resources.

实体和组件非常适合表示复杂的、可查询的数据组。但大多数应用程序也需要某种“全局唯一”的数据。在Bevy ECS中,我们使用资源表示全局唯一的数据

Here are some examples of data that could be encoded as?Resources:

以下是一些可以编码为资源的数据示例:

  • Elapsed Time? ? ? ? ?运行时间
  • Asset Collections (sounds, textures, meshes)? ? ? ? ? 资产集合(声音,纹理,网格)
  • Renderers? ? ? ? 渲染器

Tracking Time with Resources? ? ? ? 利用资源跟踪时间

Let's solve our App's "hello spam" problem by only printing "hello" once every two seconds. We'll do this by using the?Time?resource, which is automatically added to our App via?add_plugins(DefaultPlugins).

让我们通过每两秒钟打印一次“hello”来解决应用程序的“hello垃圾邮件”问题。我们将通过使用时间资源来做到这一点,它是通过add_plugins(DefaultPlugins)自动添加到我们的应用程序中的。

For simplicity, remove the?hello_world?system from your App. This way we only need to adapt the?greet_people?system.

为了简单起见,从应用程序中删除hello_world系统。这样我们只需要调整greet_people系统。

Resources are accessed in much the same way that we access components. You can access the?Time?resource in your system like this:

访问资源的方式与访问组件的方式大致相同。你可以像这样访问系统中的时间资源:

fn greet_people(time: Res<Time>, query: Query<&Name, With<Person>>) {
    for name in &query {
        println!("hello {}!", name.0);
    }
}

Res?and?ResMut?pointers provide read and write access (respectively) to resources.

Res和ResMut指针分别提供对资源的读和写访问。

The?delta?field on?Time?gives us the time that has passed since the last update. But in order to run our system once every two seconds, we must track the amount of time that has passed over a series of updates. To make this easier, Bevy provides the?Timer?type. Let's create a new Resource for our system to track elapsed time with a?Timer:

时间上的delta字段表示上次更新后经过的时间。但是为了每两秒钟运行一次系统,我们必须跟踪一系列更新所经过的时间。为了简化这一点,Bevy提供了Timer类型。让我们为我们的系统创建一个新的资源,用计时器来跟踪经过的时间:

#[derive(Resource)]
struct GreetTimer(Timer);

fn greet_people(
    time: Res<Time>, mut timer: ResMut<GreetTimer>, query: Query<&Name, With<Person>>) {
    // update our timer with the time elapsed since the last update
    // 使用上次更新后经过的时间更新计时器
    // if that caused the timer to finish, we say hello to everyone
    // 如果这导致计时器结束,我们向所有人问好
    if timer.0.tick(time.delta()).just_finished() {
        for name in &query {
            println!("hello {}!", name.0);
        }
    }
}

Now all that's left is adding a?GreetTimer?Resource to our?HelloPlugin. Use?TimerMode::Repeating?to make the timer repeat.

现在剩下的就是在HelloPlugin中添加一个GreetTimer资源。使用TimerMode:: repeat使计时器重复。

impl Plugin for HelloPlugin {
    fn build(&self, app: &mut App) {
        app.insert_resource(GreetTimer(Timer::from_seconds(2.0, TimerMode::Repeating)))
            .add_systems(Startup, add_people)
            .add_systems(Update, greet_people);
    }
}

Now?cargo run?the App. It should now greet people at a reasonable rate.

现在?cargo run运行应用程序。它现在应该以合理的速度欢迎人们。

NEXT 下一个

Next Steps 下一个步骤


Next Steps? ? ? 下一个步骤

You have reached the end of The Bevy Book! And unfortunately, we haven't even scratched the surface of Bevy's features! Eventually this book will cover almost every facet of Bevy, but until then we recommend checking out:

你已经读到《The Bevy Book》的结尾了!不幸的是,我们甚至还没有触及到Bevy功能的表面!最终,本书将涵盖Bevy的几乎所有方面,但在此之前,我们建议您查看:

  • The Bevy Examples? ? bevy的例子: We create an example for every major Bevy feature. This is currently the best way to learn Bevy's features and how to use them.? ? ? ? ? ? ? 我们为每一个主要的Bevy功能创建一个示例。这是目前学习Bevy的特性以及如何使用它们的最好方法。
    • The Bevy Web Examples: We also try to make most of these examples available directly in your browser.? ? ? ? ? ? ? ?Bevy Web示例:我们还尝试在您的浏览器中直接提供大多数示例。
  • Breakout: A small "breakout" clone that illustrates what a real Bevy game looks like.? ? ? ? ? ? ? ? ? ? ? ? ?Breakout:一个小型的“Breakout”克隆,展示了真正的Bevy游戏的样子。
  • Bevy API Docs: Documentation with examples for types, traits, methods and other items in Bevy's API.? ? ? ? ? ? ? Bevy API Docs:包含Bevy API中类型、特征、方法和其他项目示例的文档。
  • Bevy Assets 群资产: List of projects by the Bevy community, including:? ? ? ? ? ? ? ? ? Bevy社区的项目列表,包括:
    • Learning Resources: Tutorials, documentation, and examples.? ? ? ? ? ? ? ? ?学习资源:教程、文档和示例。
    • Plugins: Extra functionality you can use in your projects.? ? ? ? ? ? ? ? ? ? ?插件:你可以在项目中使用的额外功能。
    • Games: Open-source games in various stages of development.? ? ? ? ? ? ? ? 游戏:处于不同开发阶段的开源游戏。
  • Bevy Cheatbook: An in-depth, opinionated, unofficial guide to Bevy's API and ecosystem.? ? ? ? ? ? ? ?Bevy Cheatbook:一个关于Bevy API和生态系统的深入的、固执己见的非官方指南。

NEXT 下一个

Contributing 贡献


Contributing (join the bevy)? ? ? ?贡献(加入bevy队伍)

Bevy is built by volunteers. If you want to help us build the next great game engine,?please reach out! We need all the help we can get:

Bevy是由志愿者建立的。如果你想帮助我们构建下一个伟大的游戏引擎,请联系我们!我们需要所有能得到的帮助:

  • If you are a software developer and you want to help out, check out the?Contributing Code?section.? ? ? ? ? ? ? 如果您是一名软件开发人员,并且希望提供帮助,请查看贡献代码部分。
  • If you are good at teaching or writing, consider?contributing to our docs.? ? ? ? ? ? ? ?如果你擅长教学或写作,可以考虑为我们的文档做贡献。

We want Bevy to be a vibrant developer community ... that's actually why we chose the name! A Bevy is a group of birds, just like we are a group of game developers. Join the Bevy!? ? ? ? ? ? ? ? ? ? ? 我们希望Bevy成为一个充满活力的开发者社区……这就是我们选择这个名字的原因!Bevy是一群鸟,就像我们是一群游戏开发者一样。加入bevy!

NEXT 下一个

Code 代码


Contributing Code 贡献代码

Would you like to contribute code to Bevy? Here's how!

你愿意为Bevy贡献代码吗?这里就是!

How to Contribute? ? ?如何捐款

  1. Fork the?bevyengine/bevy?repository on GitHub, you'll need to create a GitHub account if you don't have one already.*? ? ? ? ? ? ? 在GitHub上分叉bevyengine/bevy存储库,如果你还没有,你需要创建一个GitHub帐户
  2. Make your changes in a local clone of your fork? ? ? ? ? ? ?在分支的本地克隆中进行更改
  3. For a higher chance of CI passing the first time, consider locally running? ? ?cargo run -p ci. ? ? ? ?为了提高初次CI通过的几率,请考虑在本地运行cargo run -p ci . You can run the commands manually: . 您可以手动执行以下命令:
    1. cargo fmt --all -- --check?(remove?--check?to let the command fix found problems? 删除--check?以使命令修复发现的问题)
    2. cargo clippy --workspace --all-targets --all-features -- -D warnings -A?clippy::type_complexity -A clippy::manual-strip?
    3. cargo test --all-targets --workspace
  4. Push your changes to your fork and open a?Pull Request? ? ? ?将您的更改推送到fork并打开Pull Request
  5. Respond to any CI failures or review feedback.? ? ? 对任何CI失败作出响应或审查反馈。

Remember to follow Bevy's?Code of Conduct, and thanks for contributing!

记得遵守Bevy的行为准则,感谢您的贡献!

*The same steps apply for any other repository in the?Bevy organization?that you would like to contribute to.

*同样的步骤适用于您想要贡献的Bevy组织中的任何其他存储库。

NEXT 下一个

Docs 文档


Contributing Docs 提供文档

The Bevy Book? ? ? ?bevy书

The Bevy Book is open source, along with the rest of this website. Check out the?Bevy Website repository on GitHub. The Bevy Book content is written in Markdown.

Bevy Book和这个网站的其他部分都是开源的。查看GitHub上的Bevy网站存储库。bevy书的内容是用Markdown写的。

Building the Website? ? ?建立网站

The website is built using the?Zola static site generator. Download Zola, then do the following:

该网站是使用Zola静态网站生成器构建的。下载Zola,然后执行以下操作:

  1. Clone the Bevy Website git repo and move to that directory:? ? ? ? 克隆Bevy网站的git repo并移动到该目录:

    git clone https://github.com/bevyengine/bevy-website.git
    cd bevy-website
  2. Start the Zola server? ? ? 启动Zola服务器

    zola serve
    

A local server should start and you should be able to access a local version of the website from there.

一个本地服务器应该启动,你应该能够从那里访问网站的本地版本。

Rust API Doc Syntax? ? ? ? ? Rust API文档语法

We made an extension to the markdown syntax that makes linking to Rust API docs nicer. It also gives the links special formatting. Here are some examples:

我们对markdown语法做了一个扩展,使链接到Rust API文档变得更好。它还为链接提供了特殊的格式。下面是一些例子:

  • Full Type Path:?std::collections::HashMap? ? 完整类型路径:std::collections::HashMap

    {{rust_type(type="struct" crate="std" mod="collections" name="HashMap")}}

  • Short Type:?HashMap? ? ?短类型:HashMap

    {{rust_type(type="struct" crate="std" mod="collections" name="HashMap" no_mod=true)}}

  • Function:?HashMap::insert()? ? ?功能:HashMap:插入()

    {{rust_type(type="struct" crate="std" mod="collections" name="HashMap" no_mod=true method="insert")}}

  • Module:?std::collections? ? ? 模块:std::集合

    {{rust_mod(crate="std" mod="collections")}}?

Modules from?std?will link to?https://doc.rust-lang.org. Other modules (like?bevy_render::render_graph?) will link to?https://docs.rs.

来自std的模块将链接到https://doc.rust-lang.org。其他模块(如bevy_render::render_graph)将链接到https://docs.rs。

Rust API Docs? ? ? ?Rust API文档

Bevy's Rust API Docs are automatically generated from the latest Bevy source code. If you add?Rust documentation comments?to the Bevy codebase, the API docs will be automatically updated.

Bevy的Rust API文档是从最新的Bevy源代码自动生成的。如果将Rust文档注释添加到Bevy代码库,API文档将自动更新。

Bevy Markdown Docs? ? ? Bevy Markdown文档

Bevy's CI will check markdown files like Readmes using?markdownlint. If you contribute to markdown files consider installing?markdownlint-cli?to locally lint your changes. Running?markdownlint -f -c .github/linters/.markdown-lint.yml .?in the root directory of the Bevy project will apply the same linting rules to your changes as the CI workflow.

Bevy的CI将使用markdownlint检查Readmes等markdown文件。如果您对标记文件做出了贡献,请考虑安装markdownlint-cli来本地检测您的更改。运行markdownlint -f -c .github/lint /. markdownlint。yml。在Bevy项目的根目录中,将对您的更改应用与CI工作流相同的检查规则。

NEXT 下一个

Building Bevy's Ecosystem 构建bevy的生态系统


Building Bevy's Ecosystem 构建bevy的生态系统

Bevy has a plug-and-play architecture, where you can easily add plugins for new features or use your own plugins instead of the built-in ones. You can also create third-party plugins that others may use in their applications.

Bevy有一个即插即用的架构,你可以很容易地为新功能添加插件,或者使用你自己的插件而不是内置的插件。您还可以创建其他人可能在其应用程序中使用的第三方插件。

With that in mind, this page provides some basic info that can be useful when authoring third-party plugins.

考虑到这一点,这个页面提供了一些在编写第三方插件时可能有用的基本信息。

Naming 命名

You are free to use a?bevy_xxx?name for your plugin, but please be reasonable. If you are about to claim a generic name like?bevy_animation,?bevy_color, or?bevy_editor, please ask first. The rationale is explained?here.

您可以自由地为您的插件使用bevy_xxx名称,但请合理。如果您要声明一个通用名称,如bevy_animation、bevy_color或bevy_editor,请先询问。这里解释了其基本原理。

Licensing 许可

Bevy is dual licensed under?MIT or Apache 2.0, at your option. Most other Rust projects (including Rust itself) also use this dual-license approach. MIT-only is very popular, and you might be tempted to just use that (Bevy also used to be MIT-only), but there are?very good reasons?to include both licenses. We highly recommend using the dual MIT / Apache 2.0 license for your Bevy Plugins and crates:

Bevy是MIT或Apache 2.0的双重许可,由您选择。大多数其他Rust项目(包括Rust本身)也使用这种双许可方法。MIT-only非常受欢迎,您可能会想使用它(Bevy也曾经是MIT-only),但是有很好的理由包括这两种许可。我们强烈建议使用双重MIT / Apache 2.0许可证为您的Bevy插件和板条箱:

  • Including the Apache 2.0 license option significantly reduces the difficulty and boilerplate of proper license compliance in published games because you only need to include one copy of the Apache 2.0 license.? ? ? ? ? 包含Apache 2.0许可选项可以显著降低已发行游戏中适当遵守许可的难度和样板,因为您只需要包含一份Apache 2.0许可副本。
  • Provides maximum compatibility with Bevy and Rust, making it easier to upstream your changes.? ? ? ? ?提供与Bevy和Rust的最大兼容性,使您的更改更容易上游。

Rust API and Cargo SemVer Guidelines? ? ? ? ? Rust API和Cargo SemVer指南

While they are only guidelines, it can be useful for you to look at and consider the?Rust API guidelines?and?Cargo SemVer compatibility conventions?for recommendations on how to write your API and what to consider a breaking or compatible change.? ? ? ? ? ? ?虽然它们只是指导方针,但您可以查看并考虑Rust API指导方针和Cargo SemVer兼容性约定,以获得关于如何编写API以及如何考虑破坏或兼容更改的建议。

Generic Plugin Types? ? ?通用插件类型

It can be useful to allow your users to supply generic types to your plugins. It can enable them to write custom logic for components to be used; give your plugin a marker component to note an entity it should do some logic to; add events that your plugin should listen for; or a resource your plugin should use (which is useful if you want to apply your plugin to multiple resources of the same type via type aliases.)

允许用户为插件提供泛型类型是很有用的。它可以使他们为要使用的组件编写自定义逻辑;给你的插件一个标记组件来标记一个它应该做一些逻辑处理的实体;添加插件应该监听的事件;或者你的插件应该使用的资源(如果你想通过类型别名将你的插件应用于相同类型的多个资源,这很有用)。

You can define a generic plugin like so:

你可以这样定义一个泛型插件:

// example with a generic type that implements Component
// 具有实现Component的泛型类型的示例

pub struct YourPlugin<T: Component> {
  pub phantom_t: PhantomData<T>,
}

impl<T: Component> Plugin for YourPlugin<T> {
  fn build(&self, app: &mut App) {
    app.add_systems(Startup, example_function::<T>);
  }

  // ... your other logic ...
  // …你的另一个逻辑。。。
}

// example function using your generics
// 使用泛型的示例函数
pub fn example_function<T: Component>(mut commands: Commands) {
  commands.spawn(T);
  // ... any other logic here ...
  // ...这里的任何其他逻辑。。。
}

A prime example of generic plugins in use is the?Bevy Cellular Automaton Plugin.

通用插件的一个典型例子是Bevy细胞自动机插件。

Small Crate Size? ? ?小板条箱尺寸

To avoid long build times in your plugin and in projects using it, you should aim for a small crate size:

为了避免在你的插件和使用它的项目中长时间的构建,你应该瞄准一个小的crate大小:

  • Only include the Bevy features you absolutely need.? ? ? ? 只包括你绝对需要的Bevy功能。

    Features are additive — Bevy features enabled in your plugin cannot be disabled by someone using your plugin.? ? ? ? ? ?特性是附加的——插件中启用的特性不能被使用插件的人禁用。

    You should add?default-features = false?to the Bevy dependency in your?Cargo.toml?and manually specify the features you need.? ? ? ? ?您应该将default-features = false添加到Cargo中的Bevy依赖项中。tom和手动指定您需要的特性。

    You can find a list of Bevy's features?here.? ? ? ? 您可以在这里找到Bevy的功能列表。

  • Avoid large new dependencies.? ? ? ? 避免大型的新依赖项。

  • Make sure your dependencies are not duplicated, using?cargo tree?or?cargo-deny.? ? ? ? ?使用cargo tree或cargo-deny,确保您的依赖项没有重复。

  • Put optional functionality and dependencies behind a?cargo feature.? ? ? ? ? ?将可选的功能和依赖项放在cargo feature后面。

Tests and CI? ? ?测试和CI

Tests are always good! For CI, you can check out?this example?for a quick start using GitHub Actions. As Bevy has additional Linux dependencies, you should install them before building your project (here is how Bevy is doing it). Even if you don't have many (or any) tests, setting up CI will compile check your plugin and ensure a basic level of quality.

测试总是好的!对于CI,您可以查看这个示例,以快速开始使用GitHub Actions。由于Bevy有额外的Linux依赖项,您应该在构建项目之前安装它们(Bevy是这样做的)。即使你没有很多(或任何)测试,设置CI也会对你的插件进行编译检查,并确保基本的质量水平。

Indicate Compatible Versions? ? ?说明兼容版本

Indicating which version of your plugin works with which version of Bevy can be helpful for your users. Some of your users may be using an older version of Bevy for any number of reasons. You can help them find which version of your plugin they should use. This can be shown as a simple table in your README with each version of Bevy and the corresponding compatible version of your plugin.

指出哪个版本的插件可以与哪个版本的Bevy一起工作,这对您的用户很有帮助。由于各种原因,您的一些用户可能正在使用旧版本的Bevy。你可以帮助他们找到他们应该使用的插件版本。这可以在README中显示为一个简单的表格,其中包含每个版本的Bevy和相应的插件兼容版本。

| bevy  | bevy_awesome_plugin |
|-------|---------------------|
| 0.12  | 0.3                 |
| 0.11  | 0.1                 |

Main Branch Tracking? ? ?主干跟踪

Bevy is evolving very fast. There are often new features on the main branch but have not yet been released. Your plugin might depend on Bevy Main or the latest release. You can also do both on different branches (e.g., have a?bevy_main?branch).

bevy发展得很快。通常在主分支上有新特性,但尚未发布。您的插件可能依赖于Bevy Main或最新版本。你也可以在不同的分支上同时做这两件事(例如,有一个bevy_main分支)。

If you intend to track Bevy's main branch, you can specify the latest commit you support in your?Cargo.toml?file:

如果您打算跟踪Bevy的主分支,您可以在Cargo中指定您支持的最新提交?Cargo.toml文件:

bevy = { version = "0.5", git = "https://github.com/bevyengine/bevy", rev = "9788b386c7846c99978ab5c1a33698ec5a471d84", default-features = false }

You can specify the dependency?both as a version and with git. The version will be used if the dependency is pulled from?crates.io. Otherwise, the git dependency will be used.

你既可以指定版本,也可以使用git指定依赖项。如果从crate .io中提取依赖,则将使用该版本。否则,将使用git依赖项。

You can use one of these badges to communicate to your users how closely you intend to track Bevy's main branch.

您可以使用这些徽章之一来告知您的用户您打算如何密切跟踪Bevy的主要分支。

???

[ (![ !Following released Bevy versions 以下是已发布的Bevy版本] ]( (https://img.shields.io/badge/Bevy%20tracking-released%20version-lightblue) )] ]( (https://bevyengine.org/learn/book/plugin-development/#main-branch-tracking) )

???

[ (![ !Following Bevy's main branch 跟随bevy的主要分支] ]( (https://img.shields.io/badge/Bevy%20tracking-main-lightblue) )] ]( (https://bevyengine.org/learn/book/plugin-development/#main-branch-tracking) )

Documentation and Examples? ? 文档和示例

Documentation and examples are very useful for a crate.? ? ?文档和示例对crate非常有用。

In the case of a Bevy plugin, a few screenshots or movies / animated GIFs from your examples can really help to understand what your plugin is capable of.

在使用Bevy插件的情况下,你的例子中的一些截图或电影/ gif动画可以真正帮助理解你的插件的功能。

Additionally, it can be helpful to list:

此外,列出以下内容也会有所帮助:

  • SystemSets available from your plugin, and their execution order if that's important.? ? ? ? 从你的插件中获得的系统集,以及它们的执行顺序,如果这很重要的话。
  • Components available from your plugin.? ? ? 插件中可用的组件。

Publishing Your Plugin? ? ?发布插件

There are some?extra fields?that you can add to your?Cargo.toml?manifest in the?[package]?section:

您可以将一些额外的字段添加到Cargo中。在[package]部分中显示:

  • description?— A description of the plugin description? ? ? -插件的描述
  • repository?— URL of the plugin source repository repository? ? ? -插件源存储库的URL
  • license?— The plugin license license? ? ? ?—插件的license
  • keywords 关键字?— Keywords for the plugin. "bevy" at least is a good idea here? ???插件的关键字 "bevy"至少在这里是个好主意
  • categories?— Categories of the plugin. See?the full list on crates.io. categories? ? ? ? ?-插件的类别。请参阅crate .io上的完整列表。
  • exclude 排除?— Files to exclude from the released package. Excluding the?assets?folder that you may have is a good idea, as well as any large files that are not needed by the plugin.? ? 要从发布包中排除的文件。排除掉你可能有的assets文件夹以及插件不需要的大文件是个好主意。

Once a crate is published to?crates.io, there are two badges that you can add to your?README.md?for easy links: 一旦一个crate被发布到crate中。io中,有两个徽章可以添加到自述文件中。浏览网页连结:

???

[ (![ !crates.io] ]( (https://img.shields.io/crates/v/bevy_awesome_plugin) )] ]( (https://crates.io/crates/bevy_awesome_plugin) )

???

[ (![ !docs.rs] ]( (https://docs.rs/bevy_awesome_plugin/badge.svg) )] ]( (https://docs.rs/bevy_awesome_plugin) )` `

Promotion 促销活动

You can promote your plugin in Bevy's?communities:

你可以在Bevy的社区中推广你的插件:

  • Add it as an?Asset on the official website.? ? ? ?在官网上添加为资产。
  • Announce it on?Discord, in the?#crates?channel.? ? ?在Discord的#crates频道上宣布。
  • Announce it on?Reddit.? ?在Reddit上宣布。

NEXT 下一个

Troubleshooting 故障排除


Troubleshooting 故障排除

Is something in Bevy not working as expected? Maybe one of these will resolve your problem:

bevy是不是有什么地方不像预期的那样好用?也许其中一个可以解决你的问题:

Unable to find a GPU? ? ? 无法找到GPU

thread 'main' panicked at 'Unable to find a GPU! Make sure you have installed required drivers!'
// 主线程“无法找到GPU!”确保你已经安装了所需的驱动程序!

This error message means that bevy is unable to draw to your screen. Causes include:

此错误信息表示无法绘制到屏幕上。原因包括:

  1. Vulkan-compatible drivers not installed. To fix this, install/update the drivers. On Linux this may be? ? ? ? ? 没有安装vulkan兼容的驱动程序。要解决这个问题,安装/更新驱动程序。在Linux上可能是这样vulkan-intel?or 或vulkan-radeon. .
  2. Trying to run an example on a headless machine. To fix this, install a GPU!? ? ? ? ? 试图在无头机器上运行一个示例。要解决这个问题,安装一个GPU!

Unable to debug dynamically linked Bevy application in VSCode on Windows? ? ? ? 无法在Windows上的VSCode中调试动态链接的Bevy应用程序#

The program '[10184] my-game.exe' has exited with code -1073741515 (0xc0000135). 
// 程序'[10184]my-game.exe'退出,代码为-1073741515 (0xc0000135)。

Whilst?cargo run?may load the application successfully, running via the debugging UI in VSCode may yield the above error. This error means that the required libraries were not loaded correctly (likely due to a pathing quirk with VSCode debug extensions on Windows).

虽然cargo run可以成功加载应用程序,但在VSCode中通过调试UI运行可能会产生上述错误。此错误意味着所需的库没有正确加载(可能是由于Windows上VSCode调试扩展的路径怪异)。

Edit your launch configurations in?.vscode/launch.json?so that the rust libraries are found correctly.

在.vscode/launch中编辑你的启动配置。Json以便正确找到rust库。

For?cppvsdbg: cppvsdbg:

"environment": [
    {"name":"PATH", "value":"%USERPROFILE%/.rustup/toolchains/nightly-x86_64-pc-windows-msvc/bin;${workspaceFolder}/target/debug/deps;%PATH%"}
    // Switch `nightly` to `stable` if you're using Rust stable
    // 如果您使用的是Rust-stable,请将“夜间”切换为“稳定”
],

Or for?codelldb:? ? ?对于codelldb来说:

"env": {
    "PATH": "${env:USERPROFILE}/.rustup/toolchains/nightly-x86_64-pc-windows-msvc/bin;${workspaceFolder}/target/debug/deps;${env:PATH}",
    // Switch `nightly` to `stable` if you're using Rust stable
    // 如果您使用的是Rust-stable,请将“夜间”切换为“稳定”
},

(全文结束了,谢谢观看)

文章来源:https://blog.csdn.net/zhanglz888/article/details/135664551
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。