Physics introduction
In game development, you often need to know when two objects in the gameintersect or come into contact. This is known ascollision detection.When a collision is detected, you typically want something to happen. Thisis known ascollision response.
Godot offers a number of collision objects in 2D and 3D to provide both collision detectionand response. Trying to decide which one to use for your project can be confusing.You can avoid problems and simplify development if you understand how each worksand what their pros and cons are.
In this guide, you will learn:
Godot's four collision object types
How each collision object works
When and why to choose one type over another
Note
This document's examples will use 2D objects. Every 2D physics objectand collision shape has a direct equivalent in 3D and in most casesthey work in much the same way.
Collision objects
Godot offers four kinds of collision objects which all extendCollisionObject2D.The last three listed below are physics bodies and additionally extendPhysicsBody2D.
- Area2D
Area2D
nodes providedetection andinfluence. They can detect whenobjects overlap and can emit signals when bodies enter or exit. AnArea2D
can also be used to override physics properties, such as gravity or damping,in a defined area.
- StaticBody2D
A static body is one that is not moved by the physics engine. It participatesin collision detection, but does not move in response to the collision. Theyare most often used for objects that are part of the environment or that donot need to have any dynamic behavior.
- RigidBody2D
This is the node that implements simulated 2D physics. You do not control a
RigidBody2D
directly, but instead you apply forces to it (gravity, impulses,etc.) and the physics engine calculates the resulting movement.Read more about using rigid bodies.
- CharacterBody2D
A body that provides collision detection, but no physics. All movement andcollision response must be implemented in code.
Physics material
Static bodies and rigid bodies can be configured to use aPhysicsMaterial. This allows adjusting the friction and bounce of an object,and set if it's absorbent and/or rough.
Collision shapes
A physics body can hold any number ofShape2D objectsas children. These shapes are used to define the object's collision boundsand to detect contact with other objects.
Note
In order to detect collisions, at least oneShape2D
must beassigned to the object.
The most common way to assign a shape is by adding aCollisionShape2DorCollisionPolygon2D as a child of the object.These nodes allow you to draw the shape directly in the editor workspace.
Important
Be careful to never scale your collision shapes in the editor.The "Scale" property in the Inspector should remain(1,1)
. When changingthe size of the collision shape, you should always use the size handles,nottheNode2D
scale handles. Scaling a shape can result in unexpectedcollision behavior.

Physics process callback
The physics engine runs at a fixed rate (a default of 60 iterations per second). This rateis typically different from the frame rate which fluctuates based on what is rendered andavailable resources.
It is important that all physics related code runs at this fixed rate. Therefore Godotdifferentiatesbetween physics and idle processing.Code that runs each frame is called idle processing and code that runs on each physicstick is called physics processing. Godot provides two different callbacks, one for eachof those processing rates.
The physics callback,Node._physics_process(),is called before each physics step. Any code that needs to access a body's properties shouldbe run in here. This method will be passed adelta
parameter, which is a floating-point number equal to the time passed inseconds since the last step. When using the default 60 Hz physics update rate,it will typically be equal to0.01666...
(but not always, see below).
Note
It's recommended to always use thedelta
parameter when relevant in yourphysics calculations, so that the game behaves correctly if you change thephysics update rate or if the player's device can't keep up.
Collision layers and masks
One of the most powerful, but frequently misunderstood, collision featuresis the collision layer system. This system allows you to build up complexinteractions between a variety of objects. The key concepts arelayersandmasks. EachCollisionObject2D
has 32 different physics layersit can interact with.
Let's look at each of the properties in turn:
- collision_layer
This describes the layers that the object appearsin. By default, allbodies are on layer
1
.
- collision_mask
This describes what layers the body willscan for collisions. If anobject 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 youmay find it useful to assign names to the layers you're using. Names canbe assigned inProject Settings > Layer Names > 2D Physics.

GUI example
You have four node types in your game: Walls, Player, Enemy, and Coin. BothPlayer and Enemy should collide with Walls. The Player node should detectcollisions with both Enemy and Coin, but Enemy and Coin should ignore eachother.
Start by naming layers 1-4 "walls", "player", "enemies", and "coins" andplace each node type in its respective layer using the "Layer" property.Then set each node's "Mask" property by selecting the layers it shouldinteract with. For example, the Player's settings would look like this:


Code example
In function calls, layers are specified as a bitmask. Where a function enablesall layers by default, the layer mask will be given as0xffffffff
. Your codecan use binary, hexadecimal, or decimal notation for layer masks, dependingon your preference.
The code equivalent of the above example where layers 1, 3 and 4 were enabledwould be as follows:
# Example: Setting mask value for enabling layers 1, 3 and 4# Binary - set the bit corresponding to the layers you want to enable (1, 3, and 4) to 1, set all other bits to 0.# Note: Layer 32 is the first bit, layer 1 is the last. The mask for layers 4,3 and 1 is therefore0b00000000_00000000_00000000_00001101# (This can be shortened to 0b1101)# Hexadecimal equivalent (1101 binary converted to hexadecimal)0x000d# (This value can be shortened to 0xd)# Decimal - Add the results of 2 to the power of (layer to be enabled - 1).# (2^(1-1)) + (2^(3-1)) + (2^(4-1)) = 1 + 4 + 8 = 13pow(2,1-1)+pow(2,3-1)+pow(2,4-1)
You can also set bits independently by callingset_collision_layer_value(layer_number,value)
orset_collision_mask_value(layer_number,value)
on any givenCollisionObject2D as follows:
# Example: Setting mask value to enable layers 1, 3, and 4.varcollider:CollisionObject2D=$CollisionObject2D# Any given collider.collider.set_collision_mask_value(1,true)collider.set_collision_mask_value(3,true)collider.set_collision_mask_value(4,true)
Export annotations can be used to export bitmasks in the editor with a user-friendly GUI:
@export_flags_2d_physicsvarlayers_2d_physics
Additional export annotations are available for render and navigation layers, in both 2D and 3D. SeeExporting bit flags.
Area2D
Area nodes providedetection andinfluence. They can detect whenobjects overlap and emit signals when bodies enter or exit. Areas can alsobe used to override physics properties, such as gravity or damping, in adefined area.
There are three main uses forArea2D:
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.
StaticBody2D
A static body is one that is not moved by the physics engine. It participatesin collision detection, but does not move in response to the collision. However,it can impart motion or rotation to a colliding bodyas if it were moving,using itsconstant_linear_velocity
andconstant_angular_velocity
properties.
StaticBody2D
nodes are most often used for objects that are part of the environmentor that do not need to have any dynamic behavior.
Example uses forStaticBody2D
:
Platforms (including moving platforms)
Conveyor belts
Walls and other obstacles
RigidBody2D
This is the node that implements simulated 2D physics. You do not control aRigidBody2D directly. Instead, you apply forcesto it and the physics engine calculates the resulting movement, includingcollisions 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 inProject Settings > Physics, or by entering anArea2Dthat 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 bythe physics engine. The body will wake up when forces are applied, either bya collision or via 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 createRigidBody2Ds and adjust their properties. Stacking, falling, and bouncing wouldautomatically be calculated by the physics engine.
However, if you do wish to have some control over the body, you should takecare - altering theposition
,linear_velocity
, or other physics propertiesof a rigid body can result in unexpected behavior. If you need to alter anyof the physics-related properties, you should use the_integrate_forces()callback instead of_physics_process()
. In this callback, you have accessto the body'sPhysicsDirectBodyState2D,which allows for safely changing properties and synchronizing them withthe physics engine.
For example, here is the code for an "Asteroids" style spaceship:
extendsRigidBody2Dvarthrust=Vector2(0,-250)vartorque=20000func_integrate_forces(state):ifInput.is_action_pressed("ui_up"):state.apply_force(thrust.rotated(rotation))else:state.apply_force(Vector2())varrotation_direction=0ifInput.is_action_pressed("ui_right"):rotation_direction+=1ifInput.is_action_pressed("ui_left"):rotation_direction-=1state.apply_torque(rotation_direction*torque)
usingGodot;publicpartialclassSpaceship:RigidBody2D{privateVector2_thrust=newVector2(0,-250);privatefloat_torque=20000;publicoverridevoid_IntegrateForces(PhysicsDirectBodyState2Dstate){if(Input.IsActionPressed("ui_up"))state.ApplyForce(_thrust.Rotated(Rotation));elsestate.ApplyForce(newVector2());varrotationDir=0;if(Input.IsActionPressed("ui_right"))rotationDir+=1;if(Input.IsActionPressed("ui_left"))rotationDir-=1;state.ApplyTorque(rotationDir*_torque);}}
Note that we are not setting thelinear_velocity
orangular_velocity
properties directly, but rather applying forces (thrust
andtorque
) tothe body and letting the physics engine calculate the resulting movement.
Note
When a rigid body goes to sleep, the_integrate_forces()
function will not be called. To override this behavior, you willneed to keep the body awake by creating a collision, applying aforce to it, or by disabling thecan_sleepproperty. 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 canrequire a huge amount of memory if many bodies are in the scene. To enablecontact reporting, set themax_contacts_reportedproperty to a non-zero value. The contacts can then be obtained viaPhysicsDirectBodyState2D.get_contact_count()and related functions.
Contact monitoring via signals can be enabled via thecontact_monitorproperty. SeeRigidBody2D for the list of availablesignals.
CharacterBody2D
CharacterBody2D bodies detect collisions withother 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 willnot move a character body.
When moving a character body, you should not set itsposition
directly.Instead, you use themove_and_collide()
ormove_and_slide()
methods.These methods move the body along a given vector, and it will instantly stopif a collision is detected with another body. After the body has collided,any collision response must be coded manually.
Character 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 collisionresponse depends on which method you used to move the CharacterBody2D.
move_and_collide
When usingmove_and_collide()
, the function returns aKinematicCollision2D object, which containsinformation about the collision and the colliding body. You can use thisinformation to determine the response.
For example, if you want to find the point in space where the collisionoccurred:
extendsPhysicsBody2Dvarvelocity=Vector2(250,250)func_physics_process(delta):varcollision_info=move_and_collide(velocity*delta)ifcollision_info:varcollision_point=collision_info.get_position()
usingGodot;publicpartialclassBody:PhysicsBody2D{privateVector2_velocity=newVector2(250,250);publicoverridevoid_PhysicsProcess(doubledelta){varcollisionInfo=MoveAndCollide(_velocity*(float)delta);if(collisionInfo!=null){varcollisionPoint=collisionInfo.GetPosition();}}}
Or to bounce off of the colliding object:
extendsPhysicsBody2Dvarvelocity=Vector2(250,250)func_physics_process(delta):varcollision_info=move_and_collide(velocity*delta)ifcollision_info:velocity=velocity.bounce(collision_info.get_normal())
usingGodot;publicpartialclassBody:PhysicsBody2D{privateVector2_velocity=newVector2(250,250);publicoverridevoid_PhysicsProcess(doubledelta){varcollisionInfo=MoveAndCollide(_velocity*(float)delta);if(collisionInfo!=null)_velocity=_velocity.Bounce(collisionInfo.GetNormal());}}
move_and_slide
Sliding is a common collision response; imagine a player moving along wallsin a top-down game or running up and down slopes in a platformer. While it'spossible to code this response yourself after usingmove_and_collide()
,move_and_slide()
provides a convenient way to implement sliding movementwithout writing much code.
Warning
move_and_slide()
automatically includes the timestep in itscalculation, so you shouldnot multiply the velocity vectorbydelta
. This doesnot apply togravity
as it is anacceleration and is time dependent, and needs to be scaled bydelta
.
For example, use the following code to make a character that can walk alongthe ground (including slopes) and jump when standing on the ground:
extendsCharacterBody2Dvarrun_speed=350varjump_speed=-1000vargravity=2500funcget_input():velocity.x=0varright=Input.is_action_pressed('ui_right')varleft=Input.is_action_pressed('ui_left')varjump=Input.is_action_just_pressed('ui_select')ifis_on_floor()andjump:velocity.y=jump_speedifright:velocity.x+=run_speedifleft:velocity.x-=run_speedfunc_physics_process(delta):velocity.y+=gravity*deltaget_input()move_and_slide()
usingGodot;publicpartialclassBody:CharacterBody2D{privatefloat_runSpeed=350;privatefloat_jumpSpeed=-1000;privatefloat_gravity=2500;privatevoidGetInput(){varvelocity=Velocity;velocity.X=0;varright=Input.IsActionPressed("ui_right");varleft=Input.IsActionPressed("ui_left");varjump=Input.IsActionPressed("ui_select");if(IsOnFloor()&&jump)velocity.Y=_jumpSpeed;if(right)velocity.X+=_runSpeed;if(left)velocity.X-=_runSpeed;Velocity=velocity;}publicoverridevoid_PhysicsProcess(doubledelta){varvelocity=Velocity;velocity.Y+=_gravity*(float)delta;Velocity=velocity;GetInput();MoveAndSlide();}}
SeeKinematic character (2D) for more details on usingmove_and_slide()
,including a demo project with detailed code.