How to properly move Rigidbody2d in kinematic mode?

FlonkaFlonka Posts: 5Member
edited February 13 in 2D

Hi,

I want to switch the behaviour of a Rigidbody2d node from kinematic to rigid and vice versa. Currently I am trying out 3.1 beta2.

What confuses me however, is how to properly move the rigidbody, when in kinematic mode. What i find is, that i should be altering the position directly, which is what is stated one should not do, reading from the documentation.

After debugging the behavior of the body. I found that It looks like, once in kinematic mode, the body's state is forced set to sleeping (though cansleep is false), and the _integrateforces function is not called. Applying forces or impulse won't move the body, so altering the position(setposition/setglobal_position) is all that's left. And once I do that, integrate is called, the body moves and is interacting with other bodies in the scene.

https://docs.godotengine.org/en/latest/classes/class_rigidbody2d.html#enum-rigidbody2d-mode

According to the latest doc, it should behave like the KinematicBody2d, but in the rigidbody class, we don't have access to the "move_*" functions , which is the recommended way to use that node type.

Asked already on on the QA site, but I thought I'd add it here as well.
https://godotengine.org/qa/39960/how-to-properly-move-rigidbody2d-in-kinematic-mode


Tags :

Best Answer

  • FlonkaFlonka Posts: 5
    Accepted Answer

    After experimenting myself, I found that the approach that works.

    When controlling the RigidBody2D in kinematic mode , one needs to alter the position of the node, in order to have the _integrate_forces called. There, one also needs to update the Physics2DDirectBodyState transform , to not get into problems later on when switching back and forth between rigid mode and kinematic mode.

    E.g. for altering the position , you would change the state.transform.origin to be the global position of the node.

Answers

  • wombatstampedewombatstampede Posts: 135Member

    You could try setting linear_velocity.

    (I don't work with Kinematic though, so I didn't try so far.)

  • FlonkaFlonka Posts: 5Member

    No that actually does not do anything : )

    Tried setting the linear velocity in the physics process , via RigidBody2D.set_linear_velocity().

  • SparrowSparrow Posts: 40Member
    edited February 16

    Hi Flonka

    rigidbody i think should only be moved as kinematic.

    for kinematic just use the example code from

    https://docs.godotengine.org/en/3.0/tutorials/2d/2d_movement.html#summary

    `extends KinematicBody2D

    export (int) var speed = 200

    var velocity = Vector2()

    func get_input():
    velocity = Vector2()
    if Input.is_action_pressed('right'):
    velocity.x += 1
    if Input.is_action_pressed('left'):
    velocity.x -= 1
    if Input.is_action_pressed('down'):
    velocity.y += 1
    if Input.is_action_pressed('up'):
    velocity.y -= 1
    velocity = velocity.normalized() * speed

    func _physics_process(delta):
    get_input()
    move_and_slide(velocity)`

  • FlonkaFlonka Posts: 5Member

    Yeah, @Sparrow one would think that is the case, reading from the docs, as i noted in my initial post. However, the move_and_slide/move_and_collide methods, are not available on the RigidBody2D class. And this is the reason for me opening this thread :).

  • wombatstampedewombatstampede Posts: 135Member

    Ok, it seems that setting the mode of RigidBody actually makes it a KinematicBody. But like you already noticed it just doesn't give the useful move/test methods that KinematicBody offers. Therefore I fail to find much use in the mode = Kinematic of RigidBody.

    I sometimes use the mode to just move a RigidBody to some static state by settting it to StaticBody (similar to sleep).

    Perhaps you tell us the reason why you need to switch from RigidBody to KinematicBody. Then one of us might have another idea to get there.

  • FlonkaFlonka Posts: 5Member

    Oh cool, I did not think to check if the type changed , or perhaps cast it as a KinematicBody2D. I will check out if thats a possibility. Not sure if theres much of a performance imapct in doing so, probably some downside , I guess.

    I want to use the mode switch kinematic<->rigid , to be able to first control the node with precise position set from mouse while affecting the physics world ( I guess, the features the KinematicBody2D gives), and then go to pure physics simulation on an event. So it seems to me that using these modes on the rigidbody should be the way to do so.

  • wombatstampedewombatstampede Posts: 135Member

    I see problems typecasting the node from Rigid to Kinematic or vice versa. (Never tried it though.)

    One could think of some crazy ideas like using two bodies and toggling visibility & collision masks.
    In that case I'd propose switching the RigidBody to static before assigning a new transform.
    It should be possible to use the same script for both nodes if required but variables won't be automatically shared.

    But that approach would be a bit complicated and probably be overkill...

  • FlonkaFlonka Posts: 5Member
    Accepted Answer

    After experimenting myself, I found that the approach that works.

    When controlling the RigidBody2D in kinematic mode , one needs to alter the position of the node, in order to have the _integrate_forces called. There, one also needs to update the Physics2DDirectBodyState transform , to not get into problems later on when switching back and forth between rigid mode and kinematic mode.

    E.g. for altering the position , you would change the state.transform.origin to be the global position of the node.

Leave a Comment

BoldItalicStrikethroughOrdered listUnordered list
Emoji
Image
Align leftAlign centerAlign rightToggle HTML viewToggle full pageToggle lights
Drop image/file