Respawning a RigidBody2D (altering position safely from outside or within)

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By BenVella
func _on_RespawnBallTimer_timeout():
	print ("We left the screen for too long, respawning at ", spawn_position)
	set_mode(RigidBody.MODE_STATIC)
	collision_shape.disabled = true
	position = spawn_position
	set_mode(RigidBody.MODE_RIGID)
	collision_shape.disabled = false

The above does not work. In the console:

Ball detected outside play area. Starting Respawn Timer
Ball is respawning!
We left the screen for too long, respawning at (512, 300)

It stays top left of the screen. The intended coordinates should be correct given where I originally placed the ball but it does not appear to be going there. Disabling the setmode back to rigid did not appear to succeed either, it just stopped collisions altogether (which makes sense since if I’m not mistaken static bodies act “idle” and won’t trigger collisions themselves)

What is the best practice to respawn a rigid body 2d object by specifying specific locations?

An alternative route was to simply free and re-create the object at a set location, the results were the same, the object doesn’t move from it’s original scene position (0,0):

var new_ball = ball_res.instance()
var ball_pos = Vector2(512,300)
new_ball.position = ball_pos
add_child(ball_res.instance())
:bust_in_silhouette: Reply From: BenVella

I kept digging figuring there was some way of doing this that wouldn’t be mind numbingly difficult and it turns out someone provided a response for “teleportation” which is technically what this would be.

Answer in question:
https://forum.godotengine.org/16627/how-to-teleport-a-rigidbody2d

For my specific use, I’m re-spawning a simple pong style ball so the following sufficed:


onready var spawn_position = get_viewport_rect().size / 2
onready var reset_position = true
func _integrate_forces(state):
	state.linear_velocity = state.linear_velocity.clamped(max_speed)
	if reset_position:
		linear_velocity = Vector2()
		state.transform.origin = spawn_position
		reset_position = false
		print ("Position has been reset.  Check game")

func _on_RespawnBallTimer_timeout():
	print ("We left the screen for too long, respawning at ", spawn_position)
	reset_position = true