⚠️ Beta State

PyBevy is in an early and experimental stage. The API is incomplete, subject to breaking changes without notice, and you should expect bugs. Many features are still under development.

Transforms and Hierarchy

Position, rotate, scale, and parent 2D entities.

Introduction

Every entity that has a position in the world needs a Transform component. The Transform stores its translation (position), rotation, and scale.

When you parent one entity to another, the child's transform is calculated relative to the parent's. This is a powerful way to create complex relationships.

from pybevy.prelude import *
from math import pi

The Scene

We'll create a simple solar system: a central "sun" and an orbiting "planet".

  • The Sun component is a "marker" component. It doesn't hold data, but it helps us find the sun entity in our rotator_system.
  • The setup system spawns the camera, the sun, and the planet.
  • with_children is a convenient way to spawn entities that are children of the current entity.
@component
class Sun(Component):
    pass
 
def setup(commands: Commands, asset_server: AssetServer):
    commands.spawn(Camera2d())
 
    # Spawn the sun
    commands.spawn(
        Sprite(image=asset_server.load_image("branding/icon.png")),
        Transform.from_scale(Vec3.splat(0.5)),
        Sun(),
    ).with_children(
        # Spawn the planet as a child of the sun
        lambda parent: parent.spawn(
            Sprite(
                image=asset_server.load_image("branding/bevy_logo_dark.png"),
                color=Color.srgb(0.0, 0.5, 0.8),
            ),
            # Position the planet relative to the sun
            Transform.from_xyz(150.0, 0.0, 0.0).with_scale(Vec3.splat(0.2)),
        )
    )

The Animation System

This system will query for the Sun entity and rotate it each frame. Because the planet is a child of the sun, its transform will be updated automatically, causing it to orbit!

def rotator_system(time: Res[Time], query: Query[Mut[Transform], With[Sun]]):
    for transform in query:
        # Rotate the sun by 90 degrees per second
        transform.rotate_z(90.0 * time.delta_secs())

Running the App

We add our setup and rotator_system to the app. You'll see the planet orbiting the central sun.

@entrypoint
def main(app: App) -> App:
    return (
        app
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, setup)
        .add_systems(Update, rotator_system)
    )
 
if __name__ == "__main__":
    main().run()