6

I have a basic code below. I am trying that the player not slide down on slopes. My slopes now are 45°. If the player stop movement on slope, it will slide down (maybe because velocity.y += delta * gravity.y). I can get the angle by normal and set velocity.y = 0 when player is on slope and it will not slide down. But I am not sure if this is the best approach. Do you have any ideas of how I can achieve this? By the way, is there a way to get project_settings values on gdscript (ie. default_gravity)?

extends KinematicBody2D

var gravity = Vector2(0,700)
var velocity = Vector2()
var hSpeed = 150
var onSlope = false

func _ready():
    set_fixed_process(true)
    pass

func _fixed_process(delta):
    var left = Input.is_action_pressed("ui_left")
    var right = Input.is_action_pressed("ui_right")

    if left:
        velocity.x = -hSpeed
    if right:
        velocity.x = hSpeed
    if !left && ! right:
        velocity.x = 0

    velocity.y += delta * gravity.y
#   if onSlope && !left && !right:
#       velocity.y = 0
#   else:
#       velocity.y += delta * gravity.y

    var movement = delta * velocity
    move(movement)

    if is_colliding():
        var normal = get_collision_normal()
        var angle = getAngleByNormal(normal)

#       I can get the angle here
#       if angle == 0 player is on ground
#       if abs(angle) > 0 && abs(angle) < 90 player is on slope |> onSlope = true

        velocity = normal.slide(velocity)
        movement = normal.slide(movement)
        move(movement)
    pass


func getAngleByNormal(normal):
    var inverseNormal = normal * -1
    var angle = inverseNormal.angle()
    angle = round(rad2deg(angle))
    return angle
    pass
gcivico
  • 61
  • 3

2 Answers2

2

if you are using Godot 3.1 or higher (3.2.1. at the moment), you can use the move_and_slide_with_snap() method. This function allows a parameter for a snap vector. It means that, while the character is standing on the floor, it will try to remain snapped to it. The Player will stand on the slope without sliding. If no longer on the ground, it will not try to snap again until it touches down.

# snap 32 pixels down
velocity = move_and_slide_with_snap(velocity, Vector2(0, -1), Vector2(0, 32)) 

Of course, you must make sure to disable snap when the character jumps. Jumping is usually done by setting velocity.y to negative velocity (like -100), but if snapping is active this will not work, as the character will snap back to the floor.

Disabling snap can be done by just passing a snap of length 0 (Vector2()) to move_and_slide_with_snap() or just by calling move_and_slide() instead.

Andrey Kachow
  • 936
  • 7
  • 22
0

Basically, in physics situations, we should think of gravity as an ever-present force.

But in games, there is no need for constant gravity so you can stop it when the player is grounded and start back up again on jumping or when you are no longer grounded.

The approach I like to use is to just the clamp the velocity in the y-axis so that it never goes down that you are using in the move_and_slide() when grounded and allow the gravity acceleration to keep affecting it regardless.

Note: This answer is based on the Godot 3 API while the question is in Godot 2 cause I thought this way it will be more relevant.

Minraws
  • 46
  • 1
  • 6