use std::f32::consts::FRAC_PI_2;
use avian_pickup::prelude::*;
use avian3d::prelude::*;
use bevy::{color::palettes::tailwind, input::mouse::AccumulatedMouseMotion, prelude::*};
mod util;
fn main() {
App::new()
.add_plugins((
DefaultPlugins,
PhysicsPlugins::default(),
AvianPickupPlugin::default(),
util::plugin(util::Example::Generic),
))
.add_systems(Startup, setup)
.add_systems(
RunFixedMainLoop,
(handle_input, rotate_camera).in_set(RunFixedMainLoopSystem::BeforeFixedMainLoop),
)
.run();
}
fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
let terrain_material = materials.add(Color::WHITE);
let prop_material = materials.add(Color::from(tailwind::EMERALD_300));
commands.spawn((
Name::new("Player Camera"),
Camera3d::default(),
Transform::from_xyz(0.0, 1.0, 5.0),
AvianPickupActor::default(),
));
commands.spawn((
Name::new("Light"),
Transform::from_xyz(3.0, 8.0, 3.0),
PointLight {
color: Color::WHITE,
intensity: 2_000_000.0,
shadows_enabled: true,
..default()
},
));
let ground_shape = Cuboid::new(15.0, 0.25, 15.0);
commands.spawn((
Name::new("Ground"),
Mesh3d::from(meshes.add(Mesh::from(ground_shape))),
MeshMaterial3d::from(terrain_material.clone()),
RigidBody::Static,
Collider::from(ground_shape),
));
let box_shape = Cuboid::from_size(Vec3::splat(0.5));
commands.spawn((
Name::new("Box"),
Mesh3d::from(meshes.add(Mesh::from(box_shape))),
MeshMaterial3d::from(prop_material.clone()),
Transform::from_xyz(0.0, 2.0, 3.5),
RigidBody::Dynamic,
Collider::from(box_shape),
TransformInterpolation,
));
}
fn handle_input(
mut avian_pickup_input_writer: EventWriter<AvianPickupInput>,
key_input: Res<ButtonInput<MouseButton>>,
actors: Query<Entity, With<AvianPickupActor>>,
) {
for actor in &actors {
if key_input.just_pressed(MouseButton::Left) {
avian_pickup_input_writer.send(AvianPickupInput {
action: AvianPickupAction::Throw,
actor,
});
}
if key_input.just_pressed(MouseButton::Right) {
avian_pickup_input_writer.send(AvianPickupInput {
action: AvianPickupAction::Drop,
actor,
});
}
if key_input.pressed(MouseButton::Right) {
avian_pickup_input_writer.send(AvianPickupInput {
action: AvianPickupAction::Pull,
actor,
});
}
}
}
fn rotate_camera(
accumulated_mouse_motion: Res<AccumulatedMouseMotion>,
mut transform: Single<&mut Transform, With<Camera>>,
) {
let camera_sensitivity = Vec2::new(0.001, 0.001);
let delta = accumulated_mouse_motion.delta;
let delta_yaw = -delta.x * camera_sensitivity.x;
let delta_pitch = -delta.y * camera_sensitivity.y;
let (yaw, pitch, roll) = transform.rotation.to_euler(EulerRot::YXZ);
let yaw = yaw + delta_yaw;
const PITCH_LIMIT: f32 = FRAC_PI_2 - 0.01;
let pitch = (pitch + delta_pitch).clamp(-PITCH_LIMIT, PITCH_LIMIT);
transform.rotation = Quat::from_euler(EulerRot::YXZ, yaw, pitch, roll);
}