diff --git a/modules/wave_survival/player_camera.cpp b/modules/wave_survival/player_camera.cpp index 92ed0c34..cb166f91 100644 --- a/modules/wave_survival/player_camera.cpp +++ b/modules/wave_survival/player_camera.cpp @@ -7,10 +7,24 @@ void PlayerCamera::_bind_methods() { } void PlayerCamera::on_look_input(Vector2 input) { + // PI / 2.1 to avoid change to the flattened forward vector + static const double LOOK_LIM{ Math::PI / 2.1 }; GETSET(rotation, { - rotation.x = CLAMP(rotation.x + input.y, -Math::PI / 2.1, Math::PI / 2.1); + rotation.x = CLAMP(rotation.x + input.y, -LOOK_LIM, LOOK_LIM); }); global_rotate(Vector3{ 0.f, 1.f, 0.f }, input.x); + lead_weapon(input * this->weapon_lead_speed); +} + +void PlayerCamera::lead_weapon(Vector2 movement) { + this->weapon_lead_rotation.x += movement.y; + this->weapon_lead_rotation.y += movement.x; + this->weapon_lead_rotation = this->weapon_lead_rotation.normalized() * CLAMP(this->weapon_lead_rotation.length(), -this->weapon_lead_limit, this->weapon_lead_limit); + for (Variant child : get_children()) { + if (Node3D * child3d{ cast_to(child) }) { + child3d->set_rotation(this->weapon_lead_rotation); + } + } } void PlayerCamera::update_fov() { @@ -20,7 +34,7 @@ void PlayerCamera::update_fov() { } void PlayerCamera::update_offset() { - bool const is_running{ this->body->get_is_running() }; + bool const is_running{ this->body->get_is_running() && this->body->is_on_floor() }; if (is_running != this->was_running) { this->was_running = is_running; this->run_bob_time = 0.0; @@ -28,8 +42,8 @@ void PlayerCamera::update_offset() { double wave{ Math::sin(this->run_bob_time) }; Vector3 offset{ Vector3{ float(wave), float(Math::abs(wave)), 0 } * this->run_bob_amplitude }; if (!is_running) { - this->run_bob_time = MIN(this->run_bob_time, this->run_bob_amplitude); - offset = offset.lerp(Vector3(), this->run_bob_time / this->run_bob_amplitude); + this->run_bob_time = MIN(this->run_bob_time, this->run_bob_blend_out); + offset = offset.lerp(Vector3(), this->run_bob_time / this->run_bob_blend_out); } GETSET(position, { Basis const basis{ get_basis() }; @@ -89,4 +103,5 @@ void PlayerCamera::recoil(float r) { GETSET(rotation, { rotation.x = CLAMP(rotation.x + r, -Math::PI / 2.0, Math::PI / 2.0); }); + lead_weapon({ 0, 0.02f }); } diff --git a/modules/wave_survival/player_camera.h b/modules/wave_survival/player_camera.h index a5a3ce94..dd7563b5 100644 --- a/modules/wave_survival/player_camera.h +++ b/modules/wave_survival/player_camera.h @@ -8,6 +8,7 @@ class PlayerCamera : public Camera3D { GDCLASS(PlayerCamera, Camera3D); static void _bind_methods(); void on_look_input(Vector2 input); + void lead_weapon(Vector2 movement); void update_fov(); void update_offset(); void ready(); @@ -31,6 +32,10 @@ private: double run_bob_time{ 0.0 }; double run_bob_amplitude{ 0.025 }; double run_bob_frequency{ 10.0 }; + double run_bob_blend_out{ 0.2 }; + double weapon_lead_limit{ Math::PI * 0.0075 }; + double weapon_lead_speed{ 0.15 }; + Vector3 weapon_lead_rotation{ 0, 0, 0 }; }; #endif // !PLAYER_CAMERA_H