move_and_slide of two stacked KinematicBody2D not working consistently

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By welkin25

Hi all, I’m new to Godot and am following a 2D platformer tutorial ( https://www.youtube.com/watch?v=Mc13Z2gboEk ). This tutorial implements Player and Enemy, both are KinematicBody2D nodes with rectangular CollisionShape2Ds. After implementing the _physics_process methods with move_and_slide on both (Player controlled by player, Enemy move left and right), about 2/3 into the video, I tried playing the game and making the player land on enemy. I haven’t implemented the “stomping/enemy death” code yet, so i had expected that the player might just get carried by enemy that keeps going back and forth. However, this only happens a fraction of the time. Other times the Enemy simply stops moving, and yet another fraction of the time the Enemy would stop for a while and then continue to move.

This is enemy’s code:

func _physics_process(delta: float) -> void:
_velocity.y += gravity * delta
if is_on_wall():
	_velocity.x *= -1
var old_velocity := _velocity
_velocity.y = move_and_slide(_velocity, FLOOR_NORMAL).y
print("Enemy", old_velocity, _velocity)

I added print statement trying to figure out what’s going on, but in either case (Enemy carries Player back and forth or stop moving), Enemy’s velocity is nonzero both before and after move_and_slide call.

I imagine it’s because after Player lands on Enemy, the two rectangles are touching, and hence it may be constantly triggering collisions between Enemy and Player which causes Enemy to stop moving somehow. There may be some floating point precision problem going on too so that the collisions are only detected sometimes and not other times, which is why Enemy sometimes stop and sometimes move. Is this right? How does this work exactly? And how to fix this so that it behaves as I expected (enemy continuing moving with player on top of it)?

A related question: in this case, how does the Player get carried by Enemy while moving? I don’t recall setting friction, so if the two objects are completely frictionless, even if one lands upon another, when the bottom one slides away, shouldn’t the top one stay in position and just fall to ground?

I hope I have described the problem in sufficient details. I have also tried googling for this information, but as I’m completely new to godot (and game dev in general), I fear that I may not know the most precise words to describe the scenario I’m seeing. Any pointers would be greatly appreciated!

:bust_in_silhouette: Reply From: BigTuna675

Hi there, one quick thing I want to say is that kinematic bodies act as though they have infinite inertia, meaning they can’t push each other around. Well, they kind-of sort-of can, it just looks a little janky/weird. For example if you have a playerKB surrounded by lots of zombieKB’s that always try to move towards the player, things get a little weird as they start to fight each other and the player to move to the player.

I think the inconsistent behaviour you’re describing is somewhat related to my zombie scenario I mentioned above. That generally speaking two kinematic bodies don’t push eachother around, unless lots of “stuff” is happening, which creates a bit of an unpredictable outcome.

What is the behaviour you want to happen? That the player gets carried by the enemy when they land on its head? If so you might be able to use “move and slide with snap” to move the player. This tutorial from KidsCanCode will help: MovingPlatforms. Because then the enemy can be thought of as a moving platform right?

Thanks for answering!

I looked at the tutorial you pointed to; however, just changing move_and_slide to move_and_slide_with_snap doesn’t help, the problem persists - sometimes the enemy moves and sometimes it stops.

I wonder if what makes MovingPlatforms tutorial work is that the moving platforms are moving by AnimationPlayer, rather than move_and_slide, thereby bypassing all considerations for collisions altogether?

welkin25 | 2022-08-04 19:43

Darn, sorry to hear it’s still happening. That’s an interesting point about the animation player! I’ve never tried to move a physics body outside of the physics process so my guess is as good as yours.

One more question for you though, what is your FLOOR NORMAL vector set to? (0,1) or (0,-1)?

BigTuna675 | 2022-08-04 19:57