chrisgliddon/bevy-skills

bevy-ecs-components

Use when defining [derive(Component)], declaring required components with [require(...)], writing observers with On , choosing Table versus SparseSet storage, registering onadd/ondiscard/onremove hooks, or migrating Replace lifecycle events in Bevy 0.19.

소스 보기

사용 방법

  1. 설치 명령을 복사하고 자신의 에이전트 환경에 설치하기 전에 소스 패키지를 확인하세요.
  2. 필요한 도구, 인증 정보, 지원 환경은 원본 문서에서 확인하세요.
  3. 입력과 원하는 산출물을 설명하고 출처와 결과를 대조하세요.
npx skills add https://github.com/chrisgliddon/bevy-skills --skill bevy-ecs-components

시작 전 확인

  • 설치에는 모델 구독, API 한도, 파일 접근 권한이 포함되지 않습니다.
  • 별점 수와 설치 수는 활동 지표이며 독립적인 품질·보안 검증이 아닙니다.
원본 Skill 문서

원본 저장소의 제목, 예시, 코드, 표, 링크, 이미지를 유지해 표시합니다.

Bevy 0.19 — ECS Components

When to use this skill

  • Defining a new Component for game state.
  • Bundling components via #[require(...)] (the modern replacement for "bundles").
  • Reacting to component lifecycle: spawning, despawning, inserting, removing.
  • Observers — reacting to entity-targeted events with On<E>.
  • Choosing storage: Table (default, fast iteration) vs SparseSet (fast add/remove).

Canonical pattern

rust
use bevy::prelude::*;

// 1. Plain components.
#[derive(Component, Default)]
struct Health(f32);

#[derive(Component)]
struct Velocity(Vec3);

// 2. Required components — spawning `Player` auto-spawns the rest.
//    `#[require]` accepts `Type` (Default), `Type(args)` (tuple constructor),
//    or `Type = expression`.
#[derive(Component)]
#[require(Health = Health(100.0), Velocity = Velocity(Vec3::ZERO), Transform)]
struct Player;

// 3. Sparse storage for components added/removed every frame (e.g. tags
//    flipped by gameplay). Default Table storage is faster to iterate.
#[derive(Component)]
#[component(storage = "SparseSet")]
struct Stunned;

// 4. An entity-targeted event reacted to by observers.
#[derive(EntityEvent)]
struct Damage {
    entity: Entity, // EntityEvent requires an `entity` field.
    amount: f32,
}

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, spawn_player)
        .add_systems(Update, deal_damage)
        .add_observer(on_damage)
        .run();
}

fn spawn_player(mut commands: Commands) {
    commands.spawn(Player);
}

fn deal_damage(mut commands: Commands, query: Query<Entity, With<Player>>) {
    for entity in &query {
        commands.trigger(Damage { entity, amount: 10.0 });
    }
}

// Observer parameter is `On<E>`, not `Trigger<E>` (renamed in 0.17, PR #19596).
fn on_damage(damage: On<Damage>, mut query: Query<&mut Health>) {
    let event = damage.event();
    if let Ok(mut hp) = query.get_mut(event.entity) {
        hp.0 -= event.amount;
    }
}

Bevy 0.19 gotchas

  • `Trigger<E>` is gone. Observer params are On<E> in 0.17+. Methods: event(), event_mut(), observer(), original_event_target(), propagate(bool).
  • `EntityEvent::set_target` requires use bevy::ecs::entity::SetEntityEventTarget; — not in the prelude.
  • Storage choice is irrevocable: it is compiled into the component. SparseSet is designed for frequent insertion/removal; Table is the default and usually iterates faster. Benchmark the real workload before changing storage.
  • `#[require(T)]` runs `T::default()`. If T: !Default, use #[require(T = expression)] or #[require(T = T::new(...))].
  • Required components are recursive. If A requires B and B requires C, inserting A also inserts C. A constructor specified directly by A wins over an inherited constructor; requirement cycles are invalid.
  • `Replace` became `Discard` in 0.19. Use hooks on_add, on_insert, on_discard, and on_remove; the derive attribute is #[component(on_discard = path)].
  • Hooks run inside World mutations, cannot take arbitrary SystemParams, and cannot despawn the entity they fire on. Use observers when you need flexibility.
  • `Resource` is now a `Component` subtrait. Do not derive both. Each resource value lives as a component on a resource entity, and inserting another value of the same resource type can move which entity owns the singleton; keep ordinary entity components and global resources as distinct types unless that behavior is intentional.
  • `Bundle` derive still exists but most use-cases are better served by #[require(...)] on a "marker" component, which keeps the spawn surface ergonomic.

See also

  • bevy-ecs-queries — reading components back out.
  • bevy-ecs-systems — observers are themselves systems.
  • bevy-migration-0-17-to-0-18 — full Trigger→On and event→message rename map.
  • bevy-migration-0-18-to-0-19 — Discard lifecycle events and resources-as-components.
같은 저장소의 Skills

더 많은 Skills

모든 Skills