+1 vote

I'm seeing inconsistent rotation behavior using apply_impulse() to a RigidBody2D. Using this simple code:

extends RigidBody2D

func _ready():
    set_process_input(true)
    apply_impulse(Vector2(-10, 0), Vector2(0, -200))

func _input(event):
    if event.is_action_pressed("ui_select"):
        apply_impulse(Vector2(-10, 0), Vector2(0, -200))

As you can see, the apply_impulse() has an offset, so the body should rotate in response. However, when the scene is run, the body does move upward but without any rotation. The same apply_impulse() when run from the _input() function does result in rotation.

I noticed this because I had similar inconsistent rotation response when using apply_impulse() in other functions. Anyone run across this before?

in Engine by (18,211 points)

How much is the angular damp? maybe is nullifying the impulse on fixed process.

No angular damp. And the impulse applied by _input()doesn't get damped at all. Even with damping, you'd think there'd be some rotation, but it's exactly 0.

And the shape is not a circle? I have noticed something weird (like no change on initial rotation) with bouncing circles but didn't tested much.

2 Answers

0 votes

Problem may be that you put the apply_impulse in _ready()

I experienced oddities when working with 3D Physics and not letting it "settle down" at least some fractions of a second directly after scene start. (Usually I give it 0.1sec). Can be that this is similar in 2D.

You can use a one-time timer or a counter (add up deltas) in fixedprocess for delaying the initial impulse.

For example:

extends RigidBody2D

var initialWait = 0.1

func _ready():
    set_process_input(true)
    set_fixed_process(true) 

func _fixed_process(delta):
    if initialWait>0:
        initialWait=initialWait-delta
        return

    set_fixed_process(false)

    apply_impulse(Vector2(-10, 0), Vector2(0, -200))

func _input(event):
    if event.is_action_pressed("ui_select"):
        apply_impulse(Vector2(-10, 0), Vector2(0, -200))
by (3,203 points)
edited by

I thought of this, but the _ready() example was just to demonstrate the problem. It also occurs when the impulse is applied in another function called during the game.

0 votes

Wait one frame to get rid of the problem with apply_torque_impulse

Example for instantiating a spinning axe:

export var axe_scene: PackedScene
const IMPULSE = 300
const TORQUE  = 100000

func throw_axe():
    var axe = axe_scene.instance() as RigidBody2D
    get_tree().get_root().add_child(axe)
    axe.position = global_position
    axe.apply_central_impulse(IMPULSE)
    yield (get_tree(),"idle_frame")
    axe.apply_torque_impulse(TORQUE)
by (133 points)
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.

Categories