Player Physics
Apply forces and impulses to the player's avatar
You can apply physical forces to the player's avatar from your scene's code. This allows you to create gameplay mechanics like launch pads, wind zones, knockback effects, explosions, and more.
There are two kinds of force you can apply:
Impulse: A one-shot instantaneous push. Use this for sudden discrete effects like launching the player into the air or knocking them back.
Continuous force: A sustained push applied every tick for as long as it's active. Use this for ongoing effects like wind zones, water currents, or gravity fields.
Both are applied through the Physics helper, imported from @dcl/sdk/ecs.
π Note: These forces only affect the local player's avatar. Other players see the changes on other player's positions, but the forces themselves aren't synced to other players in multiplayer. Each player's physics run locally on their own instance.
Apply an impulse
Use Physics.applyImpulseToPlayer() to give the player a one-shot push in a given direction.
vector: Direction and strength combined β the length of the vector encodes the impulse magnitude.
import { Physics } from '@dcl/sdk/ecs'
import { Vector3 } from '@dcl/sdk/math'
// Launch the player straight up
Physics.applyImpulseToPlayer(Vector3.create(0, 50, 0))You can also pass a direction and a magnitude separately. In this case, the direction vector is normalized automatically:
direction: Direction to push β normalized automatically before scaling.magnitude: Impulse strength.
If you call applyImpulseToPlayer() multiple times within the same frame, the impulses are accumulated β they are added together and applied as a single combined impulse.
Trigger an impulse on player entry
A common pattern is to trigger an impulse when the player steps into an area. Use a trigger area to detect when the player enters:
Apply a knockback impulse
Use Physics.applyKnockbackToPlayer() to push the player away from a point with a single impulse. This is ideal for explosions, impact effects, and other one-shot directional blasts. The direction is computed automatically from the source point to the player's current position.
You can limit the area of effect with a radius, and control how magnitude decreases with distance using the KnockbackFalloff option:
fromPosition: World-space origin of the knockback (explosion center, enemy position, etc.).magnitude: Base impulse strength.radius: Max distance of effect (default:Infinity).falloff: How magnitude decreases with distance (default:CONSTANT).
The KnockbackFalloff enum controls how the force decreases with distance:
KnockbackFalloff.CONSTANTβ same magnitude at any distance within the radius (default)KnockbackFalloff.LINEARβ smooth linear decrease to 0 at the radius edgeKnockbackFalloff.INVERSE_SQUAREβ sharp physically-realistic drop-off
If the player is exactly at the source position, the player is pushed straight up. A negative magnitude pulls the player toward the point instead of pushing them away.
The same KnockbackFalloff values are available for applyRepulsionForceToPlayer().
Apply a continuous force
Use Physics.applyForceToPlayer() to apply a sustained force to the player. Unlike an impulse, this force is applied every tick as long as it remains active.
source: An entity that identifies this force source β use it to update or remove the force later.vector: Direction and strength combined β the length of the vector encodes the force magnitude.
The source entity's position is not relevant β it's only used as an identifier.
The force vector is always in world space. If you need a direction relative to a rotated entity, use Transform.localToWorldDirection() to convert it first β see Convert a local direction to world space.
As with applyImpulseToPlayer(), you can also pass a direction and magnitude separately β see Apply an impulse:
If you call applyForceToPlayer() again with the same source entity, it replaces the previous force from that source. If multiple force sources are accumulated their vectors are summed each tick.
Remove a continuous force
To stop applying a force, call Physics.removeForceFromPlayer() with a reference to the source entity that was used to create the force. If the entity isn't currently applying a force, this call is safely ignored.
source: The entity used when the force was applied.
Apply a force for a limited duration
Use Physics.applyForceToPlayerForDuration() to apply a force for a specific amount of time. The duration is in seconds. The force is automatically removed when the time elapses. Calling this again with the same source entity resets the timer.
source: An entity that identifies this force source.duration: How long the force lasts, in seconds.vector: Direction and strength combined β the length of the vector encodes the force magnitude.
The direction + magnitude overload is also available β see Apply an impulse:
Wind zone example
This example creates a wind tunnel that pushes the player while they're inside it, and stops when they leave:
Apply a repulsion force
Use Physics.applyRepulsionForceToPlayer() to continuously push the player away from a fixed point in space. This is suited for effects like a magnetic repulsion field, a force barrier, or a hovering object that keeps players at a distance. Unlike applyKnockbackToPlayer(), this force is recalculated every tick as the player moves. The magnitude weakens with distance based on the radius and falloff β see Apply a knockback impulse for the KnockbackFalloff options. A negative magnitude reverses the effect, continuously pulling the player toward the point like a vortex or gravity well.
π Note: The repulsion origin is the fromPosition vector you pass β not the position of the source entity. The source entity is only used as an identifier so you can update or remove the force later. Its position, rotation, and scale are completely ignored.
source: An entity used as an identifier for this force β its position is not used.fromPosition: The world-space point the player is pushed away from.magnitude: Base force strength. Negative values attract instead of repel.radius: Max distance of effect (default:Infinity).falloff: How magnitude decreases with distance (default:CONSTANT).
Forces while gliding
While the player is gliding, continuous forces behave differently:
Continuous forces β from
applyForceToPlayer(),applyForceToPlayerForDuration(), orapplyRepulsionForceToPlayer()β are 1.5 times stronger, since the open glider catches the airflow. Wind zones and currents feel more responsive to a gliding player.The upward component of a continuous force can lift a gliding player. The glider's falling speed limit only caps how fast the player descends, it doesn't cancel upward motion, so an angled or vertical wind current pushes the player along the full direction of the force.
One-shot impulses β from applyImpulseToPlayer() or applyKnockbackToPlayer() β are not affected by gliding. They behave the same whether the glider is open or closed.
You can combine these behaviors to build mechanics like thermal updrafts that carry gliding players upward, or wind corridors that are easier to traverse with the glider open. To adjust the glider's falling speed or forward speed, use the AvatarLocomotionSettings component, see Locomotion Settings.
Convert a local direction to world space
Use Transform.localToWorldDirection() to transform a direction vector from an entity's local coordinate space to world space, accounting for the full parent hierarchy. This is useful when applying forces relative to a rotated entity β for example, pushing the player away from a specific face of a rotating obstacle.
entity: The source entity whose local space defines the direction.localDirection: Direction vector in the entity's local coordinates.
Returns the direction vector in world coordinates.
This applies rotation only β it does not account for translation or scale β making it directly suitable for direction vectors passed to force and impulse functions.
Last updated