use std::f32::consts::TAU;
use bevy::{
prelude::*,
window::CursorGrabMode,
};
use bevy_rapier3d::prelude::*;
use bevy_fps_controller::controller::*;
fn main() {
App::new()
.insert_resource(AmbientLight {
color: Color::WHITE,
brightness: 0.25,
})
.insert_resource(ClearColor(Color::hex("D4F5F5").unwrap()))
.insert_resource(RapierConfiguration::default())
.add_plugins(DefaultPlugins.set(WindowPlugin {
window: WindowDescriptor {
title: String::from("Minimal FPS Controller Example"),
..default()
},
..default()
}))
.add_plugin(RapierPhysicsPlugin::<NoUserData>::default())
.add_plugin(FpsControllerPlugin)
.add_startup_system(setup)
.add_system(manage_cursor)
.run();
}
fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
commands.spawn(DirectionalLightBundle {
directional_light: DirectionalLight {
illuminance: 2000.0,
shadows_enabled: true,
..default()
},
transform: Transform::from_xyz(-38.0, 40.0, 34.0),
..default()
});
commands.spawn((
Collider::capsule(Vec3::Y * 0.5, Vec3::Y * 1.5, 0.5),
Friction {
coefficient: 0.0,
combine_rule: CoefficientCombineRule::Min,
},
Restitution {
coefficient: 0.0,
combine_rule: CoefficientCombineRule::Min,
},
ActiveEvents::COLLISION_EVENTS,
Velocity::zero(),
RigidBody::Dynamic,
Sleeping::disabled(),
LockedAxes::ROTATION_LOCKED,
AdditionalMassProperties::Mass(1.0),
GravityScale(0.0),
Ccd { enabled: true }, TransformBundle::from_transform(Transform::from_xyz(0.0, 3.0, 0.0)),
LogicalPlayer(0),
FpsControllerInput {
pitch: -TAU / 12.0,
yaw: TAU * 5.0 / 8.0,
..default()
},
FpsController { ..default() }
));
commands.spawn((
Camera3dBundle::default(),
RenderPlayer(0),
));
commands.spawn((
PbrBundle {
mesh: meshes.add(Mesh::from(shape::Box {
min_x: -20.0,
max_x: 20.0,
min_y: -0.25,
max_y: 0.25,
min_z: -20.0,
max_z: 20.0,
})),
material: materials.add(StandardMaterial {
base_color: Color::hex("8C9A9E").unwrap(),
..default()
}),
transform: Transform::from_xyz(0.0, -0.25, 0.0),
..default()
},
Collider::cuboid(20.0, 0.25, 20.0),
RigidBody::Fixed,
));
let material = materials.add(StandardMaterial {
base_color: Color::hex("747578").unwrap(),
..default()
});
commands.spawn((
PbrBundle {
mesh: meshes.add(Mesh::from(shape::Box {
min_x: -1.0,
max_x: 1.0,
min_y: -0.5,
max_y: 0.5,
min_z: -1.0,
max_z: 1.0,
})),
material: material.clone(),
transform: Transform::from_xyz(4.0, 0.5, 4.0),
..default()
},
Collider::cuboid(1.0, 1.0, 1.0),
RigidBody::Fixed,
));
commands.spawn((
PbrBundle {
mesh: meshes.add(Mesh::from(shape::Box {
min_x: -1.0,
max_x: 1.0,
min_y: -1.0,
max_y: 1.0,
min_z: -1.0,
max_z: 1.0,
})),
material: material.clone(),
transform: Transform::from_xyz(2.0, 1.0, 4.0),
..default()
},
Collider::cuboid(1.0, 2.0, 1.0),
RigidBody::Fixed,
));
}
pub fn manage_cursor(
mut windows: ResMut<Windows>,
btn: Res<Input<MouseButton>>,
key: Res<Input<KeyCode>>,
mut controllers: Query<&mut FpsController>,
) {
let window = windows.get_primary_mut().unwrap();
if btn.just_pressed(MouseButton::Left) {
window.set_cursor_grab_mode(CursorGrabMode::Locked);
window.set_cursor_visibility(false);
for mut controller in &mut controllers {
controller.enable_input = true;
}
}
if key.just_pressed(KeyCode::Escape) {
window.set_cursor_grab_mode(CursorGrabMode::None);
window.set_cursor_visibility(true);
for mut controller in &mut controllers {
controller.enable_input = false;
}
}
}