implemented right-click movement, up to speed with original c++ code
This commit is contained in:
100
src/main.rs
100
src/main.rs
@@ -4,13 +4,19 @@ fn main() {
|
||||
App::new()
|
||||
.add_plugins(DefaultPlugins)
|
||||
.add_systems(Startup, setup)
|
||||
.add_systems(Update, rotate_cube)
|
||||
.add_systems(Update, (handle_click, move_to_target))
|
||||
.run();
|
||||
}
|
||||
|
||||
#[derive(Component)]
|
||||
struct RotatingCube {
|
||||
rotation_speed: f32,
|
||||
struct Player {
|
||||
move_speed: f32,
|
||||
height_offset: f32,
|
||||
}
|
||||
|
||||
#[derive(Component)]
|
||||
struct MoveTarget {
|
||||
position: Vec3,
|
||||
}
|
||||
|
||||
fn setup(
|
||||
@@ -29,8 +35,12 @@ fn setup(
|
||||
Mesh3d(meshes.add(Cuboid::new(2.0, 2.0, 2.0))),
|
||||
MeshMaterial3d(materials.add(Color::srgb(1.0, 0.0, 0.0))),
|
||||
Transform::from_xyz(0.0, 1.0, 0.0),
|
||||
RotatingCube {
|
||||
rotation_speed: 2.0,
|
||||
Player {
|
||||
move_speed: 10.0,
|
||||
height_offset: 1.0,
|
||||
},
|
||||
MoveTarget {
|
||||
position: Vec3::new(0.0, 0.0, 0.0),
|
||||
},
|
||||
));
|
||||
|
||||
@@ -41,7 +51,7 @@ fn setup(
|
||||
shadows_enabled: true,
|
||||
..default()
|
||||
},
|
||||
Transform::from_xyz(10.0, 10.0, 10.0).looking_at(Vec3::ZERO, Vec3::Y),
|
||||
Transform::from_xyz(0.0, 10.0, 0.0).looking_at(Vec3::ZERO, Vec3::Y),
|
||||
));
|
||||
|
||||
// Plane
|
||||
@@ -51,27 +61,67 @@ fn setup(
|
||||
));
|
||||
}
|
||||
|
||||
fn rotate_cube(
|
||||
mut query: Query<
|
||||
(
|
||||
&mut Transform,
|
||||
&RotatingCube,
|
||||
&MeshMaterial3d<StandardMaterial>,
|
||||
),
|
||||
Without<Camera3d>,
|
||||
>,
|
||||
time: Res<Time>,
|
||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
fn handle_click(
|
||||
mouse_button: Res<ButtonInput<MouseButton>>,
|
||||
windows: Query<&Window>,
|
||||
camera_query: Query<(&Camera, &GlobalTransform)>,
|
||||
mut target_query: Query<&mut MoveTarget>,
|
||||
) {
|
||||
for (mut transform, rotating, material_handle) in query.iter_mut() {
|
||||
transform.rotate_y(rotating.rotation_speed * time.delta_secs());
|
||||
// Guard clause
|
||||
if !mouse_button.just_pressed(MouseButton::Right) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get mutable reference to the actual material
|
||||
if let Some(material) = materials.get_mut(&material_handle.0) {
|
||||
let blue = (time.elapsed_secs().sin() + 1.0) / 2.0;
|
||||
let red = 1.0 - blue;
|
||||
let color = Color::srgb(red, 0.0, blue); // cycling colours
|
||||
material.base_color = color;
|
||||
let Ok(window) = windows.single() else {
|
||||
return;
|
||||
};
|
||||
|
||||
let Some(cursor_position) = window.cursor_position() else {
|
||||
return;
|
||||
};
|
||||
|
||||
let Ok((camera, camera_transform)) = camera_query.single() else {
|
||||
return;
|
||||
};
|
||||
|
||||
let Ok(ray) = camera.viewport_to_world(camera_transform, cursor_position) else {
|
||||
return;
|
||||
};
|
||||
|
||||
// check for sky clicks
|
||||
if ray.direction.y > 0.0 {
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate the distance that the intercept with the ground occurs
|
||||
let t = -ray.origin.y / ray.direction.y;
|
||||
|
||||
// plug T into our formula
|
||||
let intersection = ray.origin + ray.direction * t;
|
||||
|
||||
for mut target in target_query.iter_mut() {
|
||||
target.position = intersection;
|
||||
}
|
||||
}
|
||||
|
||||
fn move_to_target(mut query: Query<(&mut Transform, &MoveTarget, &Player)>, time: Res<Time>) {
|
||||
for (mut transform, target, player) in query.iter_mut() {
|
||||
let adjusted_target = target.position + Vec3::Y * player.height_offset;
|
||||
let direction = adjusted_target - transform.translation;
|
||||
let distance = direction.length();
|
||||
|
||||
// stop divide by 0 errors
|
||||
if distance < 0.001 {
|
||||
continue;
|
||||
}
|
||||
|
||||
let move_amount = player.move_speed * time.delta_secs();
|
||||
|
||||
// Snap
|
||||
if distance < move_amount {
|
||||
transform.translation = adjusted_target;
|
||||
} else {
|
||||
transform.translation += direction.normalize() * move_amount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user