+1 vote

I have a KinematicBody (the ship) with a round collision shape. There is a wall on its left, a StaticBody with a plane collision shape.

The ship is moving towards the wall, the red array is the input velocity:

enter image description here

But when I hit the wall, as long as my X velocity is < 0, I can't move, even on the Y axis.
To move along Y, I need to cancel any movement along -X. It is just like there was a huge friction coefficient between the two bodies.

However the friction coefficient of the StaticBody of the wall is set to 0...

What I want is the wall to block any translation on the X axis only but let the Y axis free.

What can I do?

in Engine by (16 points)

1 Answer

+1 vote
Best answer


According to this Issue on GitHub, this is discussed as normal behaviour.

Hello Lovax,

which method of the KinematicBody do you use for moving it?
Have you tried move_and _slide?

"Moves the body along a vector. If the body collides with another, it will slide along the other body rather than stop immediately. If the other body is a KinematicBody or RigidBody, it will also be affected by the motion of the other body. You can use this to make moving or rotating platforms, or to make nodes push other nodes."

It sounds like this would fix your problem.

According to the description, move_and _collide would stop your KinematicBody immediately if it collides.

by (252 points)
selected by

I am already using move_and_slide, here is my code to process the movement of the KinematicBody:

func process_movement(delta):
    # dir is the body's basis dot the input movement vector
    dir = dir.normalized() 

    if dir.x == 0:
        if vel.x > 0:
            vel.x = max(vel.x - DEACCEL*delta, 0)
            vel.x = min(vel.x + DEACCEL*delta, 0)
        vel.x += ACCEL*delta*dir.x

    if dir.y == 0:
        if vel.y > 0:
            vel.y = max(vel.y - DEACCEL*delta, 0)
            vel.y = min(vel.y + DEACCEL*delta, 0)
        vel.y += ACCEL*delta*dir.y

    if dir.z == 0:
        if vel.z > 0:
            vel.z = max(vel.z - DEACCEL*delta, 0)
            vel.z = min(vel.z + DEACCEL*delta, 0)
        vel.z += ACCEL*delta*dir.z

    vel = move_and_slide(vec3clamp(vel, -MAX_SPEED, MAX_SPEED))

So according to this Issue on GitHub. It seems to be normal behaviour.

They basically said, that you cant use plane mesh with plane collider in combination with KinematicBodys.
So your solution would be to use something other than planes. Read the issue for more information.

I recreated a simple scene similar to yours and can confirm that.

Here is my Player script for a KinematicBody, if you need a comparison.

export var speed = 10

var velocity = Vector3(0,0,0)

func _physics_process(delta):

    velocity = move_and_slide(velocity)

    var direction = Vector3(0,0,0)

    if Input.is_action_pressed("move_down"):
        direction.y -= 1
    if Input.is_action_pressed("move_up"):
        direction.y += 1
    if Input.is_action_pressed("move_left"):
        direction.x -= 1
    if Input.is_action_pressed("move_right"):
        direction.x += 1

    var motion = direction.normalized() * speed

    velocity.x = lerp(velocity.x, motion.x, 0.2)
    velocity.y = lerp(velocity.y, motion.y, 0.2)

Good Luck!

Understood, I replaced my plane shapes by boxes and it worked as expected. This is quite strange though, in UE4 we usually use plane collisions for invisible walls.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.