mirror of
https://github.com/bevyengine/bevy
synced 2024-11-21 20:23:28 +00:00
Migrate bevy_transform
to required components (#14964)
The first step in the migration to required components! This PR removes `GlobalTransform` from all user-facing code, since it's now added automatically wherever `Transform` is used. ## Testing - None of the examples I tested were broken, and I assume breaking transforms in any way would be visible *everywhere* --- ## Changelog - Make `Transform` require `GlobalTransform` ~~- Remove `GlobalTransform` from all engine bundles~~ - Remove in-engine insertions of GlobalTransform and TransformBundle - Deprecate `TransformBundle` - update docs to reflect changes ## Migration Guide Replace all insertions of `GlobalTransform` and/or `TransformBundle` with `Transform` alone. --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com> Co-authored-by: Tim <JustTheCoolDude@gmail.com>
This commit is contained in:
parent
a0c722ff4c
commit
b04947d44f
10 changed files with 43 additions and 67 deletions
|
@ -1,3 +1,4 @@
|
|||
#![expect(deprecated)]
|
||||
use bevy_ecs::bundle::Bundle;
|
||||
|
||||
use crate::prelude::{GlobalTransform, Transform};
|
||||
|
@ -24,6 +25,10 @@ use crate::prelude::{GlobalTransform, Transform};
|
|||
/// update the [`Transform`] of an entity in this schedule or after, you will notice a 1 frame lag
|
||||
/// before the [`GlobalTransform`] is updated.
|
||||
#[derive(Clone, Copy, Debug, Default, Bundle)]
|
||||
#[deprecated(
|
||||
since = "0.15.0",
|
||||
note = "Use the `Transform` component instead. Inserting `Transform` will now also insert a `GlobalTransform` automatically."
|
||||
)]
|
||||
pub struct TransformBundle {
|
||||
/// The transform of the entity.
|
||||
pub local: Transform,
|
||||
|
|
|
@ -17,7 +17,9 @@ use {
|
|||
///
|
||||
/// * To get the global transform of an entity, you should get its [`GlobalTransform`].
|
||||
/// * For transform hierarchies to work correctly, you must have both a [`Transform`] and a [`GlobalTransform`].
|
||||
/// * You may use the [`TransformBundle`](crate::bundles::TransformBundle) to guarantee this.
|
||||
/// ~* You may use the [`TransformBundle`](crate::bundles::TransformBundle) to guarantee this.~
|
||||
/// * [`TransformBundle`](crate::bundles::TransformBundle) is now deprecated.
|
||||
/// [`GlobalTransform`] is automatically inserted whenever [`Transform`] is inserted.
|
||||
///
|
||||
/// ## [`Transform`] and [`GlobalTransform`]
|
||||
///
|
||||
|
|
|
@ -13,7 +13,9 @@ use {
|
|||
/// * To place or move an entity, you should set its [`Transform`].
|
||||
/// * To get the global transform of an entity, you should get its [`GlobalTransform`].
|
||||
/// * To be displayed, an entity must have both a [`Transform`] and a [`GlobalTransform`].
|
||||
/// * You may use the [`TransformBundle`](crate::bundles::TransformBundle) to guarantee this.
|
||||
/// ~* You may use the [`TransformBundle`](crate::bundles::TransformBundle) to guarantee this.~
|
||||
/// * [`TransformBundle`](crate::bundles::TransformBundle) is now deprecated.
|
||||
/// [`GlobalTransform`] is inserted automatically whenever [`Transform`] is inserted.
|
||||
///
|
||||
/// ## [`Transform`] and [`GlobalTransform`]
|
||||
///
|
||||
|
@ -39,6 +41,7 @@ use {
|
|||
#[cfg_attr(
|
||||
feature = "bevy-support",
|
||||
derive(Component, Reflect),
|
||||
require(GlobalTransform),
|
||||
reflect(Component, Default, PartialEq, Debug)
|
||||
)]
|
||||
#[cfg_attr(
|
||||
|
|
|
@ -88,7 +88,6 @@ mod tests {
|
|||
use bevy_math::{Quat, Vec3};
|
||||
|
||||
use crate::{
|
||||
bundles::TransformBundle,
|
||||
components::{GlobalTransform, Transform},
|
||||
helper::TransformHelper,
|
||||
plugins::TransformPlugin,
|
||||
|
@ -122,7 +121,7 @@ mod tests {
|
|||
let mut entity = None;
|
||||
|
||||
for transform in transforms {
|
||||
let mut e = app.world_mut().spawn(TransformBundle::from(transform));
|
||||
let mut e = app.world_mut().spawn(transform);
|
||||
|
||||
if let Some(entity) = entity {
|
||||
e.set_parent(entity);
|
||||
|
|
|
@ -32,6 +32,8 @@ pub mod systems;
|
|||
/// The transform prelude.
|
||||
///
|
||||
/// This includes the most common types in this crate, re-exported for your convenience.
|
||||
#[doc(hidden)]
|
||||
#[expect(deprecated)]
|
||||
pub mod prelude {
|
||||
#[doc(hidden)]
|
||||
pub use crate::components::*;
|
||||
|
|
|
@ -190,7 +190,7 @@ mod test {
|
|||
use bevy_math::{vec3, Vec3};
|
||||
use bevy_tasks::{ComputeTaskPool, TaskPool};
|
||||
|
||||
use crate::{bundles::TransformBundle, systems::*};
|
||||
use crate::systems::*;
|
||||
use bevy_hierarchy::{BuildChildren, ChildBuild};
|
||||
|
||||
#[test]
|
||||
|
@ -199,8 +199,7 @@ mod test {
|
|||
let mut world = World::default();
|
||||
let offset_global_transform =
|
||||
|offset| GlobalTransform::from(Transform::from_xyz(offset, offset, offset));
|
||||
let offset_transform =
|
||||
|offset| TransformBundle::from_transform(Transform::from_xyz(offset, offset, offset));
|
||||
let offset_transform = |offset| Transform::from_xyz(offset, offset, offset);
|
||||
|
||||
let mut schedule = Schedule::default();
|
||||
schedule.add_systems((sync_simple_transforms, propagate_transforms));
|
||||
|
@ -257,22 +256,14 @@ mod test {
|
|||
schedule.add_systems((sync_simple_transforms, propagate_transforms));
|
||||
|
||||
// Root entity
|
||||
world.spawn(TransformBundle::from(Transform::from_xyz(1.0, 0.0, 0.0)));
|
||||
world.spawn(Transform::from_xyz(1.0, 0.0, 0.0));
|
||||
|
||||
let mut children = Vec::new();
|
||||
world
|
||||
.spawn(TransformBundle::from(Transform::from_xyz(1.0, 0.0, 0.0)))
|
||||
.spawn(Transform::from_xyz(1.0, 0.0, 0.0))
|
||||
.with_children(|parent| {
|
||||
children.push(
|
||||
parent
|
||||
.spawn(TransformBundle::from(Transform::from_xyz(0.0, 2.0, 0.)))
|
||||
.id(),
|
||||
);
|
||||
children.push(
|
||||
parent
|
||||
.spawn(TransformBundle::from(Transform::from_xyz(0.0, 0.0, 3.)))
|
||||
.id(),
|
||||
);
|
||||
children.push(parent.spawn(Transform::from_xyz(0.0, 2.0, 0.)).id());
|
||||
children.push(parent.spawn(Transform::from_xyz(0.0, 0.0, 3.)).id());
|
||||
});
|
||||
schedule.run(&mut world);
|
||||
|
||||
|
@ -299,18 +290,10 @@ mod test {
|
|||
let mut commands = Commands::new(&mut queue, &world);
|
||||
let mut children = Vec::new();
|
||||
commands
|
||||
.spawn(TransformBundle::from(Transform::from_xyz(1.0, 0.0, 0.0)))
|
||||
.spawn(Transform::from_xyz(1.0, 0.0, 0.0))
|
||||
.with_children(|parent| {
|
||||
children.push(
|
||||
parent
|
||||
.spawn(TransformBundle::from(Transform::from_xyz(0.0, 2.0, 0.0)))
|
||||
.id(),
|
||||
);
|
||||
children.push(
|
||||
parent
|
||||
.spawn(TransformBundle::from(Transform::from_xyz(0.0, 0.0, 3.0)))
|
||||
.id(),
|
||||
);
|
||||
children.push(parent.spawn(Transform::from_xyz(0.0, 2.0, 0.0)).id());
|
||||
children.push(parent.spawn(Transform::from_xyz(0.0, 0.0, 3.0)).id());
|
||||
});
|
||||
queue.apply(&mut world);
|
||||
schedule.run(&mut world);
|
||||
|
@ -417,15 +400,12 @@ mod test {
|
|||
let mut grandchild = Entity::from_raw(1);
|
||||
let parent = app
|
||||
.world_mut()
|
||||
.spawn((
|
||||
Transform::from_translation(translation),
|
||||
GlobalTransform::IDENTITY,
|
||||
))
|
||||
.spawn(Transform::from_translation(translation))
|
||||
.with_children(|builder| {
|
||||
child = builder
|
||||
.spawn(TransformBundle::IDENTITY)
|
||||
.spawn(Transform::IDENTITY)
|
||||
.with_children(|builder| {
|
||||
grandchild = builder.spawn(TransformBundle::IDENTITY).id();
|
||||
grandchild = builder.spawn(Transform::IDENTITY).id();
|
||||
})
|
||||
.id();
|
||||
})
|
||||
|
@ -462,9 +442,9 @@ mod test {
|
|||
fn setup_world(world: &mut World) -> (Entity, Entity) {
|
||||
let mut grandchild = Entity::from_raw(0);
|
||||
let child = world
|
||||
.spawn(TransformBundle::IDENTITY)
|
||||
.spawn(Transform::IDENTITY)
|
||||
.with_children(|builder| {
|
||||
grandchild = builder.spawn(TransformBundle::IDENTITY).id();
|
||||
grandchild = builder.spawn(Transform::IDENTITY).id();
|
||||
})
|
||||
.id();
|
||||
(child, grandchild)
|
||||
|
@ -477,7 +457,7 @@ mod test {
|
|||
assert_eq!(temp_grandchild, grandchild);
|
||||
|
||||
app.world_mut()
|
||||
.spawn(TransformBundle::IDENTITY)
|
||||
.spawn(Transform::IDENTITY)
|
||||
.add_children(&[child]);
|
||||
core::mem::swap(
|
||||
&mut *app.world_mut().get_mut::<Parent>(child).unwrap(),
|
||||
|
@ -496,14 +476,9 @@ mod test {
|
|||
let mut schedule = Schedule::default();
|
||||
schedule.add_systems((sync_simple_transforms, propagate_transforms));
|
||||
|
||||
// Spawn a `TransformBundle` entity with a local translation of `Vec3::ONE`
|
||||
let mut spawn_transform_bundle = || {
|
||||
world
|
||||
.spawn(TransformBundle::from_transform(
|
||||
Transform::from_translation(translation),
|
||||
))
|
||||
.id()
|
||||
};
|
||||
// Spawn a `Transform` entity with a local translation of `Vec3::ONE`
|
||||
let mut spawn_transform_bundle =
|
||||
|| world.spawn(Transform::from_translation(translation)).id();
|
||||
|
||||
// Spawn parent and child with identical transform bundles
|
||||
let parent = spawn_transform_bundle();
|
||||
|
|
|
@ -29,7 +29,7 @@ fn setup_cube(
|
|||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
) {
|
||||
commands
|
||||
.spawn(TransformBundle::default())
|
||||
.spawn(Transform::default())
|
||||
.with_children(|parent| {
|
||||
// cube
|
||||
parent.spawn(PbrBundle {
|
||||
|
@ -61,8 +61,7 @@ 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 use [`SpatialBundle`] over [`TransformBundle`],
|
||||
as follows:
|
||||
To fix this, you must use [`SpatialBundle`], as follows:
|
||||
|
||||
```rust,no_run
|
||||
use bevy::prelude::*;
|
||||
|
@ -73,7 +72,7 @@ fn setup_cube(
|
|||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
) {
|
||||
commands
|
||||
// We use SpatialBundle instead of TransformBundle, it contains the
|
||||
// We use SpatialBundle instead of Transform, it contains the
|
||||
// visibility components needed to display the cube,
|
||||
// In addition to the Transform and GlobalTransform components.
|
||||
.spawn(SpatialBundle::default())
|
||||
|
@ -103,9 +102,8 @@ fn main() {
|
|||
```
|
||||
|
||||
A similar problem occurs when the [`GlobalTransform`] component is missing.
|
||||
However, when a parent [`GlobalTransform`] is missing,
|
||||
it will simply prevent all transform propagation,
|
||||
including when updating the [`Transform`] component of the child.
|
||||
However, it will be automatically inserted whenever `Transform` is
|
||||
inserted, as it's 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.
|
||||
|
@ -113,8 +111,6 @@ as a child of a pre-existing [`Entity`] that does not have the proper components
|
|||
[`InheritedVisibility`]: https://docs.rs/bevy/*/bevy/render/view/struct.InheritedVisibility.html
|
||||
[`ViewVisibility`]: https://docs.rs/bevy/*/bevy/render/view/struct.ViewVisibility.html
|
||||
[`GlobalTransform`]: https://docs.rs/bevy/*/bevy/transform/components/struct.GlobalTransform.html
|
||||
[`Transform`]: https://docs.rs/bevy/*/bevy/transform/components/struct.Transform.html
|
||||
[`Parent`]: https://docs.rs/bevy/*/bevy/hierarchy/struct.Parent.html
|
||||
[`Entity`]: https://docs.rs/bevy/*/bevy/ecs/entity/struct.Entity.html
|
||||
[`SpatialBundle`]: https://docs.rs/bevy/*/bevy/render/prelude/struct.SpatialBundle.html
|
||||
[`TransformBundle`]: https://docs.rs/bevy/*/bevy/transform/struct.TransformBundle.html
|
||||
|
|
|
@ -130,15 +130,9 @@ fn setup(
|
|||
for i in -5..5 {
|
||||
// Create joint entities
|
||||
let joint_0 = commands
|
||||
.spawn(TransformBundle::from(Transform::from_xyz(
|
||||
i as f32 * 1.5,
|
||||
0.0,
|
||||
i as f32 * 0.1,
|
||||
)))
|
||||
.id();
|
||||
let joint_1 = commands
|
||||
.spawn((AnimatedJoint, TransformBundle::IDENTITY))
|
||||
.spawn(Transform::from_xyz(i as f32 * 1.5, 0.0, i as f32 * 0.1))
|
||||
.id();
|
||||
let joint_1 = commands.spawn((AnimatedJoint, Transform::IDENTITY)).id();
|
||||
|
||||
// Set joint_1 as a child of joint_0.
|
||||
commands.entity(joint_0).add_children(&[joint_1]);
|
||||
|
|
|
@ -111,7 +111,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
|||
..default()
|
||||
},
|
||||
Sprite::default(),
|
||||
TransformBundle::default(),
|
||||
Transform::default(),
|
||||
VisibilityBundle::default(),
|
||||
));
|
||||
}
|
||||
|
|
|
@ -380,7 +380,7 @@ fn spawn_tree(
|
|||
}
|
||||
|
||||
// insert root
|
||||
ents.push(commands.spawn(TransformBundle::from(root_transform)).id());
|
||||
ents.push(commands.spawn(root_transform).id());
|
||||
|
||||
let mut result = InsertResult::default();
|
||||
let mut rng = rand::thread_rng();
|
||||
|
@ -426,7 +426,7 @@ fn spawn_tree(
|
|||
};
|
||||
|
||||
// only insert the components necessary for the transform propagation
|
||||
cmd = cmd.insert(TransformBundle::from(transform));
|
||||
cmd = cmd.insert(transform);
|
||||
|
||||
cmd.id()
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue