Source style movement in Godot 4.
Asked Answered
U

1

0

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 😃

Uncompromising answered 5/1 at 20:5 Comment(0)
U
0

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()
Uncompromising answered 9/1 at 20:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.