Fix slow slope speed with CharacterBody3D's Constant Speed instead
This commit is contained in:
parent
2c7fef2bfa
commit
b8578a0a95
@ -37,6 +37,8 @@ hit_sound = NodePath("hit_sound")
|
||||
health = 100
|
||||
punch_cooldown = 1.0
|
||||
collision_mask = 4
|
||||
slide_on_ceiling = false
|
||||
floor_constant_speed = true
|
||||
|
||||
[node name="camera_3d" type="Camera3D" parent="." unique_id=1773137418]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.8724979, -0.2644562)
|
||||
|
||||
@ -46,6 +46,8 @@ health_bar = NodePath("health_bar_sprite/health_bar_viewport/health_bar")
|
||||
health_bar_sprite = NodePath("health_bar_sprite")
|
||||
collision_layer = 2
|
||||
collision_mask = 4
|
||||
slide_on_ceiling = false
|
||||
floor_constant_speed = true
|
||||
|
||||
[node name="soldier_m" parent="." unique_id=281995630 instance=ExtResource("1_e2ekk")]
|
||||
transform = Transform3D(-0.5, 0, -4.371139e-08, 0, 0.5, 0, 4.371139e-08, 0, -0.5, 0, 0, 0)
|
||||
|
||||
@ -1,10 +1,6 @@
|
||||
use std::{collections::HashSet, f32::consts::PI, ops::Neg};
|
||||
|
||||
use godot::{
|
||||
classes::{ICharacterBody3D, KinematicCollision3D},
|
||||
obj::WithBaseField,
|
||||
prelude::*,
|
||||
};
|
||||
use godot::{classes::ICharacterBody3D, obj::WithBaseField, prelude::*};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
@ -74,47 +70,23 @@ pub trait PlayerCommon {
|
||||
|
||||
impl<T: IPlayer + ICharacterBody3D + WithBaseField> PlayerCommon for T {
|
||||
fn player_update(&mut self, delta: f64) {
|
||||
// Gravity
|
||||
self.set_y_speed(self.get_y_speed() - 9.8 * delta as f32);
|
||||
if self.base().is_on_floor() && self.get_y_speed() < 0. {
|
||||
self.set_y_speed(0.);
|
||||
}
|
||||
let vertical_velocity = Vector3::UP * self.get_y_speed();
|
||||
|
||||
// Figure out the ground plane normal (to move on the right plane)
|
||||
let mut up_vector = Vector3::UP;
|
||||
let mut most_upward_coll: Option<Gd<KinematicCollision3D>> = None;
|
||||
for coll in (0..self.base().get_slide_collision_count())
|
||||
.flat_map(|i| self.base().get_slide_collision(i))
|
||||
{
|
||||
let coll_norm_y = coll.get_normal().y;
|
||||
if let Some(prev_most_upward) = &most_upward_coll {
|
||||
if coll_norm_y > prev_most_upward.get_normal().y {
|
||||
most_upward_coll = Some(coll);
|
||||
}
|
||||
} else if coll_norm_y > 0.5 {
|
||||
// sin(30 deg) == 0.5, so this only accepts 30 deg or shallower slopes
|
||||
most_upward_coll = Some(coll);
|
||||
}
|
||||
}
|
||||
if let Some(coll) = most_upward_coll {
|
||||
up_vector = coll.get_normal();
|
||||
}
|
||||
let speed = Vector3::UP * self.get_y_speed()
|
||||
+ self
|
||||
.get_movement_dir()
|
||||
.try_normalized()
|
||||
.unwrap_or_default()
|
||||
.rotated(Vector3::UP, self.base().get_rotation().y)
|
||||
* self.get_move_speed();
|
||||
|
||||
// Ground movement (along the plane the player is currently on)
|
||||
let input_move_on_xz = self.get_movement_dir().try_normalized().unwrap_or_default();
|
||||
let ground_plane_basis = Basis::from_axis_angle(up_vector, self.base().get_rotation().y);
|
||||
let input_move_on_ground_plane = ground_plane_basis * input_move_on_xz;
|
||||
|
||||
let move_speed = self.get_move_speed();
|
||||
let ground_plane_velocity = input_move_on_ground_plane * move_speed;
|
||||
|
||||
// Commit
|
||||
if self.is_dead() {
|
||||
self.base_mut().set_velocity(Vector3::ZERO);
|
||||
} else {
|
||||
self.base_mut()
|
||||
.set_velocity(vertical_velocity + ground_plane_velocity);
|
||||
self.base_mut().set_velocity(speed);
|
||||
self.base_mut().move_and_slide();
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user