Need help fixing a dash

Godot Version

4.5

Question

(I’m new to Godot and game design in general)
I want the player to dash toward toward the mouse a set distance/location. I want the dash to feel fast so the time it takes is almost instant.
I’ve tried doing it by setting the velocity to something and then awaiting a timer function, but this feels really inconsistent with the distance of the dash. I can’t use tweening because I’m also using collisions and I find it makes it clip through the collision shapes.
Can you help me create a dash that feels snappy and consistent?

Well set the velocity and wait until the distance is covered. Then set it back to normal

I have a variable that shows the target position, the problem is it hardly ever detects whether the player’s global position is equal to it. There’s also the problem of having the target position behind a wall and so the distance will never be reached. Is there a better way I can see the distance it has travelled?

If ypu have a fixed amount of time to reach the location then the physics is simple, but perhaps unrealistic


velocity = distance * time_to_dash

create a timer and set it to time out at time_to_dash.
Also make a radius of satisfaction around the target, so instead of position==target
You would use

if (target-position).length() < desired_range:

If you want constant speed then you need to compute the

time = distance / speed 

and dynamically change the timer.

And use a raycast to check that there are no collisions

You can accumulate it frame by frame as you move. When you’ve accumulated enough - switch back to regular speed.

There is a Raycast3D node you can add to the scene. I would attach one to the player and call
%RayCast3D.is_colliding() to check for collisions. You could also attach an area3d to the target position and filter that in the collision function.

Also checkover the code to make sure the function cant be called if the player is already dashing, same with all updates to the target area.

Theres an addon for drawing debug geometry too.

I’ve come up with this (I don’t know how to add code snippets). The distance_to()
function makes the game really laggy though:

@onready var character_body: CharacterBody2D = $CharacterBody2D
const distance = 200
var distance_travelled = 0
var dashing : bool
var pos_before : Vector2
var pos_after : Vector2
const speed = 200

func _process(_delta: float) -> void:
	
	if Input.is_action_just_pressed("ui_accept"):
		dash()
	
	
	if dashing == true:
		pos_after = character_body.global_position
		distance_travelled = pos_before.distance_to(pos_after)
		if distance_travelled >= distance:
			dashing = false
			character_body.velocity = Vector2.ZERO
	else:
		pos_before = character_body.global_position
		
func _physics_process(_delta: float) -> void:
	character_body.move_and_slide()
	
	
func dash():
	dashing = true
	character_body.velocity = getmouse(character_body.global_position ) * speed
	

func getmouse(pos: Vector2):
	return Vector2.from_angle(pos.angle_to_point(get_global_mouse_position()))
	

```
[paste code here]
```

Have a time limit and traveled distance limit. Once the dash is triggered - accumulate both. As soon as either of them is exhausted - stop the dash. That way you’ll normally go the wanted distance if there are no obstacles and stop dashing shortly anyway if you get stuck on an obstacle. No need for any complex setups or additional collision tests.

Just thinking im confused about the pos_after being set to the characterbody position

Here. This is only the main switching logic. You need to add actual speed change and whatever else you have when the dashing flag changes its state.

# extends CharacterBody2D

var dashing := false
var time_remain: float
var distance_remain: float

func _physics_process(dt):
	if dashing:
		time_remain -= dt # accumulate time
		distance_remain -= get_position_delta().length() # accumulate distance
		if time_remain <= 0 or distance_remain <= 0:
			dashing = false
	elif Input.is_action_just_pressed("dash"):
		time_remain = DASH_DURATION_MAX
		distance_remain = DASH_DISTANCE
		dashing = true
		
	# move and slide stuff etc...
1 Like

Looks like it could cause a bug … edit : looks like an error

Yeah fair enough

Sorry i see thats just the angle … walking down the street right now so hard to concentrate

What does this mean?

Character body “knows” the distance it travelled during the last frame. Although it needs to be length of what that call returns. Corrected the example code.

But it doesn’t really matter how you implement distance tracking. You can do it manually as well.

The gist is to track both - distance and time, and switch the dash off as soon as one of them crosses its limit.

1 Like

Damn this works really well. Thanks!