How to make ball not launch me at light speed

Godot Version

Godot 4

Question

Help Programming Physics

I have this problem where when I jump on top of a sphere, I get launched at insane speeds.

I want that sphere to be able to roll down slides and be able to interact with other blocks, but I don’t want the player to be launched after going on top of the sphere, I want the player to move based on how the sphere is moving without getting launched away with unnecessary strength.

Any help is appreciated, thanks in advance

What’s your player movement code look like? There might be something adding additional speed in there.

1 Like

The only thing that I modified from the base settings is that I added a ledge detector that boosts me up of a couple pixels when I meet a ledge where I would have gotten stuck even if it was really, really short (I also modified the hitbox and the sprite of the player since the video I posted on the top of the thread, so you can also skip all animation stuff and moving hitbox/area2Ds

Inside the blocks code, there is only a function that adds the blocks to the “pushable” group

Here is my full player script

extends CharacterBody2D

#VARIABLES AND CONSTANTS
const SPEED:float = 90.0
const JUMP_VELOCITY:float = -300.0
const PUSH_FORCE:float = 50
const MAX_PUSH:float = 60
var RAY_LENGHT:int
var ON:bool = false

var fallDamage:bool = false;

var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")

func _ready() -> void:
	RAY_LENGHT = $lowRay.target_position.x
	
func _physics_process(delta) -> void:
	if is_on_floor() and fallDamage: 
		explode()
		fallDamage = false
	if not is_on_floor():
		if $fallTime.is_stopped() and !fallDamage: 
			$fallTime.start() #Starts a timer that controls fall damage
		if (velocity.y<270): 
			velocity.y += gravity * delta
		else: 
			velocity.y = 270
			if $fallTime.time_left <= 0.05: fallDamage = true
	
	if is_on_floor(): 
		$fallTime.stop() #If the robot touches the ground, the fall damage timer resets
	
	if Input.is_action_just_pressed("ui_accept") and is_on_floor():
		velocity.y = JUMP_VELOCITY

	#MOVEMENT FOR TESTING, FINAL VERSION HAS AUTOMATIC MOVEMENT
	var direction = Input.get_axis("ui_left", "ui_right")
	if direction:
		$AnimatedSprite2D.play("walk")
		velocity.x = direction * SPEED
		if velocity.x > 0: #FORWARD
			$CollisionPolygon2D.scale.x = 1
			$Area2D/CollisionShape2D.position.x = -11.5
			$AnimatedSprite2D.flip_h = false
			$lowRay.target_position.x = RAY_LENGHT
			$highRay.target_position.x = RAY_LENGHT
		else: #BACKWARDS
			$CollisionPolygon2D.scale.x = -1
			$Area2D/CollisionShape2D.position.x = 11.5
			$AnimatedSprite2D.flip_h = true
			$lowRay.target_position.x = -RAY_LENGHT
			$highRay.target_position.x = -RAY_LENGHT
		if($lowRay.is_colliding() and !$highRay.is_colliding()): #ledge detection
			velocity.y = -40
	else:
		$AnimatedSprite2D.play("idle")
		velocity.x = move_toward(velocity.x, 0, SPEED)
		
	#PUSHING BLOCKS
	for i in get_slide_collision_count():
		var collision = get_slide_collision(i)
		var collision_box = collision.get_collider()
		if collision_box.is_in_group("pushable") and abs(collision_box.get_linear_velocity().x) < MAX_PUSH:
			collision_box.apply_central_impulse(collision.get_normal() * -PUSH_FORCE)
	move_and_slide()

func explode() -> void:
	$explosion.play()

hmm, it might be related to the apply_central_impulse during pushing blocks? that might be applying some impulse back to the player too.