From 98c0177df2354499aa5e0d6eed94173576cc38f1 Mon Sep 17 00:00:00 2001 From: Spencer Killen Date: Sun, 11 Dec 2022 17:02:57 -0700 Subject: [PATCH] Tuning player controller --- attribution.txt | 2 + ...p.ogg-3b8796f7d662533b21e4e04538fd4489.md5 | 3 + ...gg-3b8796f7d662533b21e4e04538fd4489.oggstr | Bin 0 -> 7811 bytes ...s.ogg-bd82bbc47e039725c74abd2d8e837e83.md5 | 3 + ...gg-bd82bbc47e039725c74abd2d8e837e83.oggstr | Bin 0 -> 20423 bytes .../388019__saturdaysoundguy__celery-snap.ogg | 3 + ...__saturdaysoundguy__celery-snap.ogg.import | 15 ++ ...4327__pfranzen__male-grunts-and-groans.ogg | 3 + ...franzen__male-grunts-and-groans.ogg.import | 15 ++ godot/effects/player/MovementSounds.gd | 50 ----- .../player/MovementSoundsAnimations.gd | 61 ++++++ ...nds.tscn => MovementSoundsAnimations.tscn} | 14 +- godot/player/CloseToFloor.gd | 8 +- godot/player/HighSpeedFOV.gd | 18 +- godot/player/OnFootPhysics.gd | 24 ++- godot/player/Overlay.gd | 8 +- godot/player/player.tscn | 181 ++++++++++++++++-- godot/tests/falling/test_falling.tscn | 2 +- 18 files changed, 317 insertions(+), 93 deletions(-) create mode 100644 godot/.import/388019__saturdaysoundguy__celery-snap.ogg-3b8796f7d662533b21e4e04538fd4489.md5 create mode 100644 godot/.import/388019__saturdaysoundguy__celery-snap.ogg-3b8796f7d662533b21e4e04538fd4489.oggstr create mode 100644 godot/.import/404327__pfranzen__male-grunts-and-groans.ogg-bd82bbc47e039725c74abd2d8e837e83.md5 create mode 100644 godot/.import/404327__pfranzen__male-grunts-and-groans.ogg-bd82bbc47e039725c74abd2d8e837e83.oggstr create mode 100644 godot/assets/audio/388019__saturdaysoundguy__celery-snap.ogg create mode 100644 godot/assets/audio/388019__saturdaysoundguy__celery-snap.ogg.import create mode 100644 godot/assets/audio/404327__pfranzen__male-grunts-and-groans.ogg create mode 100644 godot/assets/audio/404327__pfranzen__male-grunts-and-groans.ogg.import delete mode 100644 godot/effects/player/MovementSounds.gd create mode 100644 godot/effects/player/MovementSoundsAnimations.gd rename godot/effects/player/{MovementSounds.tscn => MovementSoundsAnimations.tscn} (55%) diff --git a/attribution.txt b/attribution.txt index f9aaf0c..9beec32 100644 --- a/attribution.txt +++ b/attribution.txt @@ -3,4 +3,6 @@ https://freesound.org/people/davidou/sounds/88449/ https://freesound.org/people/DanJFilms/sounds/529388/ https://freesound.org/people/InspectorJ/sounds/485420/ https://freesound.org/people/deadrobotmusic/sounds/555462/ +https://freesound.org/people/saturdaysoundguy/sounds/388019/ +https://freesound.org/people/pfranzen/sounds/404327/ diff --git a/godot/.import/388019__saturdaysoundguy__celery-snap.ogg-3b8796f7d662533b21e4e04538fd4489.md5 b/godot/.import/388019__saturdaysoundguy__celery-snap.ogg-3b8796f7d662533b21e4e04538fd4489.md5 new file mode 100644 index 0000000..533598c --- /dev/null +++ b/godot/.import/388019__saturdaysoundguy__celery-snap.ogg-3b8796f7d662533b21e4e04538fd4489.md5 @@ -0,0 +1,3 @@ +source_md5="95d19e3b9268e91ea5d793017c0d222c" +dest_md5="e115a0a023d3922072383d9ef1f22a64" + diff --git a/godot/.import/388019__saturdaysoundguy__celery-snap.ogg-3b8796f7d662533b21e4e04538fd4489.oggstr b/godot/.import/388019__saturdaysoundguy__celery-snap.ogg-3b8796f7d662533b21e4e04538fd4489.oggstr new file mode 100644 index 0000000000000000000000000000000000000000..c0e15c1a928d7739ef2920d29122cd7c3e7c3a5b GIT binary patch literal 7811 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 literal 0 HcmV?d00001 diff --git a/godot/.import/404327__pfranzen__male-grunts-and-groans.ogg-bd82bbc47e039725c74abd2d8e837e83.md5 b/godot/.import/404327__pfranzen__male-grunts-and-groans.ogg-bd82bbc47e039725c74abd2d8e837e83.md5 new file mode 100644 index 0000000..a7f79d8 --- /dev/null +++ b/godot/.import/404327__pfranzen__male-grunts-and-groans.ogg-bd82bbc47e039725c74abd2d8e837e83.md5 @@ -0,0 +1,3 @@ +source_md5="89a03bae3f5ffd821efdace8669d5da0" +dest_md5="9ae0b2b7946df84de32a3125c1171cae" + diff --git a/godot/.import/404327__pfranzen__male-grunts-and-groans.ogg-bd82bbc47e039725c74abd2d8e837e83.oggstr b/godot/.import/404327__pfranzen__male-grunts-and-groans.ogg-bd82bbc47e039725c74abd2d8e837e83.oggstr new file mode 100644 index 0000000000000000000000000000000000000000..2214528314c80259b4494428f5c4505574567c2b GIT binary patch literal 20423 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 0.0: - return - - $Footsteps.pitch_scale = rand_range(0.9, 1.1) - $Footsteps.play() - - var is_sprinting = $"../MovementInput".sprinting - - if is_sprinting: - $Footsteps/Timer.start(0.3) - else: - $Footsteps/Timer.start(0.5) - - -func _process(_delta): - if $"..".is_on_foot(): - jump() - footsteps() diff --git a/godot/effects/player/MovementSoundsAnimations.gd b/godot/effects/player/MovementSoundsAnimations.gd new file mode 100644 index 0000000..36155eb --- /dev/null +++ b/godot/effects/player/MovementSoundsAnimations.gd @@ -0,0 +1,61 @@ +extends Node + +var played_takeoff: bool = false +var falling: bool = false + +func jump(): + var phys = $"../OnFootPhysics" + var on_floor = $"../OnFootPhysics/Floor".is_on_floor + var jump_intent = $"../MovementInput".jump_intent + + if jump_intent and not on_floor and not played_takeoff: + $Jump.play() + played_takeoff = true + + if phys.just_landed: + $Jump.stop() + played_takeoff = false + if $"../OnFootPhysics".velocity.y < -3.0 and not $CameraAnimation.is_playing(): + $CameraAnimation.play("jump_landing") + var landing_playing = $JumpLanding.playing or $JumpLandingHardCrunch.playing or $JumpLandingHardOuch.playing + if not landing_playing: + if not phys.just_landed_terminally: + print("a") + $JumpLanding.play() + else: + print("b") + $JumpLandingHardCrunch.play() + $JumpLandingHardOuch.play() + + if not on_floor and phys.is_falling_velocity_terminal() and not $FallingSound.playing: + $FallingSound.play() + $FallingSound.pitch_scale = rand_range(0.8, 1.2) + elif on_floor: + $FallingSound.stop() + + +func footsteps(): + var on_floor = $"../OnFootPhysics/Floor".is_on_floor + var velocity = $"../MovementInput".input_xz + + if not on_floor or velocity.length() == 0: + $Footsteps.stop() + return + if $Footsteps/Timer.time_left > 0.0: + return + + $Footsteps.pitch_scale = rand_range(0.9, 1.1) + $Footsteps.play() + + var is_sprinting = $"../MovementInput".sprinting + + if is_sprinting: + $Footsteps/Timer.start(0.3) + else: + $Footsteps/Timer.start(0.5) + + +func _process(_delta): + if $"..".is_on_foot(): + jump() + footsteps() diff --git a/godot/effects/player/MovementSounds.tscn b/godot/effects/player/MovementSoundsAnimations.tscn similarity index 55% rename from godot/effects/player/MovementSounds.tscn rename to godot/effects/player/MovementSoundsAnimations.tscn index ecf9117..cc36921 100644 --- a/godot/effects/player/MovementSounds.tscn +++ b/godot/effects/player/MovementSoundsAnimations.tscn @@ -1,11 +1,13 @@ -[gd_scene load_steps=5 format=2] +[gd_scene load_steps=7 format=2] -[ext_resource path="res://effects/player/MovementSounds.gd" type="Script" id=1] +[ext_resource path="res://effects/player/MovementSoundsAnimations.gd" type="Script" id=1] [ext_resource path="res://assets/FootstepSfx/Steps_water-003.ogg" type="AudioStream" id=2] [ext_resource path="res://assets/FootstepSfx/Steps_water-016.ogg" type="AudioStream" id=3] [ext_resource path="res://assets/audio/falling_wind.mp3" type="AudioStream" id=4] +[ext_resource path="res://assets/audio/388019__saturdaysoundguy__celery-snap.ogg" type="AudioStream" id=5] +[ext_resource path="res://assets/audio/404327__pfranzen__male-grunts-and-groans.ogg" type="AudioStream" id=6] -[node name="MovementSounds" type="Node"] +[node name="MovementSoundsAnimations" type="Node"] script = ExtResource( 1 ) [node name="Footsteps" type="AudioStreamPlayer" parent="."] @@ -21,5 +23,11 @@ stream = ExtResource( 3 ) [node name="JumpLanding" type="AudioStreamPlayer" parent="."] stream = ExtResource( 3 ) +[node name="JumpLandingHardCrunch" type="AudioStreamPlayer" parent="."] +stream = ExtResource( 5 ) + +[node name="JumpLandingHardOuch" type="AudioStreamPlayer" parent="."] +stream = ExtResource( 6 ) + [node name="FallingSound" type="AudioStreamPlayer" parent="."] stream = ExtResource( 4 ) diff --git a/godot/player/CloseToFloor.gd b/godot/player/CloseToFloor.gd index 6904f11..26e1d72 100644 --- a/godot/player/CloseToFloor.gd +++ b/godot/player/CloseToFloor.gd @@ -2,12 +2,16 @@ extends RayCast var is_on_floor = false var floor_distance = 0.0 +export var min_floor_distance = 0.5 func _process(_delta): force_raycast_update(); if is_colliding(): - is_on_floor = true; var point = get_collision_point(); floor_distance = to_local(point).length(); + if floor_distance < min_floor_distance: + is_on_floor = true + else: + is_on_floor = false else: - is_on_floor = false; + is_on_floor = false diff --git a/godot/player/HighSpeedFOV.gd b/godot/player/HighSpeedFOV.gd index eabe6ce..d422b26 100644 --- a/godot/player/HighSpeedFOV.gd +++ b/godot/player/HighSpeedFOV.gd @@ -1,18 +1,10 @@ extends Node -onready var camera = get_parent() onready var OnFootPhysics = get_node("../../../../../OnFootPhysics") -onready var default_fov = camera.fov -onready var max_fov = default_fov + 20 -var min_speed = 0.5 +onready var Floor = get_node("../../../../../OnFootPhysics/Floor") -# Commenting out code only addresses falling, but FOV should also change a bit when sprinting. func _process(_delta): - pass - #if OnFootPhysics.velocity.y >= 0.0: - # - # return - #var terminal_velocity = -OnFootPhysics.get_terminal_falling_velocity() - #var speed = -OnFootPhysics.velocity.y - #var weight = (terminal_velocity - speed) / (terminal_velocity - min_speed) - #camera.fov = lerp(max_fov, default_fov, weight) + if OnFootPhysics.velocity.y >= 0.0 or Floor.is_on_floor: + $FOVAnimation.play("RESET") + return + $FOVAnimation.play("fov") diff --git a/godot/player/OnFootPhysics.gd b/godot/player/OnFootPhysics.gd index 84f963c..d510389 100644 --- a/godot/player/OnFootPhysics.gd +++ b/godot/player/OnFootPhysics.gd @@ -23,14 +23,17 @@ var velocity_factor: Vector3 = Vector3.ONE var target_velocity: Vector3 = Vector3.ZERO var is_jumping: bool = false var jump_permission: float = 1.0 +var is_falling: bool = false +var is_falling_terminally: bool = false +var just_landed: bool = false +var just_landed_terminally: bool = false func get_terminal_falling_velocity(): - return -gravity * .5 + return -9 func is_falling_velocity_terminal(): return velocity.y <= get_terminal_falling_velocity() - func process_velocity(delta: float): # Uses the input from MovementInput to compute and update this node's velocity # velocity_acceleration controls gradual speedup whereas velocity_friction @@ -52,6 +55,8 @@ func process_velocity(delta: float): elif is_jumping and $"../MovementInput".jump_intent == 0.0: jump_permission = 1.0 is_jumping = false + + var target_velocity_xz = $"../MovementInput".input_xz @@ -84,6 +89,20 @@ func process_velocity(delta: float): velocity = util.vec2_xz_to_vec3(velocity_xz, velocity_y) * velocity_factor +func process_falling(): + if not $Floor.is_on_floor: + is_falling = true + just_landed = false + just_landed_terminally = false + if is_falling_velocity_terminal(): + is_falling_terminally = true + return + just_landed = is_falling + just_landed_terminally = is_falling_terminally + is_falling = false + is_falling_terminally = false + + func increase_velocity_factor(by: Vector3): velocity_factor *= by @@ -94,3 +113,4 @@ func _physics_process(delta): process_velocity(delta) velocity = move_and_slide(velocity, Vector3.UP) + process_falling() diff --git a/godot/player/Overlay.gd b/godot/player/Overlay.gd index 5c10d9c..8a8ae2f 100644 --- a/godot/player/Overlay.gd +++ b/godot/player/Overlay.gd @@ -7,15 +7,11 @@ onready var OnFootPhysics = get_node("../OnFootPhysics") var will_fall_hard = false func _ready(): - $HurtScreen.visible = false + $HurtScreen.modulate.a = 0.0 func _process(_delta): if OnFootPhysics.is_falling_velocity_terminal(): will_fall_hard = true if will_fall_hard and OnFootPhysics.is_on_floor(): will_fall_hard = false - $HurtScreen.visible = true - $HurtScreen/Timer.start(1) - -func _on_Timer_timeout(): - $HurtScreen.visible = false + $HurtScreen/HurtScreenOpacityAnimation.play("opacity") diff --git a/godot/player/player.tscn b/godot/player/player.tscn index 2c23d0d..c76cced 100644 --- a/godot/player/player.tscn +++ b/godot/player/player.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=19 format=2] +[gd_scene load_steps=28 format=2] [ext_resource path="res://player/CameraController.gd" type="Script" id=1] [ext_resource path="res://player/OnFootPhysics.gd" type="Script" id=2] @@ -8,21 +8,146 @@ [ext_resource path="res://player/PlatformMechanics.gd" type="Script" id=6] [ext_resource path="res://player/ElevatorPhysics.gd" type="Script" id=7] [ext_resource path="res://effects/player/Flashlight.tscn" type="PackedScene" id=8] -[ext_resource path="res://effects/player/MovementSounds.tscn" type="PackedScene" id=9] +[ext_resource path="res://assets/audio/388019__saturdaysoundguy__celery-snap.ogg" type="AudioStream" id=9] [ext_resource path="res://player/CloseToFloor.gd" type="Script" id=10] [ext_resource path="res://player/HighSpeedFOV.gd" type="Script" id=11] [ext_resource path="res://player/Overlay.gd" type="Script" id=12] [ext_resource path="res://assets/BloodMush.png" type="Texture" id=13] [ext_resource path="res://assets/models/walkie_talkie/walkie_talkie.tscn" type="PackedScene" id=14] +[ext_resource path="res://assets/FootstepSfx/Steps_water-016.ogg" type="AudioStream" id=15] +[ext_resource path="res://assets/audio/falling_wind.mp3" type="AudioStream" id=16] +[ext_resource path="res://assets/FootstepSfx/Steps_water-003.ogg" type="AudioStream" id=17] +[ext_resource path="res://assets/audio/404327__pfranzen__male-grunts-and-groans.ogg" type="AudioStream" id=18] +[ext_resource path="res://effects/player/MovementSoundsAnimations.gd" type="Script" id=19] -[sub_resource type="AnimationNodeStateMachine" id=2] +[sub_resource type="Animation" id=8] +length = 0.001 +tracks/0/type = "value" +tracks/0/path = NodePath("..:fov") +tracks/0/interp = 0 +tracks/0/loop_wrap = true +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/keys = { +"times": PoolRealArray( 0 ), +"transitions": PoolRealArray( 1 ), +"update": 1, +"values": [ 70.0 ] +} -[sub_resource type="AnimationNodeStateMachinePlayback" id=3] +[sub_resource type="Animation" id=9] +resource_name = "fov" +length = 3.0 +step = 0.061 +tracks/0/type = "value" +tracks/0/path = NodePath("..:fov") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/keys = { +"times": PoolRealArray( 0, 0.549, 2.928 ), +"transitions": PoolRealArray( 1, 1, 1 ), +"update": 0, +"values": [ 70.0, 70.0, 110.0 ] +} [sub_resource type="CylinderShape" id=4] [sub_resource type="SphereShape" id=5] +[sub_resource type="Animation" id=10] +length = 0.001 +tracks/0/type = "bezier" +tracks/0/path = NodePath("../Smoothing/CameraController/Rotation/Camera:translation:x") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/keys = { +"points": PoolRealArray( 0, -0.25, 0, 0.25, 0 ), +"times": PoolRealArray( 0 ) +} +tracks/1/type = "bezier" +tracks/1/path = NodePath("../Smoothing/CameraController/Rotation/Camera:translation:y") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/keys = { +"points": PoolRealArray( 0, -0.25, 0, 0.25, 0 ), +"times": PoolRealArray( 0 ) +} +tracks/2/type = "bezier" +tracks/2/path = NodePath("../Smoothing/CameraController/Rotation/Camera:translation:z") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/keys = { +"points": PoolRealArray( 0, -0.25, 0, 0.25, 0 ), +"times": PoolRealArray( 0 ) +} +tracks/3/type = "value" +tracks/3/path = NodePath("../Smoothing/CameraController/Rotation/Camera:translation") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/keys = { +"times": PoolRealArray( 0 ), +"transitions": PoolRealArray( 1 ), +"update": 0, +"values": [ Vector3( 0, 0, 0 ) ] +} + +[sub_resource type="Animation" id=11] +resource_name = "jump_landing" +tracks/0/type = "value" +tracks/0/path = NodePath("../Smoothing/CameraController/Rotation/Camera:translation") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/keys = { +"times": PoolRealArray( 0, 0.1, 0.4 ), +"transitions": PoolRealArray( 1, 1, 1 ), +"update": 0, +"values": [ Vector3( 0, 0, 0 ), Vector3( 0, -0.161821, 0 ), Vector3( 0, 0, 0 ) ] +} + +[sub_resource type="Animation" id=6] +length = 0.001 +tracks/0/type = "value" +tracks/0/path = NodePath(".:modulate") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/keys = { +"times": PoolRealArray( 0 ), +"transitions": PoolRealArray( 1 ), +"update": 0, +"values": [ Color( 1, 1, 1, 0 ) ] +} + +[sub_resource type="Animation" id=7] +resource_name = "opacity" +length = 0.46 +step = 0.007 +tracks/0/type = "value" +tracks/0/path = NodePath(".:modulate") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/keys = { +"times": PoolRealArray( 0, 0.112, 0.287, 0.35 ), +"transitions": PoolRealArray( 1, 1, 1, 1 ), +"update": 0, +"values": [ Color( 1, 1, 1, 0 ), Color( 1, 1, 1, 1 ), Color( 1, 1, 1, 1 ), Color( 1, 1, 1, 0 ) ] +} + [node name="Player" type="Spatial"] transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.750395, 0 ) script = ExtResource( 3 ) @@ -41,14 +166,6 @@ script = ExtResource( 1 ) keep_aspect = 0 current = true -[node name="CameraAnimationFSM" type="AnimationTree" parent="Smoothing/CameraController/Rotation/Camera"] -tree_root = SubResource( 2 ) -anim_player = NodePath("../CameraAnimationPlayer") -parameters/playback = SubResource( 3 ) - -[node name="CameraAnimationPlayer" type="AnimationPlayer" parent="Smoothing/CameraController/Rotation/Camera"] -root_node = NodePath("../CameraAnimationFSM") - [node name="Flashlight" parent="Smoothing/CameraController/Rotation/Camera" instance=ExtResource( 8 )] transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.00211835, 0 ) light_cull_mask = 4294966783 @@ -56,6 +173,10 @@ light_cull_mask = 4294966783 [node name="HighSpeedFOV" type="Node" parent="Smoothing/CameraController/Rotation/Camera"] script = ExtResource( 11 ) +[node name="FOVAnimation" type="AnimationPlayer" parent="Smoothing/CameraController/Rotation/Camera/HighSpeedFOV"] +anims/RESET = SubResource( 8 ) +anims/fov = SubResource( 9 ) + [node name="WalkieTalkie" parent="Smoothing/CameraController/Rotation/Camera" instance=ExtResource( 14 )] [node name="OnFootPhysics" type="KinematicBody" parent="."] @@ -87,22 +208,50 @@ script = ExtResource( 4 ) [node name="PlatformMechanics" type="Node" parent="."] script = ExtResource( 6 ) -[node name="MovementSounds" parent="." instance=ExtResource( 9 )] +[node name="MovementSoundsAnimations" type="Node" parent="."] +script = ExtResource( 19 ) + +[node name="Footsteps" type="AudioStreamPlayer" parent="MovementSoundsAnimations"] +stream = ExtResource( 17 ) +volume_db = -1.0 + +[node name="Timer" type="Timer" parent="MovementSoundsAnimations/Footsteps"] +one_shot = true + +[node name="Jump" type="AudioStreamPlayer" parent="MovementSoundsAnimations"] +stream = ExtResource( 15 ) + +[node name="JumpLanding" type="AudioStreamPlayer" parent="MovementSoundsAnimations"] +stream = ExtResource( 15 ) + +[node name="JumpLandingHardCrunch" type="AudioStreamPlayer" parent="MovementSoundsAnimations"] +stream = ExtResource( 9 ) + +[node name="JumpLandingHardOuch" type="AudioStreamPlayer" parent="MovementSoundsAnimations"] +stream = ExtResource( 18 ) + +[node name="FallingSound" type="AudioStreamPlayer" parent="MovementSoundsAnimations"] +stream = ExtResource( 16 ) + +[node name="CameraAnimation" type="AnimationPlayer" parent="MovementSoundsAnimations"] +anims/RESET = SubResource( 10 ) +anims/jump_landing = SubResource( 11 ) [node name="Overlay" type="CanvasLayer" parent="."] script = ExtResource( 12 ) [node name="HurtScreen" type="TextureRect" parent="Overlay"] +modulate = Color( 1, 1, 1, 0 ) anchor_right = 1.0 anchor_bottom = 1.0 texture = ExtResource( 13 ) stretch_mode = 1 -[node name="Timer" type="Timer" parent="Overlay/HurtScreen"] -one_shot = true +[node name="HurtScreenOpacityAnimation" type="AnimationPlayer" parent="Overlay/HurtScreen"] +anims/RESET = SubResource( 6 ) +anims/opacity = SubResource( 7 ) [connection signal="area_entered" from="ElevatorPhysics/Area" to="ElevatorPhysics" method="_on_Area_area_entered"] [connection signal="area_exited" from="ElevatorPhysics/Area" to="ElevatorPhysics" method="_on_Area_area_exited"] [connection signal="timeout" from="MovementInput/VerticalTimer" to="MovementInput" method="_on_VerticalTimer_timeout"] [connection signal="timeout" from="MovementInput/HorizontalTimer" to="MovementInput" method="_on_HorizontalTimer_timeout"] -[connection signal="timeout" from="Overlay/HurtScreen/Timer" to="Overlay" method="_on_Timer_timeout"] diff --git a/godot/tests/falling/test_falling.tscn b/godot/tests/falling/test_falling.tscn index 5d16897..0ffa5a3 100644 --- a/godot/tests/falling/test_falling.tscn +++ b/godot/tests/falling/test_falling.tscn @@ -19,7 +19,7 @@ mesh = SubResource( 1 ) shape = SubResource( 2 ) [node name="MeshInstance3" type="MeshInstance" parent="."] -transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -9.41229, 1.87042 ) +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -23.0411, 1.87042 ) mesh = SubResource( 1 ) [node name="StaticBody" type="StaticBody" parent="MeshInstance3"]