I am working in Godot 3, where my player is a KinematicBody2D. When I collide with a block which is also a KinematicBody2D I'd like my player to push it without losing velocity.

My block is in a group called moveables, has no script, and has no other forces acting on it.

After I calculate the velocity of my player in _physics_process(), I have the following code.

# update position and handle collision

var collision = move_and_collide(vel * delta)
if collision:
    var collider = collision.collider
    var normal = collision.normal
    var remainder = collision.remainder
    var collision_angle = rad2deg(acos(normal.dot(Vector2(0,-1))))

    # floors
    if collision_angle == 0:

        # reset y vel so it doesn't keep accumulating
        vel.y = 0

        var horizontal_movement = Vector2(remainder.x, 0)

    # moveables
    elif collision_angle == 90:
        if collider in get_tree().get_nodes_in_group("moveables"): 
                collider.move_and_collide(remainder) # move block by remainder
                move_and_collide(remainder) # move player by remainder

This code does allow the player to push the block, but only slowly. I can't figure out why. Ideally, the player would push the block without losing any velocity.

Even if I directly update only the horizontal position of my block, it still moves slower than expected, and my player sprite is blurred, presumably because of collision corrections.

        if collider in get_tree().get_nodes_in_group("moveables"): 
            collider.global_position.x += remainder.x

The problem seems to be that when I move the player by the remainder, the player is still colliding with the block, even though I move the block itself in the previous line. This is confirmed by analyzing the collision object move_and_collide(remainder).

What's wrong and how can I achieve the desired movement?

I asked a variant of this question on a Godot forum, but am also asking it here for increased visibility.

  • 2
    \$\begingroup\$ Why did you decide to make the block a KinematicBody2D? From the Godot documentation: "Kinematic bodies are special types of bodies that are meant to be user-controlled. They are not affected by physics at all (to other types of bodies, such a character or a rigid body, these are the same as a static body)" - this seems ill-suited to an object you want to push around with physics. Is using a RigidBody2D for the block a viable option? \$\endgroup\$ – DMGregory Dec 16 '18 at 15:21
  • \$\begingroup\$ RigidBody2D uses Godot's in-built physics (it requires you to specify friction, mass, gravity scale). KinematicBody2D allows you to specify all movement yourself, and gives you more control. Because my player is a KinematicBody2D, the block should also be, I think. Especially because a KinematicBody2D cannot interact with a RigidBody2D, except by manually detecting collision between them, and then calling add_force() or apply_impulse() on the RigidBody2D (similar to what I'm doing already). There should be a simple way to do this with two KinematicBody2Ds, but I've yet to figure it out. \$\endgroup\$ – diet estus Dec 16 '18 at 15:30
  • 1
    \$\begingroup\$ KinematicBody2D is a good choice for when your physics are simple and you want to implement them yourself in code, like eg. the pieces on a chess board or the blocks of a Sokoban. If you want to rely on Godot to handle the physics, however, it's much easier to use a RigidBody2D and handle any adjustments to the default physics in the physics process callback. If you want to use a KinematicBody2D, you have to add collision areas to your blocks, check for the presence of the player character's body and inherit its horizontal movement. \$\endgroup\$ – flesk Dec 17 '18 at 7:44
  • \$\begingroup\$ Thanks for the suggestion. I will add RayCast2Ds to each side of the block and alter the block's position depending on the player's velocity (as long as certain other conditions are met). \$\endgroup\$ – diet estus Dec 17 '18 at 18:27

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Browse other questions tagged or ask your own question.