Add proper shooting effect
This commit is contained in:
parent
dc30551227
commit
79f223cb21
BIN
godot/assets/particle.png
Normal file
BIN
godot/assets/particle.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
41
godot/assets/particle.png.import
Normal file
41
godot/assets/particle.png.import
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://dawgsqbcveewg"
|
||||||
|
path.s3tc="res://.godot/imported/particle.png-5e5e4f76b889a93c8b085c65be799145.s3tc.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/particle.png"
|
||||||
|
dest_files=["res://.godot/imported/particle.png-5e5e4f76b889a93c8b085c65be799145.s3tc.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=2
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=true
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=0
|
||||||
@ -14,7 +14,7 @@ size = Vector2(100, 100)
|
|||||||
[sub_resource type="BoxShape3D" id="BoxShape3D_1cgct"]
|
[sub_resource type="BoxShape3D" id="BoxShape3D_1cgct"]
|
||||||
size = Vector3(100, 0.01, 100)
|
size = Vector3(100, 0.01, 100)
|
||||||
|
|
||||||
[node name="map_0" type="Map" unique_id=914577955 node_paths=PackedStringArray("spawner")]
|
[node name="map" type="Map" unique_id=914577955 node_paths=PackedStringArray("spawner")]
|
||||||
spawner = NodePath("spawner")
|
spawner = NodePath("spawner")
|
||||||
local_player = ExtResource("1_yjvui")
|
local_player = ExtResource("1_yjvui")
|
||||||
remote_player = ExtResource("2_kcncr")
|
remote_player = ExtResource("2_kcncr")
|
||||||
@ -33,8 +33,8 @@ material_override = SubResource("StandardMaterial3D_u8vuu")
|
|||||||
mesh = SubResource("PlaneMesh_1cgct")
|
mesh = SubResource("PlaneMesh_1cgct")
|
||||||
|
|
||||||
[node name="static_body_3d" type="StaticBody3D" parent="terrain" unique_id=203785193]
|
[node name="static_body_3d" type="StaticBody3D" parent="terrain" unique_id=203785193]
|
||||||
collision_layer = 3
|
collision_layer = 7
|
||||||
collision_mask = 3
|
collision_mask = 7
|
||||||
|
|
||||||
[node name="collision_shape_3d" type="CollisionShape3D" parent="terrain/static_body_3d" unique_id=1466526153]
|
[node name="collision_shape_3d" type="CollisionShape3D" parent="terrain/static_body_3d" unique_id=1466526153]
|
||||||
shape = SubResource("BoxShape3D_1cgct")
|
shape = SubResource("BoxShape3D_1cgct")
|
||||||
|
|||||||
@ -4,21 +4,19 @@
|
|||||||
|
|
||||||
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_oh8vq"]
|
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_oh8vq"]
|
||||||
|
|
||||||
[node name="player" type="LocalPlayer" unique_id=863055906 node_paths=PackedStringArray("camera", "soldier_mesh", "sound_emitter")]
|
[node name="player" type="LocalPlayer" unique_id=863055906 node_paths=PackedStringArray("camera", "soldier_mesh")]
|
||||||
look_sensitivity = 1.5
|
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")
|
||||||
sound_emitter = NodePath("")
|
collision_mask = 4
|
||||||
collision_mask = 2
|
|
||||||
|
|
||||||
[node name="camera_3d" type="Camera3D" parent="." unique_id=1773137418]
|
[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)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.8724979, -0.2644562)
|
||||||
current = true
|
current = true
|
||||||
|
|
||||||
[node name="soldier_m" parent="." unique_id=281995630 instance=ExtResource("1_jd651")]
|
[node name="soldier_m" parent="." unique_id=281995630 instance=ExtResource("1_jd651")]
|
||||||
transform = Transform3D(-0.5, 0, -4.371139e-08, 0, 0.5, 0, 4.371139e-08, 0, -0.5, 0, 0, -1.1592964)
|
transform = Transform3D(-0.5, 0, -4.371139e-08, 0, 0.5, 0, 4.371139e-08, 0, -0.5, 0.15878421, 0, 0.19227558)
|
||||||
visible = false
|
|
||||||
|
|
||||||
[node name="collision_shape_3d2" type="CollisionShape3D" parent="." unique_id=442150782]
|
[node name="collision_shape_3d2" type="CollisionShape3D" parent="." unique_id=442150782]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.0310049, 0)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.0310049, 0)
|
||||||
|
|||||||
@ -1,13 +1,19 @@
|
|||||||
[gd_scene format=3 uid="uid://cw7duhhjebypt"]
|
[gd_scene format=3 uid="uid://cw7duhhjebypt"]
|
||||||
|
|
||||||
[ext_resource type="PackedScene" uid="uid://cg81784ct8gf5" path="res://mesh/raygun.tscn" id="1_ckadf"]
|
[ext_resource type="PackedScene" uid="uid://cg81784ct8gf5" path="res://mesh/raygun.tscn" id="1_ckadf"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://ctslratcr8h6v" path="res://scenes/player/raygun_bullet.tscn" id="1_m84jv"]
|
||||||
[ext_resource type="AudioStream" uid="uid://xxpkjhaovyd" path="res://assets/LaserWithRecoveryEdited.ogg" id="2_lxble"]
|
[ext_resource type="AudioStream" uid="uid://xxpkjhaovyd" path="res://assets/LaserWithRecoveryEdited.ogg" id="2_lxble"]
|
||||||
|
|
||||||
[node name="raygun" type="Weapon" unique_id=751705927 node_paths=PackedStringArray("sound_emitter")]
|
[node name="raygun" type="Weapon" unique_id=751705927 node_paths=PackedStringArray("sound_emitter", "bullet_source")]
|
||||||
sound_emitter = NodePath("sound_emitter")
|
sound_emitter = NodePath("sound_emitter")
|
||||||
|
bullet_prefab = ExtResource("1_m84jv")
|
||||||
|
bullet_source = NodePath("bullet_source")
|
||||||
|
|
||||||
[node name="Raygun" parent="." unique_id=1928455392 instance=ExtResource("1_ckadf")]
|
[node name="Raygun" parent="." unique_id=1928455392 instance=ExtResource("1_ckadf")]
|
||||||
|
|
||||||
[node name="sound_emitter" type="AudioStreamPlayer3D" parent="." unique_id=1572422640]
|
[node name="sound_emitter" type="AudioStreamPlayer3D" parent="." unique_id=1572422640]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.8420726, 0)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.8420726, 0)
|
||||||
stream = ExtResource("2_lxble")
|
stream = ExtResource("2_lxble")
|
||||||
|
|
||||||
|
[node name="bullet_source" type="Node3D" parent="." unique_id=211401237]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.36108458, -1.490972)
|
||||||
|
|||||||
40
godot/scenes/player/raygun_bullet.tscn
Normal file
40
godot/scenes/player/raygun_bullet.tscn
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
[gd_scene format=3 uid="uid://ctslratcr8h6v"]
|
||||||
|
|
||||||
|
[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_3g557"]
|
||||||
|
particle_flag_align_y = true
|
||||||
|
radial_velocity_min = -500.0
|
||||||
|
radial_velocity_max = -500.0
|
||||||
|
scale_over_velocity_max = 1.0
|
||||||
|
|
||||||
|
[sub_resource type="Curve" id="Curve_dmbod"]
|
||||||
|
_data = [Vector2(0, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0]
|
||||||
|
point_count = 2
|
||||||
|
|
||||||
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_yxhor"]
|
||||||
|
emission_enabled = true
|
||||||
|
emission = Color(1, 0, 1, 1)
|
||||||
|
emission_energy_multiplier = 4.47
|
||||||
|
use_particle_trails = true
|
||||||
|
|
||||||
|
[sub_resource type="TubeTrailMesh" id="TubeTrailMesh_m77kh"]
|
||||||
|
material = SubResource("StandardMaterial3D_yxhor")
|
||||||
|
sections = 2
|
||||||
|
section_length = 0.5
|
||||||
|
section_rings = 5
|
||||||
|
cap_top = false
|
||||||
|
cap_bottom = false
|
||||||
|
curve = SubResource("Curve_dmbod")
|
||||||
|
|
||||||
|
[node name="raygun_bullet" type="Bullet" unique_id=1238833478 node_paths=PackedStringArray("emitter")]
|
||||||
|
emitter = NodePath("gpu_particles_3d")
|
||||||
|
|
||||||
|
[node name="gpu_particles_3d" type="GPUParticles3D" parent="." unique_id=1330763726]
|
||||||
|
emitting = false
|
||||||
|
amount = 1
|
||||||
|
lifetime = 3.8899999999999997
|
||||||
|
one_shot = true
|
||||||
|
fixed_fps = 100
|
||||||
|
trail_enabled = true
|
||||||
|
trail_lifetime = 0.5
|
||||||
|
process_material = SubResource("ParticleProcessMaterial_3g557")
|
||||||
|
draw_pass_1 = SubResource("TubeTrailMesh_m77kh")
|
||||||
@ -4,11 +4,11 @@
|
|||||||
|
|
||||||
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_1cgct"]
|
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_1cgct"]
|
||||||
|
|
||||||
[node name="player" type="RemotePlayer" unique_id=845968872 node_paths=PackedStringArray("soldier_mesh", "sound_emitter")]
|
[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")
|
||||||
sound_emitter = NodePath("")
|
collision_layer = 2
|
||||||
collision_mask = 2
|
collision_mask = 4
|
||||||
|
|
||||||
[node name="soldier_m" parent="." unique_id=281995630 instance=ExtResource("1_e2ekk")]
|
[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)
|
transform = Transform3D(-0.5, 0, -4.371139e-08, 0, 0.5, 0, 4.371139e-08, 0, -0.5, 0, 0, 0)
|
||||||
|
|||||||
@ -335,12 +335,13 @@ impl Game {
|
|||||||
pub fn handle_shoot(
|
pub fn handle_shoot(
|
||||||
&mut self,
|
&mut self,
|
||||||
player_id: u16,
|
player_id: u16,
|
||||||
|
to: Vector3,
|
||||||
transform: NetPlayerTransform,
|
transform: NetPlayerTransform,
|
||||||
look_up: f32,
|
look_up: f32,
|
||||||
deal_damage: bool,
|
deal_damage: bool,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if let Some(player) = self.find_player_mut(player_id) {
|
if let Some(player) = self.find_player_mut(player_id) {
|
||||||
player.try_shoot(transform, look_up, deal_damage)
|
player.try_shoot(to, transform, look_up, deal_damage)
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
@ -432,6 +433,7 @@ impl Player {
|
|||||||
|
|
||||||
pub fn try_shoot(
|
pub fn try_shoot(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
to: Vector3,
|
||||||
transform: NetPlayerTransform,
|
transform: NetPlayerTransform,
|
||||||
look_up: f32,
|
look_up: f32,
|
||||||
deal_damage: bool,
|
deal_damage: bool,
|
||||||
@ -441,7 +443,7 @@ impl Player {
|
|||||||
.dyn_bind_mut()
|
.dyn_bind_mut()
|
||||||
.apply_rotation(transform.rotation.into());
|
.apply_rotation(transform.rotation.into());
|
||||||
character.dyn_bind_mut().apply_look_up(look_up);
|
character.dyn_bind_mut().apply_look_up(look_up);
|
||||||
character.dyn_bind_mut().try_shoot(true)
|
character.dyn_bind_mut().try_shoot(to, true)
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|||||||
@ -227,10 +227,15 @@ impl INode for NetworkManager {
|
|||||||
game.bind_mut().handle_jump(player_id);
|
game.bind_mut().handle_jump(player_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Package::Shoot(player_id, transform, look_up) => {
|
Package::Shoot(player_id, to, transform, look_up) => {
|
||||||
if let Some(game) = &mut Game::singleton() {
|
if let Some(game) = &mut Game::singleton() {
|
||||||
game.bind_mut()
|
game.bind_mut().handle_shoot(
|
||||||
.handle_shoot(player_id, transform, look_up, false);
|
player_id,
|
||||||
|
to.into(),
|
||||||
|
transform,
|
||||||
|
look_up,
|
||||||
|
false,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
@ -384,7 +389,7 @@ impl INode for NetworkManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Package::Shoot(_, transform, look_up) => {
|
Package::Shoot(_, to, transform, look_up) => {
|
||||||
if let Some(game) = &mut Game::singleton() {
|
if let Some(game) = &mut Game::singleton() {
|
||||||
let player = game
|
let player = game
|
||||||
.bind()
|
.bind()
|
||||||
@ -392,10 +397,14 @@ impl INode for NetworkManager {
|
|||||||
.cloned();
|
.cloned();
|
||||||
if let Some(player) = player {
|
if let Some(player) = player {
|
||||||
if game.bind_mut().handle_shoot(
|
if game.bind_mut().handle_shoot(
|
||||||
player.id, transform, look_up, true,
|
player.id,
|
||||||
|
to.into(),
|
||||||
|
transform,
|
||||||
|
look_up,
|
||||||
|
true,
|
||||||
) {
|
) {
|
||||||
peer.broadcast_reliable(Package::Shoot(
|
peer.broadcast_reliable(Package::Shoot(
|
||||||
player.id, transform, look_up,
|
player.id, to, transform, look_up,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -531,7 +540,7 @@ pub enum Package {
|
|||||||
Sync(HashMap<u16, SyncPackage>),
|
Sync(HashMap<u16, SyncPackage>),
|
||||||
SelfSync(SyncPackage),
|
SelfSync(SyncPackage),
|
||||||
Jump(u16),
|
Jump(u16),
|
||||||
Shoot(u16, NetPlayerTransform, f32),
|
Shoot(u16, NetVector3, NetPlayerTransform, f32),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
use std::f32::consts::PI;
|
use std::{f32::consts::PI, ops::Neg};
|
||||||
|
|
||||||
use godot::{
|
use godot::{
|
||||||
classes::{
|
classes::{
|
||||||
AudioStreamPlayer3D, Camera3D, CharacterBody3D, ICharacterBody3D, Input, InputEvent,
|
AudioStreamPlayer3D, Camera3D, CharacterBody3D, ICharacterBody3D, Input, InputEvent,
|
||||||
InputEventMouseMotion, input::MouseMode,
|
InputEventMouseMotion, PhysicsRayQueryParameters3D, input::MouseMode,
|
||||||
},
|
},
|
||||||
obj::WithBaseField,
|
obj::WithBaseField,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
@ -43,7 +43,7 @@ pub trait IPlayer {
|
|||||||
fn get_look_up(&self) -> f32;
|
fn get_look_up(&self) -> f32;
|
||||||
fn get_transform(&self) -> NetPlayerTransform;
|
fn get_transform(&self) -> NetPlayerTransform;
|
||||||
fn jump(&mut self);
|
fn jump(&mut self);
|
||||||
fn try_shoot(&mut self, deal_damage: bool) -> bool;
|
fn try_shoot(&mut self, to: Vector3, deal_damage: bool) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait PlayerMovement {
|
pub trait PlayerMovement {
|
||||||
@ -154,10 +154,10 @@ impl IPlayer for LocalPlayer {
|
|||||||
|
|
||||||
fn apply_look_up(&mut self, _look: f32) {}
|
fn apply_look_up(&mut self, _look: f32) {}
|
||||||
|
|
||||||
fn try_shoot(&mut self, 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. {
|
||||||
if let Some(weapon) = &mut self.weapon {
|
if let Some(weapon) = &mut self.weapon {
|
||||||
weapon.bind_mut().shoot(Vector3::ZERO, deal_damage);
|
weapon.bind_mut().shoot(to, deal_damage);
|
||||||
}
|
}
|
||||||
self.shoot_cd = 0.2;
|
self.shoot_cd = 0.2;
|
||||||
true
|
true
|
||||||
@ -219,18 +219,56 @@ impl ICharacterBody3D for LocalPlayer {
|
|||||||
fn input(&mut self, event: Gd<InputEvent>) {
|
fn input(&mut self, event: Gd<InputEvent>) {
|
||||||
if self.locked {
|
if self.locked {
|
||||||
if event.is_action_pressed("shoot") {
|
if event.is_action_pressed("shoot") {
|
||||||
if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer {
|
let pos = if let Some(camera) = &self.camera {
|
||||||
match peer {
|
let forward = camera.get_global_basis().col_c().neg();
|
||||||
PeerKind::Client(peer, addr) => {
|
let ray = PhysicsRayQueryParameters3D::create(
|
||||||
peer.send_reliable(addr, Shoot(0, self.get_transform(), self.look_up));
|
camera.get_global_position(),
|
||||||
|
camera.get_global_position() + forward * 10000.,
|
||||||
|
);
|
||||||
|
if let Some(mut ray) = ray {
|
||||||
|
ray.set_collision_mask(0b110);
|
||||||
|
ray.set_hit_back_faces(false);
|
||||||
|
ray.set_hit_from_inside(false);
|
||||||
|
ray.set_collide_with_bodies(true);
|
||||||
|
if let Some(world) = self.base().get_world_3d()
|
||||||
|
&& let Some(mut space) = world.get_direct_space_state()
|
||||||
|
{
|
||||||
|
let results = space.intersect_ray(&ray);
|
||||||
|
if let Some(position) = results.get("position") {
|
||||||
|
Some(Vector3::from_variant(&position))
|
||||||
|
} else {
|
||||||
|
Some(camera.get_global_position() + forward * 100.)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
}
|
}
|
||||||
PeerKind::Server(peer, _) => {
|
} else {
|
||||||
if self.try_shoot(true) {
|
None
|
||||||
peer.broadcast_reliable(Shoot(
|
}
|
||||||
0,
|
} else {
|
||||||
self.get_transform(),
|
None
|
||||||
self.look_up,
|
};
|
||||||
));
|
|
||||||
|
godot_print!("{:?}", pos);
|
||||||
|
|
||||||
|
if let Some(pos) = pos {
|
||||||
|
if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer {
|
||||||
|
match peer {
|
||||||
|
PeerKind::Client(peer, addr) => {
|
||||||
|
peer.send_reliable(
|
||||||
|
addr,
|
||||||
|
Shoot(0, pos.into(), self.get_transform(), self.look_up),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
PeerKind::Server(peer, _) => {
|
||||||
|
if self.try_shoot(pos, true) {
|
||||||
|
peer.broadcast_reliable(Shoot(
|
||||||
|
0,
|
||||||
|
pos.into(),
|
||||||
|
self.get_transform(),
|
||||||
|
self.look_up,
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -343,10 +381,10 @@ impl IPlayer for RemotePlayer {
|
|||||||
self.look_up = look;
|
self.look_up = look;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_shoot(&mut self, 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. {
|
||||||
if let Some(weapon) = &mut self.weapon {
|
if let Some(weapon) = &mut self.weapon {
|
||||||
weapon.bind_mut().shoot(Vector3::ZERO, deal_damage);
|
weapon.bind_mut().shoot(to, deal_damage);
|
||||||
}
|
}
|
||||||
self.shoot_cd = 0.2;
|
self.shoot_cd = 0.2;
|
||||||
true
|
true
|
||||||
|
|||||||
@ -1,10 +1,17 @@
|
|||||||
use godot::{classes::AudioStreamPlayer3D, prelude::*};
|
use godot::{
|
||||||
|
classes::{AudioStreamPlayer3D, GpuParticles3D, PhysicsRayQueryParameters3D},
|
||||||
|
prelude::*,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(GodotClass)]
|
#[derive(GodotClass)]
|
||||||
#[class(base=Node3D, init)]
|
#[class(base=Node3D, init)]
|
||||||
pub struct Weapon {
|
pub struct Weapon {
|
||||||
#[export]
|
#[export]
|
||||||
sound_emitter: Option<Gd<AudioStreamPlayer3D>>,
|
sound_emitter: Option<Gd<AudioStreamPlayer3D>>,
|
||||||
|
#[export]
|
||||||
|
bullet_prefab: Option<Gd<PackedScene>>,
|
||||||
|
#[export]
|
||||||
|
bullet_source: Option<Gd<Node3D>>,
|
||||||
|
|
||||||
base: Base<Node3D>,
|
base: Base<Node3D>,
|
||||||
}
|
}
|
||||||
@ -14,5 +21,50 @@ impl Weapon {
|
|||||||
if let Some(emitter) = &mut self.sound_emitter {
|
if let Some(emitter) = &mut self.sound_emitter {
|
||||||
emitter.play();
|
emitter.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(prefab) = &self.bullet_prefab {
|
||||||
|
let mut bullet = prefab.instantiate_as::<Bullet>();
|
||||||
|
if let Some(mut parent) = self.base().find_parent("map") {
|
||||||
|
parent.add_child(&bullet);
|
||||||
|
if let Some(source) = &self.bullet_source {
|
||||||
|
bullet.set_global_position(source.get_global_position());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bullet.bind_mut().target = Some(to);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(GodotClass)]
|
||||||
|
#[class(base=Node3D, init)]
|
||||||
|
pub struct Bullet {
|
||||||
|
#[export]
|
||||||
|
pub emitter: Option<Gd<GpuParticles3D>>,
|
||||||
|
|
||||||
|
pub target: Option<Vector3>,
|
||||||
|
|
||||||
|
alive_for: f64,
|
||||||
|
|
||||||
|
base: Base<Node3D>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[godot_api]
|
||||||
|
impl INode3D for Bullet {
|
||||||
|
fn ready(&mut self) {
|
||||||
|
if let Some(emitter) = &mut self.emitter {
|
||||||
|
emitter.set_emitting(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn process(&mut self, delta: f64) {
|
||||||
|
self.alive_for += delta;
|
||||||
|
if self.alive_for > 0.05 {
|
||||||
|
let prev_pos = self.base().get_global_position();
|
||||||
|
|
||||||
|
if let Some(target) = self.target {
|
||||||
|
let new_pos = prev_pos.lerp(target, 0.5);
|
||||||
|
self.base_mut().set_position(new_pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user