How to properly handle collisions manually in 2D?

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


I’m currently making a Pong clone as a learning project, but I have difficulties with the physics engine, more specifically the collision handling.

In some situations I’d like to handle the collision effect manually. My current setup has a StaticBody2D as a paddle and a RigidBody2D in “Character” mode as the ball. The ball has a custom script set with an _integrate_forces method. There I use the state to query the collision, do some math and set a new linear velocity vector for the ball. However, the velocity change is in effect one frame after the physics engine has computed the new position/velocity of the ball it would have after ricocheting from the paddle.

That gives a visible disturbance when the direction the ball takes from the ricochet differs significantly from the one I set manually. See this animation for an example:

You can identify the frame where the collision takes place by the red dot which indicates the location of the collision. In this very frame the ball has already ricocheted in the direction one would expect. By script in this frame I set a velocity which more or less resembles the direction the ball came from.

My question is, can I identify not only the location of the collision but also the time it took place? For example, let us assume the frame before the collision is t0, the frame where the collision is detected and where my scripts reacts to is t1 = t0 + step, then I’d like to know the time t = t0 + delta with delta <= step (and most of the time delta < step will hold). I need this time to calculate the position where the ball should be at the time t1 using the modified velocity.

I could probably infer this time by calculating the difference vector of the ball’s current (=normal ricochet) position and the collision point and dividing it’s length by the ball’s speed, but is there some builtin way to know this delta?

:bust_in_silhouette: Reply From: GodotNoob999

You need to reflect the vector by the collision normal:
Vector2.reflect(collision normal) Godot Docs

also this:

To get delta use get_process_delta_time() or get_physics_process_delta_time()

Godot Docs

Thanks for your answer. The *_delta_time() functions are not what I was looking for - these yield the time delta between frames, but not the exact moment when a collision took place.

I tried the Vector2.reflect() method but got unexpected results. After some searching I finally found out that reflect() is not meant for physical objects bouncing off of surfaces. For that there exists Vector2.bounce().

Applied to my situation the key point was to change the ball to a KinematicBody2D and use move_and_collide() which on collision returns an object with all the info I needed. I had hoped to get around having to code all the movement and collisions manually, but it seems given the circumstances this is still the easiest way.

Nagezahn | 2018-05-01 15:21