feat: implemented camera bob and weapon bob and lead
This commit is contained in:
		
							parent
							
								
									eea0d85ff7
								
							
						
					
					
						commit
						dc65707ff1
					
				| 
						 | 
					@ -7,10 +7,24 @@ void PlayerCamera::_bind_methods() {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void PlayerCamera::on_look_input(Vector2 input) {
 | 
					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, {
 | 
						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);
 | 
						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<Node3D>(child) }) {
 | 
				
			||||||
 | 
								child3d->set_rotation(this->weapon_lead_rotation);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void PlayerCamera::update_fov() {
 | 
					void PlayerCamera::update_fov() {
 | 
				
			||||||
| 
						 | 
					@ -20,7 +34,7 @@ void PlayerCamera::update_fov() {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void PlayerCamera::update_offset() {
 | 
					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) {
 | 
						if (is_running != this->was_running) {
 | 
				
			||||||
		this->was_running = is_running;
 | 
							this->was_running = is_running;
 | 
				
			||||||
		this->run_bob_time = 0.0;
 | 
							this->run_bob_time = 0.0;
 | 
				
			||||||
| 
						 | 
					@ -28,8 +42,8 @@ void PlayerCamera::update_offset() {
 | 
				
			||||||
	double wave{ Math::sin(this->run_bob_time) };
 | 
						double wave{ Math::sin(this->run_bob_time) };
 | 
				
			||||||
	Vector3 offset{ Vector3{ float(wave), float(Math::abs(wave)), 0 } * this->run_bob_amplitude };
 | 
						Vector3 offset{ Vector3{ float(wave), float(Math::abs(wave)), 0 } * this->run_bob_amplitude };
 | 
				
			||||||
	if (!is_running) {
 | 
						if (!is_running) {
 | 
				
			||||||
		this->run_bob_time = MIN(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_amplitude);
 | 
							offset = offset.lerp(Vector3(), this->run_bob_time / this->run_bob_blend_out);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	GETSET(position, {
 | 
						GETSET(position, {
 | 
				
			||||||
		Basis const basis{ get_basis() };
 | 
							Basis const basis{ get_basis() };
 | 
				
			||||||
| 
						 | 
					@ -89,4 +103,5 @@ void PlayerCamera::recoil(float r) {
 | 
				
			||||||
	GETSET(rotation, {
 | 
						GETSET(rotation, {
 | 
				
			||||||
		rotation.x = CLAMP(rotation.x + r, -Math::PI / 2.0, Math::PI / 2.0);
 | 
							rotation.x = CLAMP(rotation.x + r, -Math::PI / 2.0, Math::PI / 2.0);
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
						lead_weapon({ 0, 0.02f });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,6 +8,7 @@ class PlayerCamera : public Camera3D {
 | 
				
			||||||
	GDCLASS(PlayerCamera, Camera3D);
 | 
						GDCLASS(PlayerCamera, Camera3D);
 | 
				
			||||||
	static void _bind_methods();
 | 
						static void _bind_methods();
 | 
				
			||||||
	void on_look_input(Vector2 input);
 | 
						void on_look_input(Vector2 input);
 | 
				
			||||||
 | 
						void lead_weapon(Vector2 movement);
 | 
				
			||||||
	void update_fov();
 | 
						void update_fov();
 | 
				
			||||||
	void update_offset();
 | 
						void update_offset();
 | 
				
			||||||
	void ready();
 | 
						void ready();
 | 
				
			||||||
| 
						 | 
					@ -31,6 +32,10 @@ private:
 | 
				
			||||||
	double run_bob_time{ 0.0 };
 | 
						double run_bob_time{ 0.0 };
 | 
				
			||||||
	double run_bob_amplitude{ 0.025 };
 | 
						double run_bob_amplitude{ 0.025 };
 | 
				
			||||||
	double run_bob_frequency{ 10.0 };
 | 
						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
 | 
					#endif // !PLAYER_CAMERA_H
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue