Godot Version
v4.2.1.stable.official [b09f793f5]
Question
Hi, I’m new in Godot, trying to implement a ball character controller for a platformer via RigidBody2D. I currently have working code, but it introduces a noticable delay between jumps. The timer does not cause the problem, it is there to prevent multiple impulses in consecutive frames. I suspect there is some kind of delay in the contact monitor contact reporting. ChatGPT is not able to help me with this. Will anyone be able to look at it?
extends RigidBody2D
@export var movement_strength := 500
@export var jump_strength := 600
var collisions: Array = []
func _physics_process(delta: float):
$RayCast2D.rotation = -rotation
$RayCast2D.force_raycast_update()
if $RayCast2D.is_colliding() and get_colliding_bodies().size() == 0:
# This is the case when the body is colliding, but the contact monitor is not reporting it
# It breaks when I put breakpoint here
pass
var movement_intent := Input.get_action_strength("ui_right") - Input.get_action_strength("ui_left")
apply_central_force(Vector2(movement_intent, 0) * movement_strength)
if Input.is_action_pressed("ui_accept") and $JumpTimer.is_stopped():
for pair in collisions:
var point = pair[0]
var object = pair[1]
var jump_direction: Vector2 = (global_position - point).normalized()
var jump_force: Vector2 = jump_direction * jump_strength / collisions.size()
apply_central_impulse(jump_force)
if object is RigidBody2D:
object.apply_impulse(-jump_force, object.to_local(point))
$JumpTimer.start()
func _integrate_forces(state: PhysicsDirectBodyState2D) -> void:
var current_collisions: Array = []
for i in state.get_contact_count():
var collision_point = state.get_contact_collider_position(i)
# store all collisions in the lower quarter of the body
if collision_point.y - global_position.y > $CollisionShape2D.shape.radius / 4:
current_collisions.append([collision_point, state.get_contact_collider_object(i)])
# I currently use this hack to forward the contact points to the _physics_process because get_colliding_bodies() only report the bodies
collisions = current_collisions
I tried to visually profile it with a ray casting and Visible Collision Shapes
and there is measurable one frame delay between when the ray detects the collision and when the debug output detects the contact, but I’m not sure if the contacts visualized in the debug output are the same reported by the Contact Monitor.
I cannot use the ray casting itself because this would break when the ball falls over an edge of a box. I guess I could calculate the contact myself with Area2D, but it seems weird to do this when the physics engine should give me this data.
Can anyone direct me in a right way? Is there a better way to detect contact points?