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")
|
camera = NodePath("camera_3d")
|
||||||
move_speed = 5.0
|
move_speed = 5.0
|
||||||
soldier_mesh = NodePath("soldier_m")
|
soldier_mesh = NodePath("soldier_m")
|
||||||
|
health = 100
|
||||||
collision_mask = 4
|
collision_mask = 4
|
||||||
|
|
||||||
[node name="camera_3d" type="Camera3D" parent="." unique_id=1773137418]
|
[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")]
|
[node name="player" type="RemotePlayer" unique_id=845968872 node_paths=PackedStringArray("soldier_mesh")]
|
||||||
move_speed = 5.0
|
move_speed = 5.0
|
||||||
soldier_mesh = NodePath("soldier_m")
|
soldier_mesh = NodePath("soldier_m")
|
||||||
|
health = 100
|
||||||
collision_layer = 2
|
collision_layer = 2
|
||||||
collision_mask = 4
|
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);
|
let ray = PhysicsRayQueryParameters3D::create(from, to);
|
||||||
if let Some(mut ray) = ray {
|
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_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);
|
||||||
|
ray.set_exclude(&exclude);
|
||||||
if let Some(world) = world
|
if let Some(world) = world
|
||||||
&& let Some(mut space) = world.get_direct_space_state()
|
&& let Some(mut space) = world.get_direct_space_state()
|
||||||
{
|
{
|
||||||
let results = space.intersect_ray(&ray);
|
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 {
|
Some(RaycastResult {
|
||||||
position: Vector3::from_variant(&position),
|
position: Vector3::from_variant(&position),
|
||||||
|
collider: Gd::from_variant(&collider),
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@ -55,4 +64,5 @@ pub fn cast_ray(from: Vector3, to: Vector3, world: Option<Gd<World3D>>) -> Optio
|
|||||||
|
|
||||||
pub struct RaycastResult {
|
pub struct RaycastResult {
|
||||||
pub position: Vector3,
|
pub position: Vector3,
|
||||||
|
pub collider: Gd<Object>,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -44,6 +44,7 @@ pub trait IPlayer {
|
|||||||
fn get_transform(&self) -> NetPlayerTransform;
|
fn get_transform(&self) -> NetPlayerTransform;
|
||||||
fn jump(&mut self);
|
fn jump(&mut self);
|
||||||
fn try_shoot(&mut self, to: Vector3, deal_damage: bool) -> bool;
|
fn try_shoot(&mut self, to: Vector3, deal_damage: bool) -> bool;
|
||||||
|
fn take_damage(&mut self, damage: i32);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait PlayerMovement {
|
pub trait PlayerMovement {
|
||||||
@ -81,6 +82,8 @@ pub struct LocalPlayer {
|
|||||||
move_speed: f32,
|
move_speed: f32,
|
||||||
#[export]
|
#[export]
|
||||||
soldier_mesh: Option<Gd<SoldierMesh>>,
|
soldier_mesh: Option<Gd<SoldierMesh>>,
|
||||||
|
#[export]
|
||||||
|
health: i32,
|
||||||
|
|
||||||
pub player_id: Option<u16>,
|
pub player_id: Option<u16>,
|
||||||
pub weapon: Option<DynGd<Node3D, dyn Weapon>>,
|
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 {
|
fn try_shoot(&mut self, to: Vector3, deal_damage: bool) -> bool {
|
||||||
if self.shoot_cd <= 0. {
|
if self.shoot_cd <= 0. {
|
||||||
|
let rid = self.base().get_rid();
|
||||||
if let Some(weapon) = &mut self.weapon {
|
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;
|
self.shoot_cd = 0.2;
|
||||||
true
|
true
|
||||||
@ -165,6 +169,11 @@ impl IPlayer for LocalPlayer {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn take_damage(&mut self, damage: i32) {
|
||||||
|
godot_print!("Took damage!");
|
||||||
|
self.health -= damage;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[godot_api]
|
#[godot_api]
|
||||||
@ -225,6 +234,7 @@ impl ICharacterBody3D for LocalPlayer {
|
|||||||
camera.get_global_position(),
|
camera.get_global_position(),
|
||||||
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()]),
|
||||||
) {
|
) {
|
||||||
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.),
|
||||||
@ -233,8 +243,6 @@ impl ICharacterBody3D for LocalPlayer {
|
|||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
godot_print!("{:?}", pos);
|
|
||||||
|
|
||||||
if let Some(pos) = pos {
|
if let Some(pos) = pos {
|
||||||
if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer {
|
if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer {
|
||||||
match peer {
|
match peer {
|
||||||
@ -298,6 +306,8 @@ pub struct RemotePlayer {
|
|||||||
move_speed: f32,
|
move_speed: f32,
|
||||||
#[export]
|
#[export]
|
||||||
soldier_mesh: Option<Gd<SoldierMesh>>,
|
soldier_mesh: Option<Gd<SoldierMesh>>,
|
||||||
|
#[export]
|
||||||
|
health: i32,
|
||||||
|
|
||||||
pub player_id: Option<u16>,
|
pub player_id: Option<u16>,
|
||||||
pub weapon: Option<DynGd<Node3D, dyn Weapon>>,
|
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 {
|
fn try_shoot(&mut self, to: Vector3, deal_damage: bool) -> bool {
|
||||||
if self.shoot_cd <= 0. {
|
if self.shoot_cd <= 0. {
|
||||||
|
let rid = self.base().get_rid();
|
||||||
if let Some(weapon) = &mut self.weapon {
|
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;
|
self.shoot_cd = 0.2;
|
||||||
true
|
true
|
||||||
@ -378,6 +389,11 @@ impl IPlayer for RemotePlayer {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn take_damage(&mut self, damage: i32) {
|
||||||
|
godot_print!("Took damage!");
|
||||||
|
self.health -= damage;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[godot_api]
|
#[godot_api]
|
||||||
|
|||||||
@ -3,10 +3,10 @@ use godot::{
|
|||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::net::util::cast_ray;
|
use crate::{net::util::cast_ray, player::IPlayer};
|
||||||
|
|
||||||
pub trait Weapon {
|
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)]
|
#[derive(GodotClass)]
|
||||||
@ -24,16 +24,22 @@ pub struct Raygun {
|
|||||||
|
|
||||||
#[godot_dyn]
|
#[godot_dyn]
|
||||||
impl Weapon for Raygun {
|
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 {
|
if let Some(emitter) = &mut self.sound_emitter {
|
||||||
emitter.play();
|
emitter.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(source) = &self.bullet_source {
|
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 dir = (to - source.get_global_position()).normalized();
|
||||||
let beam_end = target
|
let beam_end = target
|
||||||
|
.as_ref()
|
||||||
.map(|r| r.position)
|
.map(|r| r.position)
|
||||||
.unwrap_or(source.get_global_position() + dir * 100.);
|
.unwrap_or(source.get_global_position() + dir * 100.);
|
||||||
|
|
||||||
@ -47,6 +53,13 @@ impl Weapon for Raygun {
|
|||||||
parent.add_child(&bullet);
|
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