Add arrow that is visible on ball and player holding ball

This commit is contained in:
Sofia 2026-07-30 23:44:34 +03:00
parent 845fa4ea6e
commit ab4d3ed849
13 changed files with 200 additions and 5 deletions

BIN
godot/assets/Arrow.fbx Normal file

Binary file not shown.

View File

@ -0,0 +1,46 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://menoxw82ftvs"
path="res://.godot/imported/Arrow.fbx-6f0fbbfeb10245e69032bac7eca9b96f.scn"
[deps]
source_file="res://assets/Arrow.fbx"
dest_files=["res://.godot/imported/Arrow.fbx-6f0fbbfeb10245e69032bac7eca9b96f.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/root_script=null
mesh_library/use_node_names_as_mesh_names=false
array_mesh/deduplicate_surfaces=true
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
nodes/use_name_suffixes=true
nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=true
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
materials/extract=0
materials/extract_format=0
materials/extract_path=""
_subresources={}
fbx/importer=0
fbx/allow_geometry_helper_nodes=false
fbx/embedded_image_handling=1
fbx/naming_version=2

15
godot/mesh/arrow.tscn Normal file
View File

@ -0,0 +1,15 @@
[gd_scene format=3 uid="uid://d1audvg1rgiil"]
[ext_resource type="PackedScene" uid="uid://menoxw82ftvs" path="res://assets/Arrow.fbx" id="1_5xuuv"]
[ext_resource type="Shader" uid="uid://dvevqws3wm717" path="res://shaders/arrow_shader.tres" id="2_jlas5"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_y75oq"]
render_priority = 0
shader = ExtResource("2_jlas5")
shader_parameter/ColorParameter = Color(0, 0, 1, 1)
shader_parameter/MaxDistance = 40.0
[node name="Arrow" unique_id=2098940646 instance=ExtResource("1_5xuuv")]
[node name="Cube" parent="." index="0" unique_id=1659384323]
surface_material_override/0 = SubResource("ShaderMaterial_y75oq")

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,9 @@
[gd_scene format=3 uid="uid://bnha3gon4700q"]
[ext_resource type="PackedScene" uid="uid://d1audvg1rgiil" path="res://mesh/arrow.tscn" id="1_w20fr"]
[node name="arrow" type="Arrow" unique_id=1231591993 node_paths=PackedStringArray("mesh")]
mesh = NodePath("Arrow")
[node name="Arrow" parent="." unique_id=2098940646 instance=ExtResource("1_w20fr")]
transform = Transform3D(0.8991433, 0, -0.43765438, 0, 1, 0, 0.43765438, 0, 0.8991433, 0, -0.07870276, 0)

View File

@ -11,6 +11,7 @@
[ext_resource type="AudioStream" uid="uid://ca2x04htf0mpi" path="res://raw_assets/sfx/ball/7.ogg" id="8_xuvta"]
[ext_resource type="AudioStream" uid="uid://ba5rkh12mwy7o" path="res://raw_assets/sfx/ball/8.ogg" id="9_yu13l"]
[ext_resource type="AudioStream" uid="uid://0vmjtq6uxsqe" path="res://raw_assets/sfx/ball/9.ogg" id="10_p4exv"]
[ext_resource type="PackedScene" uid="uid://bnha3gon4700q" path="res://scenes/misc/arrow.tscn" id="12_of30w"]
[sub_resource type="SphereShape3D" id="SphereShape3D_1cgct"]
@ -44,3 +45,5 @@ bus = &"SFX"
[node name="SkeletonHead" parent="." unique_id=1848024401 instance=ExtResource("3_thun5")]
transform = Transform3D(0.45, 0, 0, 0, 0.45, 0, 0, 0, 0.45, 0, 0, -0.046112746)
[node name="arrow" parent="." unique_id=1231591993 instance=ExtResource("12_of30w")]

View File

@ -4,6 +4,7 @@
[ext_resource type="PackedScene" uid="uid://cl66unms2gim0" path="res://scenes/player/effects.tscn" id="2_orxjf"]
[ext_resource type="AudioStream" uid="uid://cl416orgv11vj" path="res://raw_assets/sfx/ball/little_robot_sound_factory_fantasy_Inventory_Open_00.mp3" id="3_840kl"]
[ext_resource type="AudioStream" uid="uid://uq0o8gkpqhfa" path="res://raw_assets/sfx/ball/zapsplat_foley_stick_swing_air_whoosh_very_fast_hard_003_110413.mp3" id="4_qn18y"]
[ext_resource type="PackedScene" uid="uid://bnha3gon4700q" path="res://scenes/misc/arrow.tscn" id="5_qn18y"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_1cgct"]
@ -37,7 +38,7 @@ curve = SubResource("Curve_qn18y")
[sub_resource type="ViewportTexture" id="ViewportTexture_rmxnb"]
viewport_path = NodePath("double_health_bar_sprite/health_bar_viewport")
[node name="player" type="RemotePlayer" unique_id=845968872 node_paths=PackedStringArray("soldier_mesh", "collider", "effects", "spectator_camera", "camera_origin", "name_label", "health_bar", "double_health_bar", "health_bar_sprite", "double_health_bar_sprite", "ball_pickup_sfx", "ball_throw_sfx")]
[node name="player" type="RemotePlayer" unique_id=845968872 node_paths=PackedStringArray("soldier_mesh", "collider", "effects", "spectator_camera", "camera_origin", "name_label", "health_bar", "double_health_bar", "health_bar_sprite", "double_health_bar_sprite", "ball_pickup_sfx", "ball_throw_sfx", "arrow")]
move_speed = 7.0
soldier_mesh = NodePath("soldier_m")
collider = NodePath("collision_shape_3d")
@ -53,6 +54,7 @@ health_bar_sprite = NodePath("health_bar_sprite")
double_health_bar_sprite = NodePath("double_health_bar_sprite")
ball_pickup_sfx = NodePath("ball_pickup_sfx")
ball_throw_sfx = NodePath("ball_throw_sfx")
arrow = NodePath("arrow")
telegrenade_cd = 10.0
collision_layer = 2
collision_mask = 4
@ -140,3 +142,6 @@ bus = &"SFX"
[node name="ball_throw_sfx" type="AudioStreamPlayer3D" parent="." unique_id=198255565]
stream = ExtResource("4_qn18y")
bus = &"SFX"
[node name="arrow" parent="." unique_id=1231591993 instance=ExtResource("5_qn18y")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.6812112, 0)

View File

@ -4,6 +4,7 @@
[ext_resource type="PackedScene" uid="uid://cl66unms2gim0" path="res://scenes/player/effects.tscn" id="2_rejks"]
[ext_resource type="AudioStream" uid="uid://cl416orgv11vj" path="res://raw_assets/sfx/ball/little_robot_sound_factory_fantasy_Inventory_Open_00.mp3" id="3_o85ek"]
[ext_resource type="AudioStream" uid="uid://uq0o8gkpqhfa" path="res://raw_assets/sfx/ball/zapsplat_foley_stick_swing_air_whoosh_very_fast_hard_003_110413.mp3" id="4_fwayu"]
[ext_resource type="PackedScene" uid="uid://bnha3gon4700q" path="res://scenes/misc/arrow.tscn" id="5_fwayu"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_1cgct"]
@ -37,7 +38,7 @@ curve = SubResource("Curve_qn18y")
[sub_resource type="ViewportTexture" id="ViewportTexture_bfcd3"]
viewport_path = NodePath("double_health_bar_sprite/double_health_bar_viewport")
[node name="player" type="RemotePlayer" unique_id=845968872 node_paths=PackedStringArray("soldier_mesh", "collider", "effects", "spectator_camera", "camera_origin", "name_label", "health_bar", "double_health_bar", "health_bar_sprite", "double_health_bar_sprite", "ball_pickup_sfx", "ball_throw_sfx")]
[node name="player" type="RemotePlayer" unique_id=845968872 node_paths=PackedStringArray("soldier_mesh", "collider", "effects", "spectator_camera", "camera_origin", "name_label", "health_bar", "double_health_bar", "health_bar_sprite", "double_health_bar_sprite", "ball_pickup_sfx", "ball_throw_sfx", "arrow")]
move_speed = 5.0
soldier_mesh = NodePath("soldier_m")
collider = NodePath("collision_shape_3d")
@ -53,6 +54,7 @@ health_bar_sprite = NodePath("health_bar_sprite")
double_health_bar_sprite = NodePath("double_health_bar_sprite")
ball_pickup_sfx = NodePath("ball_pickup_sfx")
ball_throw_sfx = NodePath("ball_throw_sfx")
arrow = NodePath("arrow")
collision_layer = 16
collision_mask = 4
@ -137,3 +139,6 @@ bus = &"SFX"
[node name="ball_throw_sfx" type="AudioStreamPlayer3D" parent="." unique_id=1825805271]
stream = ExtResource("4_fwayu")
bus = &"SFX"
[node name="arrow" parent="." unique_id=1231591993 instance=ExtResource("5_fwayu")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.6812112, 0)

View File

@ -0,0 +1,70 @@
[gd_resource type="VisualShader" format=3 uid="uid://dvevqws3wm717"]
[sub_resource type="VisualShaderNodeColorParameter" id="VisualShaderNodeColorParameter_lero3"]
parameter_name = "ColorParameter"
default_value_enabled = true
[sub_resource type="VisualShaderNodeFloatOp" id="VisualShaderNodeFloatOp_krsme"]
default_input_values = [0, 0.0, 1, 1.0]
operator = 7
[sub_resource type="VisualShaderNodeInput" id="VisualShaderNodeInput_krsme"]
input_name = "camera_position_world"
[sub_resource type="VisualShaderNodeInput" id="VisualShaderNodeInput_ed1nm"]
input_name = "vertex"
[sub_resource type="VisualShaderNodeVectorOp" id="VisualShaderNodeVectorOp_j5yvs"]
operator = 1
[sub_resource type="VisualShaderNodeVectorDistance" id="VisualShaderNodeVectorDistance_511aq"]
[sub_resource type="VisualShaderNodeFloatOp" id="VisualShaderNodeFloatOp_uhsfa"]
default_input_values = [0, 0.0, 1, 30.0]
operator = 3
[sub_resource type="VisualShaderNodeFloatOp" id="VisualShaderNodeFloatOp_mkhfx"]
default_input_values = [0, 0.0, 1, 10.0]
operator = 1
[sub_resource type="VisualShaderNodeFloatOp" id="VisualShaderNodeFloatOp_7bf0g"]
operator = 6
[sub_resource type="VisualShaderNodeFloatParameter" id="VisualShaderNodeFloatParameter_jxonh"]
parameter_name = "MaxDistance"
default_value_enabled = true
default_value = 100.0
[sub_resource type="VisualShaderNodeInput" id="VisualShaderNodeInput_lero3"]
input_name = "vertex"
[resource]
flags/depth_test_disabled = true
flags/unshaded = true
flags/world_vertex_coords = true
nodes/vertex/0/position = Vector2(630, 150)
nodes/vertex/2/node = SubResource("VisualShaderNodeInput_lero3")
nodes/vertex/2/position = Vector2(307.9943, 117.82249)
nodes/vertex/connections = PackedInt32Array(2, 0, 0, 0)
nodes/fragment/0/position = Vector2(1000, 110)
nodes/fragment/2/node = SubResource("VisualShaderNodeInput_krsme")
nodes/fragment/2/position = Vector2(-890, 120)
nodes/fragment/3/node = SubResource("VisualShaderNodeInput_ed1nm")
nodes/fragment/3/position = Vector2(-890, -10)
nodes/fragment/4/node = SubResource("VisualShaderNodeVectorOp_j5yvs")
nodes/fragment/4/position = Vector2(-550, -30)
nodes/fragment/5/node = SubResource("VisualShaderNodeVectorDistance_511aq")
nodes/fragment/5/position = Vector2(-360, 0)
nodes/fragment/6/node = SubResource("VisualShaderNodeFloatOp_uhsfa")
nodes/fragment/6/position = Vector2(400, 150)
nodes/fragment/7/node = SubResource("VisualShaderNodeFloatOp_mkhfx")
nodes/fragment/7/position = Vector2(-80, 100)
nodes/fragment/8/node = SubResource("VisualShaderNodeFloatOp_7bf0g")
nodes/fragment/8/position = Vector2(120, 100)
nodes/fragment/9/node = SubResource("VisualShaderNodeFloatParameter_jxonh")
nodes/fragment/9/position = Vector2(-460, 310)
nodes/fragment/11/node = SubResource("VisualShaderNodeColorParameter_lero3")
nodes/fragment/11/position = Vector2(310, -110)
nodes/fragment/12/node = SubResource("VisualShaderNodeFloatOp_krsme")
nodes/fragment/12/position = Vector2(690, 190)
nodes/fragment/connections = PackedInt32Array(3, 0, 4, 0, 2, 0, 4, 1, 4, 0, 5, 0, 5, 0, 7, 0, 7, 0, 8, 0, 8, 0, 6, 0, 9, 0, 7, 1, 11, 0, 0, 0, 6, 0, 12, 0, 12, 0, 0, 1)

28
rust/src/arrow.rs Normal file
View File

@ -0,0 +1,28 @@
use godot::{classes::MeshInstance3D, prelude::*};
#[derive(GodotClass)]
#[class(base=Node3D, init, tool)]
pub struct Arrow {
#[export]
mesh: Option<Gd<Node3D>>,
elapsed: f64,
base: Base<Node3D>,
}
#[godot_api]
impl INode3D for Arrow {
fn process(&mut self, delta: f64) {
self.elapsed += delta;
let global_pos = self.base().get_global_position();
if let Some(mesh) = &mut self.mesh {
mesh.set_global_position(
global_pos
+ Vector3::UP * 2.
+ Vector3::UP * (self.elapsed * 2.).sin() as f32 / 10.,
);
mesh.set_global_rotation(Vector3::UP * self.elapsed as f32);
}
}
}

View File

@ -1,6 +1,7 @@
use godot::prelude::*;
pub mod announcer;
pub mod arrow;
pub mod bgm;
pub mod chat;
pub mod cli_parser;

View File

@ -55,6 +55,8 @@ pub struct RemotePlayer {
ball_pickup_sfx: Option<Gd<AudioStreamPlayer3D>>,
#[export]
ball_throw_sfx: Option<Gd<AudioStreamPlayer3D>>,
#[export]
arrow: Option<Gd<Node3D>>,
pub player_id: Option<u16>,
pub player_name: String,
@ -238,19 +240,26 @@ impl IPlayer for RemotePlayer {
self.drop_ball(true);
}
if let Some(arrow) = &mut self.arrow {
arrow.set_visible(false);
}
if let Some(mesh) = &mut self.soldier_mesh {
match weapon {
WeaponType::Raygun => {
mesh.bind_mut().spawn_raygun();
if let Some(ball_pickup_sfx) = &mut self.ball_pickup_sfx {
ball_pickup_sfx.play();
}
}
WeaponType::Shotgun => {
mesh.bind_mut().spawn_shotgun();
}
WeaponType::Ball => {
mesh.bind_mut().spawn_ball();
if let Some(ball_pickup_sfx) = &mut self.ball_pickup_sfx {
ball_pickup_sfx.play();
}
if let Some(arrow) = &mut self.arrow {
arrow.set_visible(true);
}
}
};
}
@ -373,6 +382,10 @@ impl ICharacterBody3D for RemotePlayer {
};
});
if let Some(arrow) = &mut self.arrow {
arrow.set_visible(false);
}
self.buffs.clone().update_effects(self);
}