Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

More ideas of how to prevent slope slide down with KinematicBody2D?

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
like image 568
gcivico Avatar asked Jul 28 '17 15:07

gcivico


People also ask

How do you move a kinematic body 2d?

Movement and collision. When moving a KinematicBody2D , you should not set its position directly. Instead, you use the move_and_collide() or move_and_slide() methods. These methods move the body along a given vector and will instantly stop if a collision is detected with another body.


Video Answer


1 Answers

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.

like image 162
Andrey Kachow Avatar answered Dec 30 '22 22:12

Andrey Kachow