Godot 3.1: The Future of KinematicBody

The next version will focus on improving KinematicBody, bringing more features for game developers.

What is next for Godot? The next version will focus on improving KinematicBody, bringing more features for game developers. Let’s study a post from the team behind Godot to learn more. 

KINEMATICBODY

One of the features that make Godot stand out is how easy it is to use the physics engine for non-physics games. KinematicBody allows controlling a character entity around with a single function (move_and_slide). Simply pass a linear velocity, and it will be returned back adjusted while the player moves around the level.

velocity = move_and_slide(velocity)

This function tries to move the character using that velocity and every time a collision is found, it will slide against it (and adjust the velocity accordingly). Some extra features are also present, such as specifying the floor direction:

velocity = move_and_slide(velocity, Vector2(0, -1)) # floor points up

After the call, detecting if a character is on floor can be done with a call to:

is_on_floor()

Likewise for walls. This allows adjusting the player animation accordingly. Godot also detects if the floor below is moving, and it will adjust the character accordingly too.

Unfortunately, despite the ease of use, this approach had a few limitations that could (or not) be evident depending on the type of game you were working on.

SNAPPING

The most obvious problem with this approach is snapping to the floor. As the character slides around the level, some situations may lead to the player flying around:

ramp_normal.gif

In some games, this effect may be desired (looks kind of cool), but in other types of games this is unacceptable.

To easily solve this, Godot 3.1 will introduce a new function: move_and_slide_with_snap

This function allows a third parameter for a snap vector. It means that, while the character is standing on the floor, it will try to remain snapped to it. If no longer on ground, it will not try to snap again until it touches down.

The snap argument is a simple vector pointing towards a direction and length (how long it should try to search for the ground to snap)

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

This works very well in practice:

samp_snap.gif

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

Vector2()move_and_slide_with_snap()move_and_slide()

A common trick for this is to have a jumping boolean variable and toggle it on when the character jumps:

# jump logic example with snapping
if is_on_floor() and Input.is_action_just_pressed("jump"):
    # can jump only when on floor
    velocity.y = -100
    jumping = true

# disable jumping when charcter is falling again
if jumping and velocity.y > 0:
    jumping = false 

# preset for snap, 32 pixels down
var snap = Vector2(0, 32)

# oh, but are we jumping? no snap then
if jumping:
    snap = Vector2()

velocity = move_and_slide_with_snap(velocity, Vector2(0, -1), snap) 

RAYCAST SHAPES

Another common situation (when using move_and_slide()) is that the character incurs more effort going up slopes than it does going down.

samp_snap.gif

This is physically correct, but some types of game expect velocity to be constant when moving up and down in slopes.

The solution for this is now the same as when creating a dynamic character controller (physics-based), which is using RayCast shapes. They work now with KinematicBody.

RayCast shapes separate the body in the direction they are pointed to, and will always return a collision normal along their ray, instead of the one provided by the floor (because, again, their goal is to separate). Yes, the name is confusing, maybe they should be renamed to SeparationRayShape in Godot 4.0 ?

In any case, change the collision shape in your body to include a ray pointing down:

separator_ray.png

And now, when moving around the stage, the speed will remain constant:

snap_raycast_snap.gif

Keep in mind that the maximum slope angle where this will work will be geometrically determined by the length of the ray, so make sure to adjust the ray length according to the approximate slope you want to support:

slope_angle.png

As you can see in the picture above, the right slope is so steep that it hits the capsule before the ray, so this effectively disables the ray effect and makes the character incur a lot more effort. It happens naturally, without a single line of code needing to be written.

SYNC TO PHYSICS

move_and_slidepositionrotationmove_and_slide

This makes KinematicBody also very useful for moving platforms, elevators, scripted doors, etc.

The main limitation until now is that, when used as moving platform, its motion was always a frame ahead than the physics, so the character appears to slowly slide over it:

moving_plat_old.gif

To compensate with this, a new option “Sync to Physics” was added. This option is useful when animating via AnimationPlayer or tweaking the position/rotation properties manually in the object:

sync_to_physics.png

When enabled, objects will appear in sync with the KinematicBody:

moving_plat_new.gif

Godot

You can learn more about v3.1 here

Join discussion

Comments 0

    You might also like

    We need your consent

    We use cookies on this website to make your browsing experience better. By using the site you agree to our use of cookies.Learn more