Introduction à la physique

Dans le développement d’un jeu, vous avez souvent besoin de savoir quand deux objets du jeu se croisent ou entrent en contact. C’est ce qu’on appelle la détection des collisions. Lorsqu’une collision est détectée, vous voulez généralement que quelque chose se produise. C’est ce qu’on appelle la réponse à la collision.

Godot offre un certain nombre d’objets de collision en 2D et 3D pour fournir à la fois la détection et la réponse aux collisions. Essayer de décider lequel utiliser pour votre projet peut prêter à confusion. Vous pouvez éviter les problèmes et simplifier le développement si vous comprenez comment chacun fonctionne et quels sont ses avantages et ses inconvénients.

Dans ce guide, vous apprendrez :

  • Les quatre types d’objets de collision de Godot
  • Comment chaque objet de collision fonctionne
  • Quand et pourquoi choisir un type plutôt qu’un autre


Les exemples de ce document utilisent des objets 2D. Chaque objet physique 2D et chaque forme de collision a un équivalent direct en 3D et dans la plupart des cas, ils fonctionnent de la même manière.

Objets de collisions

Godot offre 4 types de corps physiques, qui sont des extensions de CollisionObject2D :

  • Area2D (Zone 2D)
    Les nœuds Area2D` fournissent la détection et l’influence. Ils peuvent détecter quand les objets se chevauchent et peuvent émettre des signaux quand des corps entrent ou sortent. Un Area2D peut aussi être utilisé pour outrepasser les propriétés physiques, telles que la gravité ou l’amortissement, dans une zone définie.

Les 3 autres corps sont des extensions de PhysicsBody2D :

  • StaticBody2D (Corps statique 2D)
    Un corps statique est un corps qui n’est pas déplacé par le moteur physique. Il participe à la détection des collisions, mais ne bouge pas en réponse à la collision. Ils sont le plus souvent utilisés pour des objets qui font partie de l’environnement ou qui n’ont pas besoin d’avoir un comportement dynamique.
  • RigidBody2D (Corps rigide 2D)
    C’est le nœud qui implémente la physique 2D simulée. Vous ne contrôlez pas directement un RigidBody2D, mais vous lui appliquez des forces (gravité, impulsions, etc.) et le moteur physique calcule le mouvement résultant. En savoir plus sur l’utilisation des RigidBody.
  • KinematicBody2D (Corps cinématique 2D)
    Un corps qui fournit la détection de collision, mais n’a pas de physique. Toute réponse au mouvement ou à la collision doit être implémentée dans le code.

Formes de collisions

A physics body can hold any number of Shape2D objects as children. These shapes are used to define the object’s collision bounds and to detect contact with other objects.


In order to detect collisions, at least one Shape2D must be assigned to the object.

The most common way to assign a shape is by adding a CollisionShape2D or CollisionPolygon2D as a child of the object. These nodes allow you to draw the shape directly in the editor workspace.


Be careful to never scale your collision shapes in the editor. The « Scale » property in the Inspector should remain (1, 1). When changing the size of the collision shape, you should always use the size handles, not the Node2D scale handles. Scaling a shape can result in unexpected collision behavior.


Physics process callback

The physics engine may spawn multiple threads to improve performance, so it can use up to a full frame to process physics. Because of this, the value of a body’s state variables such as position or linear velocity may not be accurate for the current frame.

In order to avoid this inaccuracy, any code that needs to access a body’s properties should be run in the Node._physics_process() callback, which is called before each physics step at a constant frame rate (60 times per second by default).

Niveaux et masques de collisions

One of the most powerful, but frequently misunderstood, collision features is the collision layer system. This system allows you to build up complex interactions between a variety of objects. The key concepts are layers and masks. Each CollisionObject2D has 20 different physics layers it can interact with.

Let’s look at each of the properties in turn:

  • collision_layer
    This describes the layers that the object appears in. By default, all bodies are on layer 1.
  • 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 can be configured via code, or by editing them in the Inspector.

Keeping track of what you’re using each layer for can be difficult, so you may find it useful to assign names to the layers you’re using. Names can be assigned in Project Settings -> Layer Names.



You have four node types in your game: Walls, Player, Enemy, and Coin. Both Player and Enemy should collide with Walls. The Player node should detect collisions with both Enemy and Coin, but Enemy and Coin 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 » property. Then set each node’s « Mask » property by selecting the layers it should interact with. For example, the Player’s settings would look like this:

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


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

There are three main uses for Area2D:

  • Overriding physics parameters (such as 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.


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. However, it can impart motion or rotation to a colliding body as if it 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 environment or that do not need to have any dynamic behavior.

Example uses for StaticBody2D:

  • Platforms (including moving platforms)
  • Conveyor belts
  • Walls and other obstacles


This is the node that implements simulated 2D physics. You do not control a RigidBody2D directly. Instead, you apply forces to it and the physics engine calculates the resulting movement, including collisions with other bodies, and collision responses, such as bouncing, rotating, etc.

You can modify a rigid body’s behavior via properties such as « Mass », « Friction », or « Bounce », which can be set in the Inspector.

The body’s behavior is also affected by the world’s properties, as set in Project Settings -> Physics, or by entering an Area2D that is overriding the global physics properties.

When a rigid body is at rest and hasn’t moved for a while, it goes to sleep. A sleeping body acts like a static body, and its forces are not calculated by the physics engine. The body will wake up when forces are applied, either by a collision or via code.

Rigid body modes

A rigid body can be set to one of four modes:

  • Rigid - The body behaves as a physical object. It collides with other bodies and responds to forces applied to it. This is the default mode.
  • Static - The body behaves like a StaticBody2D and does not move.
  • Character - Similar to « Rigid » mode, but the body cannot rotate.
  • Kinematic - The body behaves like a KinematicBody2D and must be moved by code.

Using RigidBody2D

One of the benefits of using a rigid body is that a lot of behavior can be had « for free » without writing any code. For example, if you were making an « Angry Birds »-style game with falling blocks, you would only need to create RigidBody2Ds and adjust their properties. Stacking, falling, and bouncing would automatically be calculated by the physics engine.

However, if you do wish to have some control over the body, you should take care - altering the position, linear_velocity, or other physics properties of a rigid body can result in unexpected behavior. If you need to alter any of the physics-related properties, you 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 properties and synchronizing them with the physics engine.

For example, here 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)
        applied_force = Vector2()
    var rotation_dir = 0
    if Input.is_action_pressed("ui_right"):
        rotation_dir += 1
    if Input.is_action_pressed("ui_left"):
        rotation_dir -= 1
    applied_torque = rotation_dir * torque
class Spaceship : RigidBody2D
    private Vector2 thrust = new Vector2(0, 250);
    private float torque = 20000;

    public override void _IntegrateForces(Physics2DDirectBodyState state)
        if (Input.IsActionPressed("ui_up"))
            SetAppliedForce(new Vector2());

        var rotationDir = 0;
        if (Input.IsActionPressed("ui_right"))
            rotationDir += 1;
        if (Input.IsActionPressed("ui_left"))
            rotationDir -= 1;
        SetAppliedTorque(rotationDir * torque);

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


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 body awake by creating a collision, applying a force to it, or by disabling the can_sleep property. Be aware that this can have a negative effect on performance.

Contact reporting

By default, rigid bodies do not keep track of contacts, because this can require a huge amount of memory if many bodies are in the scene. To enable contact reporting, set 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 property. See RigidBody2D for the list of available signals.


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

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

Kinematic collision response

After a collision, you may want the body to bounce, to slide along a wall, or to alter the properties of the object it hit. The way you handle collision response depends on which method you used to move the KinematicBody2D.


When using move_and_collide(), the function returns a KinematicCollision2D object, which contains information about the collision and the colliding body. You can use this information to determine the response.

For example, if you want to find 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
class Body : KinematicBody2D
    private Vector2 velocity = new Vector2(250, 250);

    public override void _PhysicsProcess(float delta)
        var collisionInfo = MoveAndCollide(velocity * delta);
        if (collisionInfo != null)
            var collisionPoint = collisionInfo.GetPosition();

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.bounce(collision_info.normal)
class Body : KinematicBody2D
    private Vector2 velocity = new Vector2(250, 250);

    public override void _PhysicsProcess(float delta)
        var collisionInfo = MoveAndCollide(velocity * delta);
        if (collisionInfo != null)
            velocity = velocity.Bounce(collisionInfo.Normal);


Sliding is a common collision response; imagine a player moving along walls in a top-down game or running up and down slopes in a platformer. While it’s possible to code this response yourself after using move_and_collide(), move_and_slide() provides a convenient way to implement sliding movement without writing much code.


move_and_slide() automatically includes the timestep in its calculation, so you should not multiply the velocity vector by delta.

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

extends KinematicBody2D

var run_speed = 350
var jump_speed = -1000
var gravity = 2500

var velocity = Vector2()

func get_input():
    velocity.x = 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 right:
        velocity.x += run_speed
    if left:
        velocity.x -= run_speed

func _physics_process(delta):
    velocity.y += gravity * delta
    velocity = move_and_slide(velocity, Vector2(0, -1))
class Body : KinematicBody2D
    private float runSpeed = 350;
    private float jumpSpeed = -1000;
    private float gravity = 2500;

    private Vector2 velocity = new Vector2();

    private void getInput()
        velocity.x = 0;

        var right = Input.IsActionPressed("ui_right");
        var left = Input.IsActionPressed("ui_left");
        var jump = Input.IsActionPressed("ui_select");

        if (IsOnFloor() && jump)
            velocity.y = jumpSpeed;
        if (right)
            velocity.x += runSpeed;
        if (left)
            velocity.x -= runSpeed;

    public override void _PhysicsProcess(float delta)
        velocity.y += gravity * delta;

See Kinematic character (2D) for more details on using move_and_slide(), including a demo project with detailed code.