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.
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()