How to make projectiles bounce off an actively moving body V4.6

Godot Version

V4.6

Question

Hello, I have a projectile(character body) that moves and collide then bounces off a character body.

The issue is that the projectiles don’t bounce off of moving bodies and instead they pile up. How would I go about implementing the physics so the projectiles bounce off all bodies.

Projectile physics process:
func _physics_process(delta: float) -> void:

	collision = move_and_collide(velocity*delta)

	if collision:
		collider=collision.get_collider()
		velocity = velocity.bounce(collision.get_normal())
##Friction
	if velocity.length() > 0:
		var drop = friction * delta
		var new_speed = max(velocity.length() - drop, 0)
		velocity = velocity.normalized() * new_speed
Character processes:

func _process(delta: float) -> void:
##get mouse position and rotates the shield towards mouse position
	var aim = get_global_mouse_position() - $Node2D.global_position
	if aim.length() > dead_zone_shield:
		$Node2D.rotation = lerp_angle($Node2D.rotation,aim.angle(), 0.2)
	$Node2D/Shield.ball_dir=($Node2D.get_global_mouse_position()-$Node2D.global_position).normalized()

func _physics_process(delta: float) -> void:
	var target_pos = get_global_mouse_position()
	var to_mouse = target_pos - global_position
	var input = Vector2.ZERO
##moves the character towards mouse
	if to_mouse.length() > dead_zone_moving: # dead zone
		input = to_mouse.normalized()
	var lerp_weight = delta * (acceleration if input != Vector2.ZERO else friction)
	velocity = lerp(velocity, input * (max_speed+to_mouse.length()), lerp_weight)
	move_and_slide()

Push the position further away along the normal when the collision happens. You can also try using rigid bodies instead.

Thanks, I tried using this on the ball physics process.

if collision:
	collider=collision.get_collider()
	velocity = velocity.bounce(collision.get_normal())	
    var push_distance = 10
	translate(collision.get_normal() * push_distance)

It works alright when the body is slower but no much for higher speeds.

Check the collider’s velocity vector and make sure you push enough so that collision with the same collider can’t happen again on the next frame.

2 Likes

Thanks! :slight_smile: I monitored the characters velocity with:

func _physics_process(delta: float) → void:
real_velocity = (global_position - last_position) / delta

then translated the speed to be proportional to push distance, used a bit of trail and error to get what I wanted:

	if collider is CharacterBody2D:
		velocity = velocity.bounce(collision.get_normal())
		if "real_velocity" in collider:
			var speed = collider.real_velocity.length()
			var push_distance = speed
			if speed>10:
				push_distance=(speed/2)/10
			if push_distance>50:
				velocity += velocity.normalized() * (push_distance*10)
			#print(str(push_distance))
			translate(collision.get_normal() * push_distance)

Also I found out that increasing the push distance and the velocity helps reduce multiple collisions.

1 Like

Yeah, the point is to tweak the push/velocity it so it successfully “escapes” the other body once the collision happened.