+2 votes

Hello, I'm new to Godot, and am trying to make the switch! RigidBody physics are giving me a little trouble at the moment, however:
I am trying to write a simple 3d game in which you move an object around in space via attached thrusters. To test that I have the basic physics working I created a RigidBody node, with an attached Spatial representing the thruster. Also attached is a CollisionShape (box)

I put the thruster on the bottom of the object, offset to the side a little bit. It should fire, rotating the object since it's placed off to the side.

Here is the integrateforces code:

func _integrate_forces(state):
    var thruster = self.get_node("BottomThruster")
    var force_vector = thruster.get_global_transform().basis.y
    var pos = thruster.get_global_transform().origin

    state.add_force(force_vector, pos)

What happens is it thrusts and rotates just fine, until it is facing the scene origin, at which point it keeps going straight towards the origin. When it crosses over, it rotates back around to face the origin. It just keeps oscillating to face the origin at all times!

Is there something I am forgetting to do to update the body? Or am I not using the correct vector for force?
Thanks for the help!

in Engine by (24 points)

1 Answer

+6 votes
Best answer

You should have read the top questions first, I asked and later answered almost the same question myself just 12 hours ago.

The problem is that the wording on addforce (and applyimpulse) is a little ambiguous. It says that the offset is to be provided in world coordinates, but what it doesn't say is that it still is to be given as an offset. So if you use the transform's origin as the point where the force is applied it will NOT affect the center of the object but the position that is equally far from the object's center than the object is from the world origin. That's why the behaviour changes suddenly when you move past the origin.

Long story short: use
state.addforce(forcevector, Vector3(0,0,0))

by (1,122 points)
selected by

I am trying to actually apply a force not at the center of the body, but at a certain object's position. In my case then, I simply need to subtract the global position of the body being moved from the global thruster position, and now it works.

Thank you so much for the answer, it was exactly what I needed!

Can you provide the code? Stuck here

Here is how I did:

extends RigidBody
class_name Rocket

export var thrust_vector = Vector3()


func _input(event):
    if (Input.is_key_pressed(KEY_UP)):
        var rocket_orientation: Vector3 = get_global_transform().basis[1]
        thrust_vector = Vector3(0.0, 13.0, 0.0)
        var rotation_axis: Vector3 = thrust_vector.cross(rocket_orientation).normalized()
        var angle = thrust_vector.angle_to(rocket_orientation)
        thrust_vector = thrust_vector.rotated(rotation_axis, angle)
    else:
        thrust_vector = Vector3()


func _integrate_forces(state):
    var boosters_position = get_node("Boosters").get_global_transform().origin
    var rocket_position = get_global_transform().origin
    add_force(thrust_vector, rocket_position - boosters_position)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.