bevy-ecs-expert
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseBevy ECS Expert
Bevy ECS 专家指南
Overview
概述
A guide to building high-performance game logic using Bevy's data-oriented ECS architecture. Learn how to structure systems, optimize queries, manage resources, and leverage parallel execution.
本指南介绍如何使用Bevy的面向数据的ECS架构构建高性能游戏逻辑。学习如何构建系统、优化查询、管理资源并利用并行执行。
When to Use This Skill
何时使用该技能
- Use when developing games with the Bevy engine in Rust.
- Use when designing game systems that need to run in parallel.
- Use when optimizing game performance by minimizing cache misses.
- Use when refactoring object-oriented logic into data-oriented ECS patterns.
- 在使用Rust语言的Bevy引擎开发游戏时使用。
- 在设计需要并行运行的游戏系统时使用。
- 在通过减少缓存未命中来优化游戏性能时使用。
- 在将面向对象逻辑重构为面向数据的ECS模式时使用。
Step-by-Step Guide
分步指南
1. Defining Components
1. 定义组件
Use simple structs for data. Derive and .
ComponentReflectrust
#[derive(Component, Reflect, Default)]
#[reflect(Component)]
struct Velocity {
x: f32,
y: f32,
}
#[derive(Component)]
struct Player;使用简单结构体存储数据,派生和 trait。
ComponentReflectrust
#[derive(Component, Reflect, Default)]
#[reflect(Component)]
struct Velocity {
x: f32,
y: f32,
}
#[derive(Component)]
struct Player;2. Writing Systems
2. 编写系统
Systems are regular Rust functions that query components.
rust
fn movement_system(
time: Res<Time>,
mut query: Query<(&mut Transform, &Velocity), With<Player>>,
) {
for (mut transform, velocity) in &mut query {
transform.translation.x += velocity.x * time.delta_seconds();
transform.translation.y += velocity.y * time.delta_seconds();
}
}系统是普通的Rust函数,用于查询组件。
rust
fn movement_system(
time: Res<Time>,
mut query: Query<(&mut Transform, &Velocity), With<Player>>,
) {
for (mut transform, velocity) in &mut query {
transform.translation.x += velocity.x * time.delta_seconds();
transform.translation.y += velocity.y * time.delta_seconds();
}
}3. Managing Resources
3. 管理资源
Use for global data (score, game state).
Resourcerust
#[derive(Resource)]
struct GameState {
score: u32,
}
fn score_system(mut game_state: ResMut<GameState>) {
game_state.score += 10;
}使用存储全局数据(如分数、游戏状态)。
Resourcerust
#[derive(Resource)]
struct GameState {
score: u32,
}
fn score_system(mut game_state: ResMut<GameState>) {
game_state.score += 10;
}4. Scheduling Systems
4. 调度系统
Add systems to the builder, defining execution order if needed.
Apprust
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.init_resource::<GameState>()
.add_systems(Update, (movement_system, score_system).chain())
.run();
}将系统添加到构建器中,必要时定义执行顺序。
Apprust
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.init_resource::<GameState>()
.add_systems(Update, (movement_system, score_system).chain())
.run();
}Examples
示例
Example 1: Spawning Entities with Require Component
示例1:生成包含必填组件的实体
rust
use bevy::prelude::*;
#[derive(Component, Reflect, Default)]
#[require(Velocity, Sprite)]
struct Player;
#[derive(Component, Default)]
struct Velocity {
x: f32,
y: f32,
}
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn((
Player,
Velocity { x: 10.0, y: 0.0 },
Sprite::from_image(asset_server.load("player.png")),
));
}rust
use bevy::prelude::*;
#[derive(Component, Reflect, Default)]
#[require(Velocity, Sprite)]
struct Player;
#[derive(Component, Default)]
struct Velocity {
x: f32,
y: f32,
}
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn((
Player,
Velocity { x: 10.0, y: 0.0 },
Sprite::from_image(asset_server.load("player.png")),
));
}Example 2: Query Filters
示例2:查询过滤器
Use and to filter entities efficiently.
WithWithoutrust
fn enemy_behavior(
query: Query<&Transform, (With<Enemy>, Without<Dead>)>,
) {
for transform in &query {
// Only active enemies processed here
}
}使用和高效过滤实体。
WithWithoutrust
fn enemy_behavior(
query: Query<&Transform, (With<Enemy>, Without<Dead>)>,
) {
for transform in &query {
// 仅处理活跃敌人
}
}Best Practices
最佳实践
- ✅ Do: Use filters (
Query,With,Without) to reduce iteration count.Changed - ✅ Do: Prefer over
Reswhen read-only access is sufficient to allow parallel execution.ResMut - ✅ Do: Use to spawn complex entities atomically.
Bundle - ❌ Don't: Store heavy logic inside Components; keep them as pure data.
- ❌ Don't: Use or interior mutability inside components; let the ECS handle borrowing.
RefCell
- ✅ 推荐: 使用过滤器(
Query、With、Without)减少迭代次数。Changed - ✅ 推荐: 当仅需要只读访问时,优先使用而非
Res,以支持并行执行。ResMut - ✅ 推荐: 使用原子化生成复杂实体。
Bundle - ❌ 避免: 在组件中存储复杂逻辑;组件应仅作为纯数据容器。
- ❌ 避免: 在组件内部使用或内部可变性;让ECS处理借用逻辑。
RefCell
Troubleshooting
故障排除
Problem: System panic with "Conflict" error.
Solution: You are likely trying to access the same component mutably in two systems running in parallel. Use to order them or split the logic.
.chain()问题: 系统因“Conflict”错误崩溃。
解决方案: 你可能尝试在两个并行运行的系统中可变访问同一组件。使用指定执行顺序,或拆分逻辑。
.chain()