Physics introduction¶

In game development, you oftentimes demand to know when ii objects in the game intersect or come up into contact. This is known equally collision detection. When a collision is detected, you typically want something to happen. This is known equally collision response.

Godot offers a number of collision objects in 2d and 3D to provide both standoff detection and response. Trying to decide which one to use for your project tin exist confusing. You can avoid problems and simplify development if you understand how each works and what their pros and cons are.

In this guide, y'all will learn:

  • Godot's four collision object types

  • How each collision object works

  • When and why to choose i type over another

Note

This document'due south examples will use 2nd objects. Every 2D physics object and collision shape has a direct equivalent in 3D and in most cases they work in much the same mode.

Collision objects¶

Godot offers 4 kinds of physics bodies, extending CollisionObject2D:

  • Area2D

    Area2D nodes provide detection and influence. They can discover when objects overlap and can emit signals when bodies enter or exit. An Area2D can likewise exist used to override physics properties, such every bit gravity or damping, in a defined expanse.

The other three bodies extend PhysicsBody2D:

  • StaticBody2D

    A static body is i that is not moved by the physics engine. Information technology participates in collision detection, only does not move in response to the collision. They are most often used for objects that are part of the environment or that practice not need to have any dynamic behavior.

  • RigidBody2D

    This is the node that implements fake 2D physics. Y'all practise not command a RigidBody2D directly, but instead y'all utilize forces to information technology (gravity, impulses, etc.) and the physics engine calculates the resulting movement. Read more most using rigid bodies.

  • KinematicBody2D

    A trunk that provides collision detection, but no physics. All movement and collision response must exist implemented in lawmaking.

Physics textile¶

Static bodies and rigid bodies can be configured to utilize a physics cloth. This allows adjusting the friction and bounce of an object, and prepare if it's absorptive and/or rough.

Standoff shapes¶

A physics body tin can agree whatever number of Shape2D objects equally children. These shapes are used to define the object'south standoff bounds and to observe contact with other objects.

Notation

In order to find collisions, at least one Shape2D must exist assigned to the object.

The most common manner to assign a shape is past calculation a CollisionShape2D or CollisionPolygon2D as a kid of the object. These nodes permit you to draw the shape directly in the editor workspace.

Important

Be careful to never scale your collision shapes in the editor. The "Scale" belongings in the Inspector should remain (1, ane) . When changing the size of the collision shape, you should always use the size handles, non the Node2D calibration handles. Scaling a shape can result in unexpected collision beliefs.

../../_images/player_coll_shape.png

Physics process callback¶

The physics engine may spawn multiple threads to ameliorate functioning, and then it tin can use upwardly to a total frame to procedure physics. Considering of this, the value of a trunk's land variables such as position or linear velocity may not be accurate for the current frame.

In order to avoid this inaccuracy, whatever code that needs to access a body's properties should exist run in the Node._physics_process() callback, which is called earlier each physics step at a constant frame charge per unit (60 times per 2d by default). This method will be passed a delta parameter, which is a floating-point number equal to the fourth dimension passed in seconds since the last step. When using the default sixty Hz physics update rate, it volition typically exist equal to 0.01666... (but not always, run across below).

Note

It'due south recommended to always use the delta parameter when relevant in your physics calculations, then that the game behaves correctly if you change the physics update rate or if the player's device can't keep upwardly.

Collision layers and masks¶

One of the near powerful, but frequently misunderstood, collision features is the collision layer system. This system allows y'all to build upwards complex interactions between a variety of objects. The key concepts are layers and masks. Each CollisionObject2D has 20 different physics layers information technology can collaborate with.

Let's look at each of the properties in plow:

  • collision_layer

    This describes the layers that the object appears in. Past default, all bodies are on layer ane .

  • collision_mask

    This describes what layers the body will scan for collisions. If an object isn't in one of the mask layers, the body will ignore it. By default, all bodies scan layer 1 .

These properties tin can be configured via code, or by editing them in the Inspector.

Keeping track of what you're using each layer for tin exist difficult, and then y'all may detect it useful to assign names to the layers you're using. Names can be assigned in Project Settings -> Layer Names.

../../_images/physics_layer_names.png

GUI case¶

You have four node types in your game: Walls, Player, Enemy, and Coin. Both Player and Enemy should collide with Walls. The Actor node should detect collisions with both Enemy and Money, but Enemy and Money should ignore each other.

Start by naming layers 1-4 "walls", "player", "enemies", and "coins" and place each node type in its respective layer using the "Layer" belongings. Then set each node's "Mask" holding by selecting the layers it should interact with. For example, the Histrion's settings would await like this:

../../_images/player_collision_layers.png ../../_images/player_collision_mask.png

Code example¶

In function calls, layers are specified as a bitmask. Where a function enables all layers by default, the layer mask will be given as 0x7fffffff . Your lawmaking can use binary, hexadecimal, or decimal note for layer masks, depending on your preference.

The code equivalent of the above example where layers 1, three and 4 were enabled would be as follows:

                                    # Case: Setting mask value for enabling layers one, three and 4                  # Binary - ready the chip corresponding to the layers you want to enable (1, 3, and iv) to 1, gear up all other bits to 0.                  # Note: Layer 20 is the first scrap, layer 1 is the final. The mask for layers 4,three and 1 is therefore                  0b00000000000000001101                  # (This can exist shortened to 0b1101)                  # Hexadecimal equivalent (1101 binary converted to hexadecimal)                  0x000d                  # (This value can be shortened to 0xd)                  # Decimal - Add the results of ii to the ability of (layer to be enabled - i).                  # (2^(1-ane)) + (two^(3-i)) + (2^(4-1)) = 1 + 4 + 8 = thirteen                  prisoner of war                  (                  2                  ,                  1                  )                  +                  pow                  (                  2                  ,                  3                  )                  +                  prisoner of war                  (                  2                  ,                  iv                  )                

Area2D¶

Area nodes provide detection and influence. They tin detect when objects overlap and emit signals when bodies enter or leave. Areas tin can also be used to override physics properties, such equally gravity or damping, in a defined area.

At that place are three chief uses for Area2D:

  • Overriding physics parameters (such every bit gravity) in a given region.

  • Detecting when other bodies enter or exit a region or what bodies are currently in a region.

  • Checking other areas for overlap.

By default, areas also receive mouse and touchscreen input.

StaticBody2D¶

A static body is one that is not moved by the physics engine. It participates in collision detection, but does not move in response to the collision. Nevertheless, it can impart motility or rotation to a colliding body equally if information technology were moving, using its constant_linear_velocity and constant_angular_velocity properties.

StaticBody2D nodes are most often used for objects that are part of the environs or that practise not need to have any dynamic beliefs.

Example uses for StaticBody2D :

  • Platforms (including moving platforms)

  • Conveyor belts

  • Walls and other obstacles

RigidBody2D¶

This is the node that implements faux second physics. Yous do not command a RigidBody2D directly. Instead, you apply forces to information technology and the physics engine calculates the resulting movement, including collisions with other bodies, and collision responses, such as billowy, rotating, etc.

You can modify a rigid torso's beliefs via properties such equally "Mass", "Friction", or "Bounce", which tin can be set in the Inspector.

The body'south behavior is besides affected by the world'south properties, as gear up in Projection Settings -> Physics, or by entering an Area2D that is overriding the global physics backdrop.

When a rigid body is at remainder and hasn't moved for a while, information technology goes to sleep. A sleeping trunk acts similar a static body, and its forces are not calculated past the physics engine. The body will wake upward when forces are applied, either by a standoff or via code.

Rigid trunk modes¶

A rigid body tin can exist set to one of four modes:

  • Rigid - The torso behaves as a physical object. It collides with other bodies and responds to forces applied to it. This is the default mode.

  • Static - The torso behaves like a StaticBody2D and does not move.

  • Graphic symbol - Similar to "Rigid" mode, but the body cannot rotate.

  • Kinematic - The body behaves like a KinematicBody2D and must be moved by lawmaking.

Using RigidBody2D¶

One of the benefits of using a rigid body is that a lot of beliefs can exist had "for free" without writing whatsoever code. For case, if yous were making an "Angry Birds"-style game with falling blocks, yous would just need to create RigidBody2Ds and adjust their properties. Stacking, falling, and bouncing would automatically exist calculated past the physics engine.

Yet, if you practice wish to have some command over the trunk, you should take care - altering the position , linear_velocity , or other physics backdrop of a rigid body tin event in unexpected behavior. If you need to alter any of the physics-related backdrop, y'all should use the _integrate_forces() callback instead of _physics_process() . In this callback, you have access to the body's Physics2DDirectBodyState, which allows for safely changing backdrop and synchronizing them with the physics engine.

For instance, hither is the code for an "Asteroids" style spaceship:

                                extends                RigidBody2D                var                thrust                =                Vector2                (                0                ,                250                )                var                torque                =                20000                func                _integrate_forces                (                state                ):                if                Input                .                is_action_pressed                (                "ui_up"                ):                applied_force                =                thrust                .                rotated                (                rotation                )                else                :                applied_force                =                Vector2                ()                var                rotation_dir                =                0                if                Input                .                is_action_pressed                (                "ui_right"                ):                rotation_dir                +=                i                if                Input                .                is_action_pressed                (                "ui_left"                ):                rotation_dir                -=                1                applied_torque                =                rotation_dir                *                torque              

Annotation that we are not setting the linear_velocity or angular_velocity backdrop directly, but rather applying forces ( thrust and torque ) to the body and letting the physics engine calculate the resulting movement.

Annotation

When a rigid body goes to sleep, the _integrate_forces() function will not be called. To override this behavior, you will need to keep the torso awake past creating a standoff, applying a force to it, or by disabling the can_sleep belongings. Exist aware that this can have a negative effect on operation.

Contact reporting¶

By default, rigid bodies do not keep runway of contacts, because this can crave a huge amount of memory if many bodies are in the scene. To enable contact reporting, fix the contacts_reported property to a non-zero value. The contacts can then be obtained via Physics2DDirectBodyState.get_contact_count() and related functions.

Contact monitoring via signals can be enabled via the contact_monitor belongings. Run into RigidBody2D for the list of available signals.

KinematicBody2D¶

KinematicBody2D bodies detect collisions with other bodies, simply are not affected by physics properties similar gravity or friction. Instead, they must be controlled past the user via lawmaking. The physics engine will not move a kinematic body.

When moving a kinematic body, you should not set up its position directly. Instead, yous use the move_and_collide() or move_and_slide() methods. These methods move the trunk forth a given vector, and it will instantly stop if a collision is detected with some other body. After the trunk has collided, any collision response must be coded manually.

Kinematic collision response¶

Afterward a collision, you lot may want the torso to bounciness, to slide along a wall, or to alter the properties of the object information technology hit. The way you handle collision response depends on which method you used to motion the KinematicBody2D.

move_and_collide

When using move_and_collide() , the role returns a KinematicCollision2D object, which contains information nearly the collision and the colliding body. You lot tin employ this information to make up one's mind the response.

For example, if you want to discover the point in space where the collision occurred:

                                    extends                  KinematicBody2D                  var                  velocity                  =                  Vector2                  (                  250                  ,                  250                  )                  func                  _physics_process                  (                  delta                  ):                  var                  collision_info                  =                  move_and_collide                  (                  velocity                  *                  delta                  )                  if                  collision_info                  :                  var                  collision_point                  =                  collision_info                  .                  position                

Or to bounce off of the colliding object:

                                    extends                  KinematicBody2D                  var                  velocity                  =                  Vector2                  (                  250                  ,                  250                  )                  func                  _physics_process                  (                  delta                  ):                  var                  collision_info                  =                  move_and_collide                  (                  velocity                  *                  delta                  )                  if                  collision_info                  :                  velocity                  =                  velocity                  .                  bounciness                  (                  collision_info                  .                  normal                  )                

move_and_slide

Sliding is a common collision response; imagine a player moving forth walls in a meridian-down game or running up and down slopes in a platformer. While it'due south possible to code this response yourself after using move_and_collide() , move_and_slide() provides a convenient way to implement sliding motion without writing much lawmaking.

Alarm

move_and_slide() automatically includes the timestep in its calculation, and so y'all should non multiply the velocity vector by delta .

For example, use the following code to make a character that tin can walk along the ground (including slopes) and jump when standing on the footing:

                                    extends                  KinematicBody2D                  var                  run_speed                  =                  350                  var                  jump_speed                  =                  -                  thousand                  var                  gravity                  =                  2500                  var                  velocity                  =                  Vector2                  ()                  func                  get_input                  ():                  velocity                  .                  10                  =                  0                  var                  right                  =                  Input                  .                  is_action_pressed                  (                  'ui_right'                  )                  var                  left                  =                  Input                  .                  is_action_pressed                  (                  'ui_left'                  )                  var                  jump                  =                  Input                  .                  is_action_just_pressed                  (                  'ui_select'                  )                  if                  is_on_floor                  ()                  and                  jump                  :                  velocity                  .                  y                  =                  jump_speed                  if                  correct                  :                  velocity                  .                  x                  +=                  run_speed                  if                  left                  :                  velocity                  .                  x                  -=                  run_speed                  func                  _physics_process                  (                  delta                  ):                  velocity                  .                  y                  +=                  gravity                  *                  delta                  get_input                  ()                  velocity                  =                  move_and_slide                  (                  velocity                  ,                  Vector2                  (                  0                  ,                  -                  i                  ))                

Run across Kinematic character (2nd) for more than details on using move_and_slide() , including a demo project with detailed lawmaking.