godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
89.55k stars 20.27k forks source link

Kinematic bodies having collision normal problems against other Kinematic bodies. #24335

Open ghost opened 5 years ago

ghost commented 5 years ago

Godot version:

9c3293b844fd5fa524778b519c2e0ce6ff495c19

OS/device including version:

Win 10

Issue description:

The issue is that when trying to reflect kinematic bodies on collision, they sometimes stick to each other. This results also in sticking to walls.

sticking

It can be alleviated it somewhat by making temporarily exclusion between bodies for a few frames, which has a potential for worse side effects.

var ball = col.collider

if(ball is KinematicBody2D):

    add_collision_exception_with(ball)
    temp_excl[ball] = delta * EXCLUSION_FRAMES

Steps to reproduce: Use the MRP below or the following code.

var col = move_and_collide(heading * speed * delta )

if(col):
    heading = heading.bounce(col.normal)

Minimal reproduction project:

Kinematic Bodies Sticking.zip

bojidar-bg commented 5 years ago

Happens on 3.1 as well.

Can be worked around by checking if col.normal.dot(heading) < 0, but that seems hacky.

ghost commented 5 years ago

@bojidar-bg Thanks, that's definitely a more compact and easier method.

Yeah, maybe a hack, but it's been my experience over the last year of using the physics that once things go beyond the platformer 101, things start falling apart like this.

I still don't know enough yet to say which exactly are bugs, or if this is just something so dense with tradeoffs that it's always going to require some pile of hacks to get desirable results. I suspect though I'm not terribly off the mark in saying that there are things here and there that do not work fully as advertised.

As long as the physics queries are reliable, works-arounds should be possible most the time.

benjarmstrong commented 5 years ago

I've just tried the KinematicBody2D Demo on Godot 3.1.stable.official_x11.64 and I'm having a similar problem that I suspect is caused by the same bug.

It appears when the returned vector of KinematicBody2D is {0,0} it won't integrate the forces of other bodies. This is evident when opening the KinematicBody2D project in 3.1 and standing on a horizontally-moving platform (in 3.0 you move with it, it 3.1 after your character stops moving and the platform briefly stops then you stop integrating it's movement).

This can be illustrated by adding/removing a line of code before move_and_slide(..):

#player.gd from "2D Platformer Demo (Kinematicbody)"
#...

#linear_vel.x = sign(linear_vel.x) * max(1, abs(linear_vel.x)) # Ensure velocity x is never 0 - uncomment to allowing sticking to moving platforms
linear_vel = move_and_slide(linear_vel, FLOOR_NORMAL, SLOPE_SLIDE_STOP)

#...

Obviously in a game where objects are moving across both axis you would need to do the same for linear_vel.y

I've attached the demo project for reference (player.gd in particular): KinematicBody2D_Demo_3.0.zip

KoBeWi commented 4 years ago

Tested the attached project in 3.2.2 and... TPrAb00Nf7 Not sure if it's same issue though. The behavior from OP's GIF doesn't seem to happen (or at least it's less severe and hard to observe).

ghost commented 4 years ago

Looks a bit worse if they're also sticking to the walls.

ghost commented 3 years ago

@pouleyKetchoupp I'm not entirely sure about this one. The logic seems simple enough that it should work, but maybe its not a valid way of dealing with KBodies. It does appear something has changed between 3.1 and 3.2 at some point. There is less stickiness between the circles, and more against the walls.

Either way, I updated the MRP so it's more current with 3.2

abhiagnihotri01 commented 3 years ago

I am also facing the same problem. In my case, the KinematicBody2D is moving in vertical direction from top to bottom.