Problem with my grapple mechanic (3D)

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By meroborou

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:

The intended effect isn’t there when the player grapples the target while on the ground. I tried to trigger a little jump if is_on_floor() 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?