bevy/errors/B0004.md
Joona Aalto 25bfa80e60
Migrate cameras to required components (#15641)
# Objective

Yet another PR for migrating stuff to required components. This time,
cameras!

## Solution

As per the [selected
proposal](https://hackmd.io/tsYID4CGRiWxzsgawzxG_g#Combined-Proposal-1-Selected),
deprecate `Camera2dBundle` and `Camera3dBundle` in favor of `Camera2d`
and `Camera3d`.

Adding a `Camera` without `Camera2d` or `Camera3d` now logs a warning,
as suggested by Cart [on
Discord](https://discord.com/channels/691052431525675048/1264881140007702558/1291506402832945273).
I would personally like cameras to work a bit differently and be split
into a few more components, to avoid some footguns and confusing
semantics, but that is more controversial, and shouldn't block this core
migration.

## Testing

I ran a few 2D and 3D examples, and tried cameras with and without
render graphs.

---

## Migration Guide

`Camera2dBundle` and `Camera3dBundle` have been deprecated in favor of
`Camera2d` and `Camera3d`. Inserting them will now also insert the other
components required by them automatically.
2024-10-05 01:59:52 +00:00

3.5 KiB

B0004

A runtime warning.

An Entity with a hierarchy-inherited component has a Parent without the hierarchy-inherited component in question.

The hierarchy-inherited components defined in bevy include:

Third party plugins may also define their own hierarchy components, so read the warning message carefully and pay attention to the exact type of the missing component.

To fix this warning, add the missing hierarchy component to all ancestors of entities with the hierarchy component you wish to use.

The following code will cause a warning to be emitted:

use bevy::prelude::*;

// WARNING: this code is buggy
fn setup_cube(
    mut commands: Commands,
    mut meshes: ResMut<Assets<Mesh>>,
    mut materials: ResMut<Assets<StandardMaterial>>,
) {
    commands
        .spawn(Transform::default())
        .with_children(|parent| {
            // cube
            parent.spawn((
                Mesh3d(meshes.add(Cuboid::default())),
                MeshMaterial3d(materials.add(Color::rgb(0.8, 0.7, 0.6))),
                Transform::from_xyz(0.0, 0.5, 0.0),
            ));
        });

    // camera
    commands.spawn((
        Camera3d::default(),
        Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
     ));
}

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, setup_cube)
        .run();
}

This code will not show a cube on screen. This is because the entity spawned with commands.spawn(…) doesn't have a ViewVisibility or InheritedVisibility component. Since the cube is spawned as a child of an entity without the visibility components, it will not be visible at all.

To fix this, you must also add a Visibility component. It automatically adds the other relevant visibility components for you:

use bevy::prelude::*;

fn setup_cube(
    mut commands: Commands,
    mut meshes: ResMut<Assets<Mesh>>,
    mut materials: ResMut<Assets<StandardMaterial>>,
) {
    commands
        .spawn((Transform::default(), Visibility::default()))
        .with_children(|parent| {
            // cube
            parent.spawn((
                Mesh3d(meshes.add(Cuboid::default())),
                MeshMaterial3d(materials.add(Color::rgb(0.8, 0.7, 0.6))),
                Transform::from_xyz(0.0, 0.5, 0.0),
            ));
        });

    // camera
    commands.spawn((
        Camera3d::default(),
        Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
     ));
}

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, setup_cube)
        .run();
}

A similar problem occurs when the GlobalTransform component is missing. However, it will be automatically inserted whenever Transform is inserted, as it is a required component.

You will most likely encounter this warning when loading a scene as a child of a pre-existing Entity that does not have the proper components.