Issue with translating rigidbody

WesterWester Posts: 2Member
edited November 2018 in 3D

Hi, when I run this code I get the output:

Before translation: (0, 0, 101.666626)
After translation: (1, 0, -98.333374)
Before translation: (0, 0, 103.33329)
After translation: (1, 0, -96.66671)
Before translation: (1, 0, 101.666557)
After translation: (2, 0, -98.333443)
Before translation: (1, 0, 103.333221)
After translation: (2, 0, -96.666779)

Meaning body.translate gets called twice when it shouldn't and I can't figure out why.
Please help.

extends Node

var body
var col
var pos = Vector3()

func _ready():
    body = RigidBody.new()
    body.set_gravity_scale(0)
    body.set_mode(RigidBody.MODE_RIGID)
    col = CollisionShape.new()
    col.set_shape(BoxShape.new())
    body.add_child(col)
    body.set_mass(0.1)
    add_child(body)
    body.apply_impulse(Vector3(0,0,0),Vector3(0,0,10))

func _process(delta):
    pos = body.get_translation()
    if pos.z > 100.0:
        print("Before translation: " + str(body.get_translation()))
        body.translate(Vector3(1,0,-200.0))
        print("After translation: " + str(body.get_translation()))

Answers

  • TwistedTwiglegTwistedTwigleg Posts: 1,049Admin

    While I am not sure, I think there are a couple things that could be causing the behavior.
    (I'm by no means an expert at Godot, or with computer physics, so I could be completely wrong!)


    One thing that could be causing this to happen is that you are interacting with a physics object in _process instead of _physics_process.

    One is that _process is called every time a frame is drawn on the screen, while the physics engine updates several times every second (the rate physics updates is defined in the project settings). Because of this, if you are going to change something that uses physics, you really should be changing it in _physics_process whenever possible, as _physics_process is called every time the physics engine updates, not every time a frame is drawn.

    Because you are using _process with a RigidBody, it is quite possible that the RigidBody is moving using the physics while you are translating it through 3D space. If I recall correctly, many of Godot's internals are multi-threaded, meaning it's quite possible that more than one process is acting on the same object at the same time.

    In theory, all you would have to do is replace _process with _physics_process and the issue may just go away like that.


    Another reason you could be getting that result is due to the physics object you are interacting is a RigidBody.

    RigidBody nodes are not really designed to be moved around using Translate or similar functions, but rather designed to have impulses applied to them to move them around when possible. The general idea behind using a RigidBody is because you want the physics engine to handle the movement of the object in 3D space, and you just interact with it when needed through functions like apply_impulse.

    If you need to move the RigidBody directly, there are several ways to go about this, but the general idea is to disable the Rigidbody, move it, and then re-enable the RigidBody again. This is so the physics engine does not get in the way and cause problems when moving the RigidBody.

    If you are wanting to control the movement of the RigidBody but still get physics interactions (like collisions between physics objects), I would highly suggest using a KinematicBody instead, and then using the move and/or move_and_slide functions. If you do not need the physics body to do anything but be a barrier, then I would suggest using a StaticBody and moving it around as needed.

    Looking at the code you are using, I think you'll probably want to use a KinematicBody, or a RigidBody in Kinematic mode, instead of a RigidBody.


    If you have not looked at the Physics Introduction section of the documentation, I would highly suggest giving it a look as it may be able to help you narrow down if you are using the correct physics body for what you are trying to achieve, which I think is probably the major cause of the problem.

    Hopefully this helps :smile:

  • WesterWester Posts: 2Member
    Answer ✓

    Thank you for your input!

    It seems I have to use _integrate_forces() as the documentation clearly states.

Sign In or Register to comment.