I am using a RigidBody3D when it falls I want to redirect the force of gravity (linear_velocity.y) in another direction.
For example as soon as the body touches the floor before the physics engine reset the vertical speed I want to assign it to another axis. How can I do it?

I've tried with this, but it doesn't work

func _integrate_forces(state):
	for contactIndex in state.get_contact_count():
		var normal: Vector3 = state.get_contact_local_normal(contactIndex);
		if normal == Vector3.UP:
			if linear_velocity.y > 0:
				linear_velocity.x += linear_velocity.y;

    Emax if normal == Vector3.UP:

    It's very unlikely that normal will be exactly the same as Vector3.UP, since their components are floats. There may be other problems with the code, but that sticks out.

    • Emax replied to this.

      DaveTheCoder You are right but the code is simplified to explain the problem
      Take this code as example:

      func _integrate_forces(state):
      	if state.get_contact_count() > 0:
      		print(linear_velocity.y);

      even if the body falls from an height this will print 0.
      I think the _integrate_forces functions is called after the physics engine process

        What @DaveTheCoder said. We should regard it as a mistake to do floating point comparisons for equality, at least inside of physics. Godot has a bunch of almost-equal functions (or is_equal_approx()).

        Emax I think the _integrate_forces functions is called after the physics engine process

        https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html?highlight=_integrate_forces()

        Quote:

        Note that we are not setting the linear_velocity or angular_velocity properties directly, but rather applying forces (thrust and torque) to the body and letting the physics engine calculate the resulting movement.

        _integrate_forces() is used instead of _physics_process(). In it, one adds forces to the body, and the physics engine calculates the movement.

        • Emax replied to this.

          Pixophir move_and_slide doesn't exist for rigid bodies. The problem is not the dection of the floor, the problem is that whenever a contact is recorded the vertical force is already gone.

          Let's say my scene is configured like this:

          The body has attached this script:

          func _integrate_forces(state):
          	if get_contact_count() > 0:
          		print("from _integrate_forces: ", linear_velocity.y);
          
          func _physics_process(delta):
          	if get_contact_count() > 0:
          		print("from _physics_process: ", linear_velocity.y);

          At the exact moment when the body touches the floor (when the contact is recorded) the linear_velocity is already 0, in fact this code prints:

          from _integrate_forces: 0
          from _physics_process: 0

          So I cannot redirect the force in another direction because it's cleared before my code runs.
          Maybe I should save the linear velocity at each frame and use it after the contact has been recorded, but it doesn't seem like the right way.