Implement footstepbox checking with raycasts
This commit is contained in:
parent
c530cfedba
commit
7fc2da4800
@ -901,6 +901,7 @@ impl LocalPlayer {
|
|||||||
camera.get_global_position() + forward,
|
camera.get_global_position() + forward,
|
||||||
&self.base().get_world_3d(),
|
&self.base().get_world_3d(),
|
||||||
&Array::from_iter(vec![self.base().get_rid()]),
|
&Array::from_iter(vec![self.base().get_rid()]),
|
||||||
|
None,
|
||||||
) {
|
) {
|
||||||
Some(res) => Some(res.position),
|
Some(res) => Some(res.position),
|
||||||
None => Some(camera.get_global_position() + forward * 100.),
|
None => Some(camera.get_global_position() + forward * 100.),
|
||||||
|
|||||||
@ -18,7 +18,7 @@ use crate::{
|
|||||||
telegrenade::Telegrenade,
|
telegrenade::Telegrenade,
|
||||||
weapon::{BallWeapon, Weapon, WeaponType},
|
weapon::{BallWeapon, Weapon, WeaponType},
|
||||||
},
|
},
|
||||||
util::shotgun_ray,
|
util::{cast_ray, shotgun_ray},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub mod ball;
|
pub mod ball;
|
||||||
@ -110,19 +110,21 @@ impl<T: IPlayer + ICharacterBody3D + WithBaseField> PlayerCommon for T {
|
|||||||
self.base_mut().set_velocity(speed);
|
self.base_mut().set_velocity(speed);
|
||||||
self.base_mut().move_and_slide();
|
self.base_mut().move_and_slide();
|
||||||
|
|
||||||
if let Some(collision) = self.base().get_last_slide_collision()
|
if self.base().is_on_floor() {
|
||||||
&& let Some(collider) = collision.get_collider()
|
if let Some(result) = cast_ray(
|
||||||
|
self.base().get_global_position() + Vector3::UP,
|
||||||
|
self.base().get_global_position() + Vector3::DOWN,
|
||||||
|
&self.base().get_world_3d(),
|
||||||
|
&Array::new(),
|
||||||
|
Some(0b100),
|
||||||
|
) && let Ok(footstep_box) = result.collider.try_cast::<FootstepBox>()
|
||||||
{
|
{
|
||||||
// Detect if it's floor we're contacting with
|
|
||||||
if collision.get_normal().dot(self.base().get_floor_normal()) > 0.95 {
|
|
||||||
if let Ok(footstep_box) = collider.try_cast::<FootstepBox>() {
|
|
||||||
self.set_walk_kind(footstep_box.bind().kind);
|
self.set_walk_kind(footstep_box.bind().kind);
|
||||||
} else {
|
} else {
|
||||||
self.set_walk_kind(FootstepKind::default());
|
self.set_walk_kind(FootstepKind::default());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Check if hitting a ceiling; if so, stop upwards velocity (done here instead of
|
// Check if hitting a ceiling; if so, stop upwards velocity (done here instead of
|
||||||
// at the start of the next frame to get the right-after-move_and_slide state
|
// at the start of the next frame to get the right-after-move_and_slide state
|
||||||
@ -262,6 +264,7 @@ impl<T: IPlayer + ICharacterBody3D + WithBaseField> PlayerCommon for T {
|
|||||||
10,
|
10,
|
||||||
PI / 2.,
|
PI / 2.,
|
||||||
2.,
|
2.,
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut colliders = HashSet::new();
|
let mut colliders = HashSet::new();
|
||||||
|
|||||||
@ -92,6 +92,7 @@ impl Weapon for Raygun {
|
|||||||
to,
|
to,
|
||||||
&self.base().get_world_3d(),
|
&self.base().get_world_3d(),
|
||||||
&Array::from_iter(vec![player]),
|
&Array::from_iter(vec![player]),
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
if play_fx {
|
if play_fx {
|
||||||
@ -231,6 +232,7 @@ impl Weapon for Shotgun {
|
|||||||
10,
|
10,
|
||||||
PI / 2.,
|
PI / 2.,
|
||||||
10.,
|
10.,
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
if play_fx {
|
if play_fx {
|
||||||
let mut bullet_decal_results = Vec::new();
|
let mut bullet_decal_results = Vec::new();
|
||||||
|
|||||||
@ -8,10 +8,11 @@ pub fn cast_ray(
|
|||||||
to: Vector3,
|
to: Vector3,
|
||||||
world: &Option<Gd<World3D>>,
|
world: &Option<Gd<World3D>>,
|
||||||
exclude: &Array<Rid>,
|
exclude: &Array<Rid>,
|
||||||
|
mask: Option<u32>,
|
||||||
) -> Option<RaycastResult> {
|
) -> Option<RaycastResult> {
|
||||||
let ray = PhysicsRayQueryParameters3D::create(from, to);
|
let ray = PhysicsRayQueryParameters3D::create(from, to);
|
||||||
if let Some(mut ray) = ray {
|
if let Some(mut ray) = ray {
|
||||||
ray.set_collision_mask(0b1111);
|
ray.set_collision_mask(mask.unwrap_or(0b1111));
|
||||||
ray.set_hit_back_faces(false);
|
ray.set_hit_back_faces(false);
|
||||||
ray.set_hit_from_inside(false);
|
ray.set_hit_from_inside(false);
|
||||||
ray.set_collide_with_bodies(true);
|
ray.set_collide_with_bodies(true);
|
||||||
@ -49,6 +50,7 @@ pub fn shotgun_ray(
|
|||||||
density: u8,
|
density: u8,
|
||||||
angle: f32,
|
angle: f32,
|
||||||
distance: f32,
|
distance: f32,
|
||||||
|
mask: Option<u32>,
|
||||||
) -> Vec<RaycastResult> {
|
) -> Vec<RaycastResult> {
|
||||||
let mut results = Vec::new();
|
let mut results = Vec::new();
|
||||||
|
|
||||||
@ -64,7 +66,7 @@ pub fn shotgun_ray(
|
|||||||
let x_rot = -(angle / 2.) + step * x as f32;
|
let x_rot = -(angle / 2.) + step * x as f32;
|
||||||
let dir = original_dir.rotated(up, x_rot).rotated(right, y_rot);
|
let dir = original_dir.rotated(up, x_rot).rotated(right, y_rot);
|
||||||
let to = from + dir * distance;
|
let to = from + dir * distance;
|
||||||
if let Some(res) = cast_ray(from, to, world, exclude) {
|
if let Some(res) = cast_ray(from, to, world, exclude, mask) {
|
||||||
results.push(res);
|
results.push(res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user