Hey all! I've been attempting to replicate the old source style of movement (strafing, bhopping, surfing) in Godot 4, but I've run into an issue with slide collisions in move_and_slide. Surfing is the main problem right now since the slide collisions just make the player character slow down and drop off the slope, whereas in Godot 3, this was not a problem.

The only fix I've managed to find uses slide on the velocity along the normal of the slope, but this locks your height on the slope and does not allow for going back up the slope.

var collided := move_and_slide()
if collided and not get_floor_normal():
	var slide_direction := get_last_slide_collision().get_normal()
	velocity = velocity.slide(slide_direction)

Is there any way I'm able to get the old form of move_and_slide back into Godot 4? Or are there any workarounds for this?

Thanks in advance 😃

4 days later

For anyone in the future who may be looking for this too.

Thanks to this amazing person who already figured out how to do it in his game.
https://github.com/EricXu1728/Godot4SourceEngineMovement

This is the code that managed to solve everything

func move_and_slide_own() -> bool:
    var collided := false
    on_floor  = false

    #check floor
    var checkMotion := velocity * (1/60.0)
    checkMotion.y  -= gravity * (1/360.0)

    var testcol := move_and_collide(checkMotion, true)
    if testcol:
        var testNormal = testcol.get_normal()
        if testNormal.angle_to(up_direction) < floor_max_angle:
            on_floor = true

    # Loop performing the move
    var motion := velocity * get_delta_time()
    for step in max_slides:
        var _collision := move_and_collide(motion)
        if !_collision: break # No collision, so move has finished

        # Calculate velocity to slide along the surface
        var normal = _collision.get_normal()
        motion = _collision.get_remainder().slide(normal)
        velocity = velocity.slide(normal)

        # Collision has occurred
        collided = true

    return collided

func get_delta_time() -> float:
    if Engine.is_in_physics_frame():
        return get_physics_process_delta_time()

    return get_process_delta_time()
4 months later

I am also trying to add surfing to my game I took the movement code from here
https://adrianb.io/2015/02/14/bunnyhop.html
Then I added a function which is called when the player is in air

func clip(normal:Vector3,overbounce:float,delta:float):

var back := velocity.dot(normal)*overbounce
if back>=0: return

#var collision = move_and_collide(velocity * delta)

var change:= normal*back

self.velocity -=change

var adjust:=self.velocity.dot(normal)
if adjust<0.0:

	self.velocity-=normal*adjust

I rly don't understand why it's not working is it because move_and_slide() is being called in my process code ?
what changes would i have to make to get it to work ? add my own move and slide and this or just adding my own move_and_slide will fix surfing?