Teleport
In 4.9 we’ve exposed the teleport flag to several blueprint nodes, and this seemed like a good opportunity to give some detail on how it all works.
When moving physical objects we are concerned with velocity and collision response. Normally when an object’s position (or rotation) is set, the physics engine computes an implicit velocity and uses it to move the object through the world. This ensures that colliding objects bounce away at the right speed.
A nice side effect of this implicit velocity is that in the case of characters, attached simulated bodies (like a pony tail or a pouch) will sway back and forth in a physical way. However, this effect can break when you need to move a character across a large distance (for example when respawning). In this case the implicit velocity will be huge because velocity = distance travelled / frame time.
To get around this we can use the teleport flag which will move objects to the desired position immediately and without affecting their velocity.
Example
In this example we have a simple ball character with a simulated antenna that sways back and forth with forward movement. If we want to teleport the character across the wall (which is really a stack of boxes) using the regular SetWorldLocation will not work because the antenna will inherit a large amount of implicit velocity.
If we set the teleport flag to true, the movement happens without modifying the character’s velocity, and the antenna stays perfectly still on the character’s head.
Sweep
The sweep flag is used for restricting movement. For example, if you want to prevent a player from walking through walls you can use the sweep flag to make sure the movement stops at the first blocking volume. Sweep and Teleport are completely agnostic of one another, and you can get interesting behavior by combining them.
Example
In this example we call AddActorLocalOffset every frame to give the appearance of movement. We do this with every flag combination to show the different behaviors you can expect. Note that when teleport is off, the antenna lags behind due to inertia. When teleport is on, the antenna moves at the same speed as the ball. Observe that when sweep is on we stop moving before colliding with the boxes. When sweep is off, we pass through knocking the boxes out of the way.
Here is a summary of the different behaviors:
Teleport = False | Teleport = True | |
---|---|---|
Sweep = False |
Final position is as specified by user. Velocity changes based on the final position. Colliding objects react to implicit velocity |
Final position is as specified by user. Velocity unaffected. Colliding objects depenetrate only. |
Sweep = True |
Final location is determined by first colliding object along the path. Velocity changes based on the final position. There will be no collision since the sweep prevents it from happening. |
Final location is determined by first colliding object along the path. Velocity unaffected. There will be no collision since the sweep prevents it from happening. |
CCD
You may have wondered why in the first example when we move across the wall there is no physical reaction from the stacked boxes. That is to say, how does the physics engine know that we wanted to jump across the map and not push the boxes out of the way?
It turns out that it knows this because it’s the default behavior. The reason for this is that it would be very expensive to actually move the character through the world and compute reactions along the way. Instead, the physics engine places the character in the final position and then checks for any collisions. If Teleport is used, the colliding objects simply depenetrate (ignoring the actual velocities involved). If Teleport is off, the colliding objects will get knocked away with the implicit velocity.
However, you can certainly change this behavior by turning on continuous collision detection (or CCD). This is more computationally expensive, but is a must for physics-based games that demand very fast movement.
Sweep, Teleport, and CCD can be used interchangeably. Note that Teleport will mean that CCD is effectively ignored.
Simulated objects
The velocity of simulated objects is driven by the physics simulation. Because of this, any movement done on a simulated object is implicitly turned into a teleport. Moreover, kinematic objects that become simulated require special care. Consider the case where a non-simulating object’s position is set without using teleport. In this case we are asking the physics engine to change the velocity of the object so that at the end of the frame (PostPhysics) the object will arrive at the target position. However, if we immediately change the object to be simulated we will see that the target location is ignored. This is because the physics simulation has not had a chance to run yet, and so the new implicit velocity has not been calculated. The result is that our original request is effectively ignored. If we really want to set the position we must use teleport.
Scene Queries
Regular object movement is deferred on the physics simulation side (it uses velocity to move the object during simulating). However, when it comes to scene queries (raycasts, capsule sweeps, etc…) the results are treated as if they happened immediately. This discrepancy is on purpose, and if you think of some common gameplay cases you will (hopefully!) agree.
Consider the case where you have two characters (Player1 and Player2). Since you don’t want the characters to walk through walls (or one another) you move them using the sweep flag. Now imagine a case where both characters want to move to the same position. Player1 will move first, and to do this it will do a capsule sweep to its desired position. Since nothing is there it will go ahead and tell the physics engine to move to that position. Now Player2 will do a capsule sweep. Since scene queries see position changes right away Player2’s sweep will see that Player1 is already at the desired position. Player2 will then move along the path, but stop before colliding with Player1.
If scene queries used the same deferred scheme as the physics simulation the Player2 sweep would not see Player1 (since its position hasn’t actually changed yet). Player1 and Player2 would both end up in the same position, which is exactly what we were trying to avoid!