Having trouble placing a rigidbody_2d object in a specific coordinate

Godot Version

4.3

Question

I am new to Godot and am probably making some stupid mistake. I want to be able to instantiate objects with Rigidbody2D in a given place similiar to how it is done in this example godot-demo-projects/2d/instancing at 3.5-9e68af3 · godotengine/godot-demo-projects · GitHub
However I just cannot get it to work - I can intantiate an object at (0, 0) but cannot change its position.

The function for changing objects position is simply this:

func place(pos : Vector2, normal : Vector2) -> void:
	global_position = pos + normal * size.dot(normal)

I’ve also tried to use set_deferred like this:

func place(pos : Vector2, normal : Vector2) -> void:
	set_deferred("global_position", pos + normal * size.dot(normal))

And I’ve tried executing this code in a _physics_process as well.
The behaviour I am getting is that the object just blinks to the proper position for one frame before going back to it’s original position.

I have read that I shouldn’t set rigidbode_2d position directly but I can’t find any other way to do it.

If the RigidBody2D was already in the scene you can’t teleport it like that because it will be only teleported for a frame and the next frame the physics system will teleport it back to whatever position it was originally.

You’ll need to do it in RigidBody2D._integrate_forces() and modify the state.transform.origin accordingly. You can check this answer How can I change a node's position during physics interpolation without fast moving effect? - #2 by mrcdk as to how to do it

1 Like

That solution worked first try. Thank you!
In case anyone runs into similiar issue the full code for changing the objects position that worked for me looks like this

var next_global : Vector2
var should_update_gp : bool = false

func place(pos : Vector2) -> void:
	next_global = pos
	should_update_gp = true

func _integrate_forces(state: PhysicsDirectBodyState2D) -> void:
	if should_update_gp:
		state.transform.origin = next_global
		reset_physics_interpolation.call_deferred()
		should_update_gp = false