Inconsistent Death Flying Trajectory

Godot Version

v4.2.stable.official [46dc27791]

Question

How do I get the player death flying trajectory to be consistent with the intended behavior?

Intended behavior: Upon death, the player is given an upwards velocity as he falls (he jumps up and then falls to the ground)

Actual behavior: Works as intended…unless touching the ceiling; if the player is touching the ceiling upon death, he doesn’t fly into the air and falls straight down.

Here’s a video to show what I mean:


First death shows intended behavior; second shows unintended behavior (when touching ceiling)

And here’s my player code:

# Player camera is its own seperate scene.

extends CharacterBody2D

const SPEED = 800.0
const JUMP_VELOCITY = -400.0

var directionX = 1
var bumped = false
var alive = true
var launched = false

# Get the gravity from the project settings to be synced with RigidBody nodes.
var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")

# Nodes
@onready var ray_cast_left = $RayCastLeft
@onready var ray_cast_right = $RayCastRight
@onready var animated_sprite = $AnimatedSprite2D
@onready var camera = $Camera2D

# Sounds
@onready var mach_sound = $MachSound
@onready var bump_sound = $BumpSound

# Signals
signal damage_taken()
signal boing_boing()

func bump(dir_x, ray_cast, flip):
  # Variables!
  ray_cast.enabled = false
  mach_sound.playing = false
  bump_sound.playing = true
  bumped = true
  # Play bump
  animated_sprite.play("bump")
  await get_tree().create_timer(0.3).timeout
  # Flip it around
  directionX = dir_x
  animated_sprite.flip_h = flip
  animated_sprite.play("fly")
  # More variables!
  mach_sound.playing = true
  bumped = false
  # Enable raycast after 1 sec; DON'T PUT VARIABLES BELOW THIS!!!
  await get_tree().create_timer(0.1).timeout
  ray_cast.enabled = true

func death():
  print("lmao")
  animated_sprite.play("death")
  get_node("CollisionShape2D").queue_free()

  # Manage camera
  #camera.get_parent().remove_child(camera)
  #get_node(bump_sound).add_child(camera)

  # No longer a living Noise to make some Noise
  alive = false
  velocity.y = -400
  launched = true
  mach_sound.playing = false


func _physics_process(delta):
  # Bump and turn stuff
  if ray_cast_left.is_colliding() and alive:
  bump(1, ray_cast_left, false)
  elif ray_cast_right.is_colliding() and alive:
  bump(-1, ray_cast_right, true)

  # Add the gravity.

  var directionY = Input.get_axis("move_up", "move_down")
  if not bumped and alive:
    velocity.y = directionY * (SPEED / 2)
    #print("HEEHEE")
  elif not alive and launched:
    velocity.y += gravity * delta
    #print(velocity.y)
  elif alive and not launched:
    velocity.y = 0
    #print("LOL")

  # Get the input direction and handle the movement/deceleration.
  # move_right and move_left are swapped because godot is kinda weird
  var acceleration = Input.get_axis("move_right", "move_left")
  if alive:
    velocity.x = (directionX * SPEED) + (acceleration * 150)
  else:
    velocity.x = (-directionX * SPEED)

  if abs(velocity.x) == SPEED:
    animated_sprite.sprite_frames.set_animation_speed("fly", 24)
  elif abs(velocity.x) > SPEED:
    animated_sprite.sprite_frames.set_animation_speed("fly", 30)
  elif abs(velocity.x) < SPEED:
    animated_sprite.sprite_frames.set_animation_speed("fly", 18)

  move_and_slide()

You are putting the character2d into a invalid state by removing the collision body.

You should deactivate the collision layers of the collision body instead of deleting it.

1 Like

I replaced the line you pointed out with this code:

set_collision_mask_value(1, false)

Now it works as intended! Thank you!

1 Like