Update raycasting to work properly for all players
This commit is contained in:
parent
d4f4dc43b0
commit
0678c56dae
@ -12,6 +12,7 @@ look_sensitivity = 1.5
|
||||
camera = NodePath("camera_3d")
|
||||
move_speed = 5.0
|
||||
soldier_mesh = NodePath("soldier_m")
|
||||
health = 100
|
||||
collision_mask = 4
|
||||
|
||||
[node name="camera_3d" type="Camera3D" parent="." unique_id=1773137418]
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
[node name="player" type="RemotePlayer" unique_id=845968872 node_paths=PackedStringArray("soldier_mesh")]
|
||||
move_speed = 5.0
|
||||
soldier_mesh = NodePath("soldier_m")
|
||||
health = 100
|
||||
collision_layer = 2
|
||||
collision_mask = 4
|
||||
|
||||
|
||||
@ -27,20 +27,29 @@ impl From<NetVector3> for Vector3 {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cast_ray(from: Vector3, to: Vector3, world: Option<Gd<World3D>>) -> Option<RaycastResult> {
|
||||
pub fn cast_ray(
|
||||
from: Vector3,
|
||||
to: Vector3,
|
||||
world: Option<Gd<World3D>>,
|
||||
exclude: Array<Rid>,
|
||||
) -> Option<RaycastResult> {
|
||||
let ray = PhysicsRayQueryParameters3D::create(from, to);
|
||||
if let Some(mut ray) = ray {
|
||||
ray.set_collision_mask(0b110);
|
||||
ray.set_collision_mask(0b111);
|
||||
ray.set_hit_back_faces(false);
|
||||
ray.set_hit_from_inside(false);
|
||||
ray.set_collide_with_bodies(true);
|
||||
ray.set_exclude(&exclude);
|
||||
if let Some(world) = world
|
||||
&& let Some(mut space) = world.get_direct_space_state()
|
||||
{
|
||||
let results = space.intersect_ray(&ray);
|
||||
if let Some(position) = results.get("position") {
|
||||
if let (Some(position), Some(collider)) =
|
||||
(results.get("position"), results.get("collider"))
|
||||
{
|
||||
Some(RaycastResult {
|
||||
position: Vector3::from_variant(&position),
|
||||
collider: Gd::from_variant(&collider),
|
||||
})
|
||||
} else {
|
||||
None
|
||||
@ -55,4 +64,5 @@ pub fn cast_ray(from: Vector3, to: Vector3, world: Option<Gd<World3D>>) -> Optio
|
||||
|
||||
pub struct RaycastResult {
|
||||
pub position: Vector3,
|
||||
pub collider: Gd<Object>,
|
||||
}
|
||||
|
||||
@ -44,6 +44,7 @@ pub trait IPlayer {
|
||||
fn get_transform(&self) -> NetPlayerTransform;
|
||||
fn jump(&mut self);
|
||||
fn try_shoot(&mut self, to: Vector3, deal_damage: bool) -> bool;
|
||||
fn take_damage(&mut self, damage: i32);
|
||||
}
|
||||
|
||||
pub trait PlayerMovement {
|
||||
@ -81,6 +82,8 @@ pub struct LocalPlayer {
|
||||
move_speed: f32,
|
||||
#[export]
|
||||
soldier_mesh: Option<Gd<SoldierMesh>>,
|
||||
#[export]
|
||||
health: i32,
|
||||
|
||||
pub player_id: Option<u16>,
|
||||
pub weapon: Option<DynGd<Node3D, dyn Weapon>>,
|
||||
@ -156,8 +159,9 @@ impl IPlayer for LocalPlayer {
|
||||
|
||||
fn try_shoot(&mut self, to: Vector3, deal_damage: bool) -> bool {
|
||||
if self.shoot_cd <= 0. {
|
||||
let rid = self.base().get_rid();
|
||||
if let Some(weapon) = &mut self.weapon {
|
||||
weapon.dyn_bind_mut().shoot(to, deal_damage);
|
||||
weapon.dyn_bind_mut().shoot(rid, to, deal_damage);
|
||||
}
|
||||
self.shoot_cd = 0.2;
|
||||
true
|
||||
@ -165,6 +169,11 @@ impl IPlayer for LocalPlayer {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn take_damage(&mut self, damage: i32) {
|
||||
godot_print!("Took damage!");
|
||||
self.health -= damage;
|
||||
}
|
||||
}
|
||||
|
||||
#[godot_api]
|
||||
@ -225,6 +234,7 @@ impl ICharacterBody3D for LocalPlayer {
|
||||
camera.get_global_position(),
|
||||
camera.get_global_position() + forward,
|
||||
self.base().get_world_3d(),
|
||||
Array::from_iter(vec![self.base().get_rid()]),
|
||||
) {
|
||||
Some(res) => Some(res.position),
|
||||
None => Some(camera.get_global_position() + forward * 100.),
|
||||
@ -233,8 +243,6 @@ impl ICharacterBody3D for LocalPlayer {
|
||||
None
|
||||
};
|
||||
|
||||
godot_print!("{:?}", pos);
|
||||
|
||||
if let Some(pos) = pos {
|
||||
if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer {
|
||||
match peer {
|
||||
@ -298,6 +306,8 @@ pub struct RemotePlayer {
|
||||
move_speed: f32,
|
||||
#[export]
|
||||
soldier_mesh: Option<Gd<SoldierMesh>>,
|
||||
#[export]
|
||||
health: i32,
|
||||
|
||||
pub player_id: Option<u16>,
|
||||
pub weapon: Option<DynGd<Node3D, dyn Weapon>>,
|
||||
@ -369,8 +379,9 @@ impl IPlayer for RemotePlayer {
|
||||
|
||||
fn try_shoot(&mut self, to: Vector3, deal_damage: bool) -> bool {
|
||||
if self.shoot_cd <= 0. {
|
||||
let rid = self.base().get_rid();
|
||||
if let Some(weapon) = &mut self.weapon {
|
||||
weapon.dyn_bind_mut().shoot(to, deal_damage);
|
||||
weapon.dyn_bind_mut().shoot(rid, to, deal_damage);
|
||||
}
|
||||
self.shoot_cd = 0.2;
|
||||
true
|
||||
@ -378,6 +389,11 @@ impl IPlayer for RemotePlayer {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn take_damage(&mut self, damage: i32) {
|
||||
godot_print!("Took damage!");
|
||||
self.health -= damage;
|
||||
}
|
||||
}
|
||||
|
||||
#[godot_api]
|
||||
|
||||
@ -3,10 +3,10 @@ use godot::{
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
use crate::net::util::cast_ray;
|
||||
use crate::{net::util::cast_ray, player::IPlayer};
|
||||
|
||||
pub trait Weapon {
|
||||
fn shoot(&mut self, to: Vector3, deal_damage: bool);
|
||||
fn shoot(&mut self, player: Rid, to: Vector3, deal_damage: bool);
|
||||
}
|
||||
|
||||
#[derive(GodotClass)]
|
||||
@ -24,16 +24,22 @@ pub struct Raygun {
|
||||
|
||||
#[godot_dyn]
|
||||
impl Weapon for Raygun {
|
||||
fn shoot(&mut self, to: Vector3, deal_damage: bool) {
|
||||
fn shoot(&mut self, player: Rid, to: Vector3, deal_damage: bool) {
|
||||
if let Some(emitter) = &mut self.sound_emitter {
|
||||
emitter.play();
|
||||
}
|
||||
|
||||
if let Some(source) = &self.bullet_source {
|
||||
let target = cast_ray(source.get_global_position(), to, self.base().get_world_3d());
|
||||
let target = cast_ray(
|
||||
source.get_global_position(),
|
||||
to,
|
||||
self.base().get_world_3d(),
|
||||
Array::from_iter(vec![player]),
|
||||
);
|
||||
|
||||
let dir = (to - source.get_global_position()).normalized();
|
||||
let beam_end = target
|
||||
.as_ref()
|
||||
.map(|r| r.position)
|
||||
.unwrap_or(source.get_global_position() + dir * 100.);
|
||||
|
||||
@ -47,6 +53,13 @@ impl Weapon for Raygun {
|
||||
parent.add_child(&bullet);
|
||||
}
|
||||
}
|
||||
|
||||
if deal_damage && let Some(target) = target {
|
||||
godot_print!("{}", target.collider);
|
||||
if let Ok(mut player) = target.collider.try_dynify::<dyn IPlayer>() {
|
||||
player.dyn_bind_mut().take_damage(100);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user