Altering Player velocity without influencing destination


Hello, I am making a game with recoil based traversal.
Meaning you navigate through “Launching”, gaining momentum through the recoil of your shots.


func launch():
	if Input.is_action_just_pressed("LeftClick"):
		velocity = get_local_mouse_position().normalized() * launch_strength

you launch yourself to the direction opposite of where you clicked with your mouse.

I’d love to implement a mechanic where the player’s velocity gets halved while holding down a button, without influencing the destination the player would have went if the button wouldn’t have been pressed.

I want to do something this specific so I can make the player vary between two “speeds” with the press of a button.

I already thought about altering the engine.time_scale, but then everything gets slowed and the game would be too easy.

Is there any way to apply a slowmotion effect only for the player’s velocity?
Or does something similar exist that would yield the same result?
Thank you very much for reading this, if you have any input regarding that topic I’d love to discuss this!

I may give you a bad answer but my thought process would be to half everything, like the gravity scale and/or the velocity to see if that works without affecting everything else. You could keep a separate slow-mo velocity and gravity (and other forces that could apply) variables and one button would use the full velocity variables and the other the slow-mo variables.

Just thinking that the only reason that the trajectory would change if you slow the velocity down to whatever (0.5, 0.3 or whatever), is because gravity and other forces are not scaled down. I don’t have more context on your code or needs and I hope I understood your issue well enough to suggest something that makes sense.

Is it just the player that slows down on click or everything?

I have try some possibility. The most efficient way I found so far is to define the character movement of your player from physics_process like this :

func _physics_process(delta):
	if (Input.is_action_pressed("Ctrl")): return;

Where move is a function containing all your character movement.
You need to readjust gravity and player speed to match your requirement.

You can try this with the character body 2D template:
extends CharacterBody2D

@export var SPEED = 150.0
@export var JUMP_VELOCITY = -300.0

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

func _physics_process(delta):
	if (Input.is_action_pressed("ui_up")): return;

func move(delta):
	# Add the gravity.
	if not is_on_floor():
		velocity.y += gravity * delta

	# Handle jump.
	if Input.is_action_just_pressed("ui_accept") and is_on_floor():
		velocity.y = JUMP_VELOCITY

	# Get the input direction and handle the movement/deceleration.
	# As good practice, you should replace UI actions with custom gameplay actions.
	var direction = Input.get_axis("ui_left", "ui_right")
	if direction:
		velocity.x = direction * SPEED
		velocity.x = move_toward(velocity.x, 0, SPEED)