Topic was automatically imported from the old Question2Answer platform.
Asked By
Sprowk
I tried putting it in sleep and then changing pos. Also tried this inside _integrate_forces(s).
if teleporting:
var new_transform = s.get_transform()
new_transform.o = teleported_pos
s.set_transform(new_transform)
teleporting = false
Even creating other functions, yield(get_tree(),"idle_frame") putting these idle frames everywhere and literally every combination of things mentioned above.
The body is always teleported inaccurately. Usually going into walls. It varies around ± 100 for both x and y. I’m really depressed…
What is simple and proper way to teleport RigidBody2D in version 2.1.4?
I don’t know of any official “proper” way. The most consistent method I’ve found is to use set_physics_process(false), wait for a small delay, then set_global_position, then wait again, then reactivate physics.
Usually the delays are not enough to make the player feel lag, especially since teleporting usually happens around a level transition or somewhere players expect it / won’t be upset by it.
You might be interested in this question, although it’s about a KinematicBody2D.
Is your object moving before teleporting using _integrate_forces()? If yes, I suppose that you also need to reset RigidBody2D’s linear and angular velocities to avoid the object going into walls that way. Setting body’s transform is usually not enough:
if teleporting:
var new_transform = s.get_transform()
new_transform.o = teleported_pos
s.set_transform(new_transform)
# Reset velocities to avoid the object going through walls
s.set_linear_velocity(Vector2())
s.set_angular_velocity(0.0)
teleporting = false
The same works in 3d. To get rid of any velocity or rotation, set those using the state like in the previous comment. Weirdly, this may still cause weird bugs if the object is allowed to sleep, so for transporting objects, make sure can_sleep is false.
extends RigidBody
var warp_offset = null
func _on_Spatial_shift(offset):
warp_offset = offset
func _integrate_forces(state):
if warp_offset:
var t = state.get_transform()
t.origin += warp_offset
state.set_transform(t)
warp_offset = null