• 2D
  • Reset position of RigidBody2D object

I have a RigidBody2D object which player flicks (swipe and hit) it to make it reach an area. I use velocity to move this object when it's hit and this mechanic works fine. But I want to manually set this object's position when it reaches the target area. How can I do that?

I know that we cannot directly manipulate RigidBody2D objects' position. I've tried to change its mode to Kinematic and then tried to set its position but this didn't work too. I don't know what to do.

The object is RigidBody2D with Rigid mode and has Sprite and CollisionShape2D childs.

@SIsilicon28 said: Have you tried the Static mode instead?

When I do the following, it acts the same, doesn't change its position:


get_node("Coins").Coin1.MODE_STATIC
get_node("Coins").Coin1.transform = Transform2D(0, Vector2(180, 180))

I've tried it with physics_process(delta), fixed_process(delta) and _integrate_forces(state), no luck. Tried "position" instead of "transform2D" as well.

Edit:

I corrected the code and I believe it works. Let me test it for a while.

get_node("Coins").Coin1.mode = RigidBody2D.MODE_KINEMATIC
get_node("Coins").Coin1.transform = Transform2D(0, Vector2(180, 180))

The following code reposition the item but when I change it to Rigid again, it goes to the previous position, I can't keep it at the defined position.

get_node("Coins").Coin1.mode = RigidBody2D.MODE_KINEMATIC
get_node("Coins").Coin1.transform = Transform2D(0, Vector2(180, 180))

Where are you executing this code? It could be that the physics engine and the code are out of sync, which causes the physics engine to "take control" and snap the object back into where the physics engine thinks it should be. I would recommend manipulating the RigidBody2D node in _physics_process if possible, to avoid syncing issue. Though, looking at the previous posts, it seems that is not the issue. Have you tried modifying global_position/global_transform? I doubt it would make a difference, but it might be something to experiment with.

A hack workaround that might work is code like the following:

get_node("Coins").Coin1.can_sleep = true # may not be needed.
get_node("Coins").Coin1.sleeping = true
get_node("Coins").Coin1.transform = Transform2D(0, Vector2(180, 180))
get_node("Coins").Coin1.sleeping = false

Not sure if that would fix the issue, but making the RigidBody2D sleep for a second might work around the position snapping back into place.

@TwistedTwigleg said: Where are you executing this code? It could be that the physics engine and the code are out of sync, which causes the physics engine to "take control" and snap the object back into where the physics engine thinks it should be. I would recommend manipulating the RigidBody2D node in _physics_process if possible, to avoid syncing issue. Though, looking at the previous posts, it seems that is not the issue. Have you tried modifying global_position/global_transform? I doubt it would make a difference, but it might be something to experiment with.

A hack workaround that might work is code like the following:

get_node("Coins").Coin1.can_sleep = true # may not be needed.
get_node("Coins").Coin1.sleeping = true
get_node("Coins").Coin1.transform = Transform2D(0, Vector2(180, 180))
get_node("Coins").Coin1.sleeping = false

Not sure if that would fix the issue, but making the RigidBody2D sleep for a second might work around the position snapping back into place.

Unfortunately it didn't work. It acts like the second code below.

Actually previous solution (changing it to static before positioning) partly worked but it has some other problems.

The following code changes its position correctly but then I need to change it to rigid again to interact with the object:

func _physics_process(delta):
	if freekick_formation == true:
		get_node("Coins").Coin1.mode = RigidBody2D.MODE_KINEMATIC
		get_node("Coins").Coin1.global_transform = Transform2D(0, Vector2(180, 180))
		formation_done = 1
		freekick_formation = false

When I change the object mode to Rigid again after setting its position like below, it just moves the object for a moment (like flickering) and then move it to the previous position as soon as it becomes rigid:

func _physics_process(delta):
	if freekick_formation == true:
		get_node("Coins").Coin1.mode = RigidBody2D.MODE_KINEMATIC
		get_node("Coins").Coin1.global_transform = Transform2D(0, Vector2(180, 180))
		formation_done = 1
		freekick_formation = false
	if formation_done == 1:
		get_node("Coins").Coin1.mode = RigidBody2D.MODE_RIGID
		formation_done = 0

Hmm, strange. Maybe replace the if in line 7 with an elif and see if that helps? That should make the physics engine wait a tick before setting the coin back to MODE_RIGID, which may fix the issue of it snapping back into place.

Seems odd though that it is having this issue though. I've only done a little bit of 2D programming with Godot, but I do not think I've had any issues directly manipulating RigidBody2D nodes.

I needed to use a different way (similar to TwistedTwigleg's first answer but not exactly the same), used _integrate_forces(state) and finally solved it. Thank you for your helps.