Hello, I'm making a 3D FPS game. I'm still on my newbie shenanigans and I'm working on a grapple mechanic. The idea is that once an enemy is at <40% health, they enter a stun phase (indiciated by the flashing animation). When an enemy is grappled, the player flies towards them and get an upwards boost once there's a collision, sorta like Hyper Demon. The problem comes from the fact that the player gets that boost ONLY when they grapple the target mid-air.

Here's a clip to better demonstrate what I mean by this:
https://youtu.be/Ls8iNWlfGUY

The intended effect isn't there when the player grapples the target while on the ground. I tried to trigger a little jump if isonfloor() returns true, but it still won't work

Here's the relevant piece of code:

``````var grapple_speed = 1.5
var grapple_multiplier = 1.1
var grappleCounter = 0.05
var grappleRecovery = 0.025
var grappleTarget
var grappleDirection = Vector3()
var isGrapplingActive = false
var isGrapplingRecovering = false

func _physics_process(delta):
input_move = _get_directions()
velocity = input_move * MAX_SPEED

if not is_on_floor():
gravity_local += Vector3.DOWN * GRAVITY_ACCELERATION * delta
snap_vector = Vector3.ZERO
else:
gravity_local = Vector3.ZERO

snap_vector = Vector3.DOWN

if is_on_floor():
snap_vector = -get_floor_normal()

# JUMP
if Input.is_action_just_pressed("jump") and is_on_floor() and !isGrapplingActive:
snap_vector = Vector3.ZERO
gravity_local = Vector3.UP * jump_speed

if Input.is_action_just_pressed("grapple") and !isGrapplingActive:
grapple_target()

if isGrapplingActive:
update_grappling()
else:
move_and_slide_with_snap(velocity + gravity_local , snap_vector, Vector3.UP)

func grapple_target():
if aimcast.is_colliding() and aimcast.get_collider().is_in_group("enemy"):
playerState = PLAYER_STATE.GRAPPLING
grappleTarget = aimcast.get_collider()
if grappleTarget.has_method("can_be_grappled") and grappleTarget.can_be_grappled():
#grapplePoint returns the position of a Position3D node
grappleDirection = lookPivot.global_transform.origin.direction_to(grappleTarget.get_grapplePoint()).normalized()
disable_shotgun_movement()
velocity = Vector3.ZERO
grappleCounter = 0.05
isGrapplingActive = true

func update_grappling():
gravity_local = Vector3.ZERO
shotgun_velocity = Vector3.ZERO
velocity += grappleDirection * (grapple_speed * (grapple_multiplier * grappleCounter))
var col = move_and_collide(velocity + gravity_local)
grappleCounter += 0.05
if col and col.get_collider().is_in_group("enemy"):
isGrapplingActive = false
col.get_collider().hit(100.0)
snap_vector = Vector3.ZERO
gravity_local = Vector3.UP * (jump_speed * 1.5)
grappleRecovery = 0.025
isGrapplingRecovering = true
if grappleTarget != null and grappleTarget.has_method("disable_grappleState"):
grappleTarget.disable_grappleState()
``````

The code is a bit of a mess, but yeah. Any ideas for what i can do?

Godot version 3.5
in Engine
edited