Repository: godot
Issue: RigidBody contacts are outdated by a frame
Labels: bug,topic:physics

### Godot version

v4.2.dev3.official [013e8e3af]

### System information

Godot v4.2.dev3 - Windows 10.0.22621 - Vulkan (Forward+) - dedicated NVIDIA GeForce GTX 1650 (NVIDIA; 31.0.15.2824) - Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz (12 Threads)

### Issue description

RigidBody2D and RigidBody3D contacts stored in `PhysicsDirectBodyState2D`/`PhysicsDirectBodyState3D` are outdated by a frame.

- `CharacterBody2D.move_and_collide()` is nice because it reports collisions immediately with that call. This (to my knowledge) isn't a possibility for RigidBody because it has to run through the engine physics system. Instead, when you intend to move a RigidBody with methods like `apply_impulse()` you can't detect new collisions in that frame, you need to wait until the next frame for those changes to propagate to be able to detect new collisions. 
Except, that's not even the case currently. you need to wait *2 frames* for collisions resulting from that change to be available in the RigidBody's `PhysicsDirectBodyState2D`.

There is a small blurb about collision updates in the [RigidBody2D docs for `get_colliding_bodies()`](https://docs.godotengine.org/en/stable/classes/class_rigidbody2d.html#class-rigidbody2d-method-get-colliding-bodies):
> Note: The result of this test is not immediate after moving objects. For performance, list of collisions is updated once per frame and before the physics step. Consider using signals instead.

However, the suggestion to use signals is either false or irrelevant to this issue because the `body_entered` etc. signals are not fired until the same frame that the new collision info is available in the RigidBody's `PhysicsDirectBodyState2D` (and in fact are even less useful because signals are not parsed until after the node's `_physics_process` or `_integrate_forces` is, in my tests)

(It's worth noting that `RigidBody2D.get_contact_count()` and `RigidBody2D.get_colliding_bodies()` have the same issue as the relevant methods in `PhysicsDirectBodyState2D`)

This makes something as simple as a jumping behavior have annoying issues that can't be easily worked around without manually detecting collisions.

### Steps to reproduce

1. Move a RigidBody with a method like `apply_impulse()` such that the body would enter or exit a collision.
2. On the next frame, get the RigidBody's `PhysicsDirectBodyState` and call `state.get_contact_count()` and notice that the count does not reflect the current state of the object.

### Minimal reproduction project

[delayed-contacts-mrp.zip](https://github.com/godotengine/godot/files/12328562/delayed-contacts-mrp.zip)

There are two scenes in this project, `2d.tscn` and `3d.tscn`, for highlighting the issue with RigidBody2D and RigidBody3d respectively. Press "up" or "space" to jump, and notice that the object remains "stuck" to the ground. The script placed on each RigidBody highlights this issue by setting its `linear_velocity.y` to 0.0 when `on_ground` is true, which should be `false` on the frame after jumping. (printing values like `state.get_contact_count()` to the console would highlight the issue as well, but I figured the jump demo was more obvious)