+1 vote

I have two `RigidBody2D` (and maybe there are more `PhysicsBody2D` around) that I want to:

1. Check if they have collided.
2. Know the collision velocity at contact point of each body.
3. Based on both velocities (magnitude and direction) compared to the normal vector of collision, decide which body hit the other body.

I can `use _integrate_forces(Physics2DDirectBodyState state )` and reading the state I can know the list of colliders (`get_colliding_bodies`), the collision contact position for each one of the colliders (`state.get_contact_collider_pos`), and the velocity of the body at the contact point (`state.get_contact_collider_velocity_at_pos`).

I even could now the `Object` of one of the colliders (`state.get_contact_collider_object`). Even I can imagine that I detect the object in the list of colliders and it is the other body that I want to check its velocity.

How can I know the velocity on contact point of the other collider? I guess I can't directly call `_integrate_forces` so once I have detected the collider I'm interested in, how can I know its velocity at the colliding point?

in Engine

+1 vote

Using a `test_motion()` would result in a `Physics2DTestMotionResult` which may have what you want. See here.

by (1,106 points)
+1 vote

use a var called velocitylastframe or something like that
at the end of fixedprocess() set velocitylastframe = getlinearvelocity()
When 2 physics bodies collide their velocities are changed in the frame in which they collide, before any fixedprocess() runs, so using getlinearvelocity() when a collision happens will return the new, post-collision velocities. But if you always have the velocity from the last frame, you will have the velocities from right before the collision.

by (16 points)

To anyone from the future who is looking for how to designate a "hitter" and "hittee" and find the collision force after a collision as I was, here is the code that does that.

Firstly, in the physics process or integrate physics (Whichever you use) paste the following code:

``````previous_velocity = current_velocity
current_velocity = self.linear_velocity
``````

Next, go to the physics object's node and access its signals. Connect the node's onbody_entered signal to itself, and find the newly made function in its script, and set it to this:

``````func _on_Object_body_entered(body):
var hit_force = 0
var hitter = false
if body is RigidBody2D:
if body.get_index()>self.get_index():
if body.previous_velocity == Vector2.ZERO:
hitter = true
hit_force = self.previous_velocity.length()*body.mass
elif self.previous_velocity == Vector2.ZERO:
hitter = false
hit_force = body.previous_velocity.length()*body.mass
else:
var hit_velocity = (body.previous_velocity - self.previous_velocity.project(body.previous_velocity)).length()
var enemy_hit_priority
var our_hit_priority
var collision_angle = abs(sin(previous_velocity.angle_to(body.previous_velocity)*0.5))
if collision_angle == 0:
enemy_hit_priority = body.previous_velocity.length()
our_hit_priority = self.previous_velocity.length()
else:
enemy_hit_priority = body.previous_velocity.length()*(body.mass*collision_angle)
our_hit_priority = self.previous_velocity.length()*(self.mass*collision_angle)
if enemy_hit_priority > our_hit_priority:
hitter = false
else:
hitter = true
hit_force = hit_velocity*body.mass
on_hit(hit_force,hitter)
body.on_hit(hit_force,not hitter)
``````

Now just make the `on_hit(hit_force, is_hitter)` function referenced in the code and you're done!

Is it gross? Sure. Is it uncommented because I'm lazy? Yup. Does it work after DAYS OF SEARCHING? Certainly.

by (14 points)