52 lines
1.7 KiB
Rust
52 lines
1.7 KiB
Rust
use bevy::prelude::*;
|
|
|
|
/// Which plane the orbit lies on.
|
|
#[derive(Debug, Clone, Copy, Default)]
|
|
pub enum OrbitPlane {
|
|
/// XZ plane (Y up). Typical for planets around a star viewed from above.
|
|
#[default]
|
|
Horizontal,
|
|
/// XY plane (Z up). Useful for UI elements or top-down 2D-style orbits.
|
|
Vertical,
|
|
}
|
|
|
|
/// An entity that orbits around its parent's origin.
|
|
/// Attach as a child of the orbit center; local Transform is updated each frame.
|
|
#[derive(Component, Debug, Clone, Copy)]
|
|
pub struct Orbit {
|
|
pub angle: f32,
|
|
pub angular_velocity: f32,
|
|
pub radius: f32,
|
|
pub plane: OrbitPlane,
|
|
}
|
|
|
|
impl Default for Orbit {
|
|
fn default() -> Self {
|
|
Self {
|
|
angle: 0.0,
|
|
// ~1 full revolution every 40 seconds — calm enough to read at
|
|
// inspection-scale zoom levels. Callers can override per-instance.
|
|
angular_velocity: 0.15,
|
|
radius: 10.0,
|
|
plane: OrbitPlane::Horizontal,
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Advance each Orbit's angle and recompute local translation.
|
|
/// The orbit center is the parent entity (via Bevy's parent-child hierarchy).
|
|
pub fn update_orbits(mut query: Query<(&mut Orbit, &mut Transform)>, time: Res<Time>) {
|
|
let dt = time.delta_secs();
|
|
for (mut orbit, mut transform) in &mut query {
|
|
orbit.angle += orbit.angular_velocity * dt;
|
|
let (sin, cos) = orbit.angle.sin_cos();
|
|
let (x, y, z) = match orbit.plane {
|
|
OrbitPlane::Horizontal => (cos * orbit.radius, 0.0, sin * orbit.radius),
|
|
OrbitPlane::Vertical => (cos * orbit.radius, sin * orbit.radius, 0.0),
|
|
};
|
|
transform.translation.x = x;
|
|
transform.translation.y = y;
|
|
transform.translation.z = z;
|
|
}
|
|
}
|