Reputation: 1150
I have a cube that is supposed to be floating (gravity set to 0). After an event, the cube is supposed to "fall down" (gravity set to 1). I know that the RigidBody is asleep when gravity is set to 0
, so I am trying to wake it up by applying an ExternalForce
.
Here is my code
use bevy::prelude::*;
use std::time::Duration;
use bevy_inspector_egui::quick::WorldInspectorPlugin;
use bevy_rapier3d::prelude::*;
use leafwing_input_manager::prelude::*;
use prelude::*;
#[derive(Component)]
struct MyGameCamera;
#[derive(Reflect, Component, Default)]
#[reflect(Component)]
struct ActiveElement {
pendulum_timer: Timer,
pendulum_inverted: bool,
}
#[derive(Component)]
struct Player;
#[derive(Actionlike, PartialEq, Eq, Clone, Copy, Hash, Debug)]
enum Action {
Drop,
}
fn main() {
App::new()
.register_type::<ActiveElement>()
.add_plugins(DefaultPlugins)
.add_plugin(RapierPhysicsPlugin::<NoUserData>::default())
.add_plugin(RapierDebugRenderPlugin::default())
.add_plugin(WorldInspectorPlugin::default())
.add_plugin(InputManagerPlugin::<Action>::default())
.add_startup_system(setup)
.add_system(drop)
.run()
}
fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
// Camera
commands.spawn((
Camera3dBundle {
transform: Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
..Default::default()
},
MyGameCamera,
));
// Light
commands.spawn(PointLightBundle {
transform: Transform::from_xyz(4.0, 10.0, 4.0),
point_light: PointLight {
intensity: 3000.0,
shadows_enabled: true,
range: 30.0,
..default()
},
..default()
});
// Floor
commands
.spawn(PbrBundle {
mesh: meshes.add(shape::Plane::from_size(5.0).into()),
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
..default()
})
.insert(Collider::cuboid(100.0, 0.1, 100.0));
// cube
commands
.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Box::new(1.0, 0.2, 1.0))),
material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()),
transform: Transform::from_xyz(0.0, 1.6, 0.0),
..default()
})
.insert(RigidBody::Dynamic)
.insert(Collider::cuboid(0.5, 0.1, 0.5))
.insert(ColliderMassProperties::Density(1.0))
.insert(Restitution::coefficient(0.1))
.insert(Name::new("Cube"))
.insert(GravityScale(0.0))
.insert(ActiveElement {
pendulum_timer: Timer::new(Duration::from_secs(3), TimerMode::Repeating),
pendulum_inverted: false,
});
// Input
commands
.spawn(InputManagerBundle::<Action> {
action_state: ActionState::default(),
input_map: InputMap::new([(KeyCode::Space, Action::Drop)]),
})
.insert(Player);
}
fn drop(
action: Query<&ActionState<Action>, With<Player>>,
mut query: Query<(&mut GravityScale, &mut ExternalForce, &mut Sleeping), With<ActiveElement>>,
) {
let action_state = action.single();
if action_state.just_pressed(Action::Drop) {
query.iter_mut().for_each(|(mut gravity_scale, mut external_force, mut sleeping)| {
gravity_scale.0 = 1.0;
sleeping.sleeping = false;
external_force.force = Vec3::new(200.0, 30000.0, 0.0);
external_force.torque = Vec3::new(10.0, 1.0, 0.0);
});
}
}
Cargo.toml
[...]
[dependencies]
bevy = "0.10.0"
bevy_rapier3d = { version = "0.21.0", features = [ "simd-stable", "debug-render", "parallel" ] }
leafwing-input-manager = "0.9.0"
bevy-inspector-egui = "0.18.0"
[...]
I can see with the egui inspector that the gravity is applied to the Cube
, but the RigidBody is not woken up (I assume...). What am I missing?
Upvotes: 0
Views: 169