Adding force to RigidBody2D at point is weird when rotated

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

I’m trying to make something like a rocket, with two thrusters. Ship is RigidBody2D, thrusterPoints are simple Nodes2D that are placed on the sides. I’m trying to “drive” the rocket, just by adding force to one thruster or the other.

I have script attached to the RigidBody2D

onready var forcePointLeft = $ForcePointLeft

func _integrate_forces(state: Physics2DDirectBodyState) -> void:
  add_force(forcePointLeft.position, (Vector2.UP * 10).rotated(rotation))

(I added some gravity and stuff, to make it not just fly off into space, but with zero gravity it works the same)
In this case, I expect the rocket to spin in single direction, as it has constant force beeing added to it all the time. It doesn’t behave as expected -.- It does something weird, like on gif below.
weirdly spinning thing

Why is that happening? how is that possible?

That will happen if you constantly call add_force every frame and the code you’ve provided will cause it to spin continually. You need to set conditions and call apply_impulse for a single frame.

Magso | 2020-09-13 09:32

That’s okay, I expect it to spin continuously, for this code example. but as you see on gif - it does not spin continuously - you can see that on first ‘loop’ it goes around half-way, and then goes back - that is not logically possible, without providing additional force the other way around.

Bugari | 2020-09-13 10:00

Even if I try doing it like this:

  if(Input.is_action_just_pressed('ui_left')):
    apply_impulse(forcePointLeft.position, ((Vector2.UP) * 100).rotated(rotation))

And then I mash the button repeatedly, it goes like this:

enter image description here

Bugari | 2020-09-13 10:07

That maybe because you’re using local coordinates, try

apply_impulse(forcePointLeft.global_position, global_transform.xform(Vector2.UP) * 100))

Magso | 2020-09-13 13:32

Nope, that’s also not global/local position.

Finally I have found the reason for the problem:

apply_impulse(forcePointLeft.position.rotated(rotation), ((Vector2.UP) * 40).rotated(rotation))

For some weird reason, force point has to be rotated, even though it’s node inside the ship structure.

Bugari | 2020-09-13 14:24

OMG, this thread saved me, I was having the same problem trying to apply knockback with a projectile. Thank you so much!!!

Nedink | 2021-05-17 21:37