physics_introduction.rst 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535
  1. .. _doc_physics_introduction:
  2. Physics introduction
  3. ====================
  4. In game development, you often need to know when two objects in the game
  5. intersect or come into contact. This is known as **collision detection**.
  6. When a collision is detected, you typically want something to happen. This
  7. is known as **collision response**.
  8. Godot offers a number of collision objects in 2D and 3D to provide both collision detection
  9. and response. Trying to decide which one to use for your project can be confusing.
  10. You can avoid problems and simplify development if you understand how each works
  11. and what their pros and cons are.
  12. In this guide, you will learn:
  13. - Godot's four collision object types
  14. - How each collision object works
  15. - When and why to choose one type over another
  16. .. note:: This document's examples will use 2D objects. Every 2D physics object
  17. and collision shape has a direct equivalent in 3D and in most cases
  18. they work in much the same way.
  19. Collision objects
  20. -----------------
  21. Godot offers four kinds of collision objects which all extend :ref:`CollisionObject2D <class_CollisionObject2D>`.
  22. The last three listed below are physics bodies and additionally extend :ref:`PhysicsBody2D <class_PhysicsBody2D>`.
  23. - :ref:`Area2D <class_Area2D>`
  24. ``Area2D`` nodes provide **detection** and **influence**. They can detect when
  25. objects overlap and can emit signals when bodies enter or exit. An ``Area2D``
  26. can also be used to override physics properties, such as gravity or damping,
  27. in a defined area.
  28. - :ref:`StaticBody2D <class_StaticBody2D>`
  29. A static body is one that is not moved by the physics engine. It participates
  30. in collision detection, but does not move in response to the collision. They
  31. are most often used for objects that are part of the environment or that do
  32. not need to have any dynamic behavior.
  33. - :ref:`RigidBody2D <class_RigidBody2D>`
  34. This is the node that implements simulated 2D physics. You do not control a
  35. ``RigidBody2D`` directly, but instead you apply forces to it (gravity, impulses,
  36. etc.) and the physics engine calculates the resulting movement.
  37. :ref:`Read more about using rigid bodies. <doc_rigid_body>`
  38. - :ref:`CharacterBody2D <class_CharacterBody2D>`
  39. A body that provides collision detection, but no physics. All movement and
  40. collision response must be implemented in code.
  41. Physics material
  42. ~~~~~~~~~~~~~~~~
  43. Static bodies and rigid bodies can be configured to use a :ref:`PhysicsMaterial
  44. <class_PhysicsMaterial>`. This allows adjusting the friction and bounce of an object,
  45. and set if it's absorbent and/or rough.
  46. Collision shapes
  47. ~~~~~~~~~~~~~~~~
  48. A physics body can hold any number of :ref:`Shape2D <class_Shape2D>` objects
  49. as children. These shapes are used to define the object's collision bounds
  50. and to detect contact with other objects.
  51. .. note:: In order to detect collisions, at least one ``Shape2D`` must be
  52. assigned to the object.
  53. The most common way to assign a shape is by adding a :ref:`CollisionShape2D <class_CollisionShape2D>`
  54. or :ref:`CollisionPolygon2D <class_CollisionPolygon2D>` as a child of the object.
  55. These nodes allow you to draw the shape directly in the editor workspace.
  56. .. important:: Be careful to never scale your collision shapes in the editor.
  57. The "Scale" property in the Inspector should remain ``(1, 1)``. When changing
  58. the size of the collision shape, you should always use the size handles, **not**
  59. the ``Node2D`` scale handles. Scaling a shape can result in unexpected
  60. collision behavior.
  61. .. image:: img/player_coll_shape.webp
  62. Physics process callback
  63. ~~~~~~~~~~~~~~~~~~~~~~~~
  64. The physics engine runs at a fixed rate (a default of 60 iterations per second). This rate
  65. is typically different from the frame rate which fluctuates based on what is rendered and
  66. available resources.
  67. It is important that all physics related code runs at this fixed rate. Therefore Godot
  68. differentiates :ref:`between physics and idle processing <doc_idle_and_physics_processing>`.
  69. Code that runs each frame is called idle processing and code that runs on each physics
  70. tick is called physics processing. Godot provides two different callbacks, one for each
  71. of those processing rates.
  72. The physics callback, :ref:`Node._physics_process() <class_Node_private_method__physics_process>`,
  73. is called before each physics step. Any code that needs to access a body's properties should
  74. be run in here. This method will be passed a ``delta``
  75. parameter, which is a floating-point number equal to the time passed in
  76. *seconds* since the last step. When using the default 60 Hz physics update rate,
  77. it will typically be equal to ``0.01666...`` (but not always, see below).
  78. .. note::
  79. It's recommended to always use the ``delta`` parameter when relevant in your
  80. physics calculations, so that the game behaves correctly if you change the
  81. physics update rate or if the player's device can't keep up.
  82. .. _doc_physics_introduction_collision_layers_and_masks:
  83. Collision layers and masks
  84. ~~~~~~~~~~~~~~~~~~~~~~~~~~
  85. One of the most powerful, but frequently misunderstood, collision features
  86. is the collision layer system. This system allows you to build up complex
  87. interactions between a variety of objects. The key concepts are **layers**
  88. and **masks**. Each ``CollisionObject2D`` has 32 different physics layers
  89. it can interact with.
  90. Let's look at each of the properties in turn:
  91. - collision_layer
  92. This describes the layers that the object appears **in**. By default, all
  93. bodies are on layer ``1``.
  94. - collision_mask
  95. This describes what layers the body will **scan** for collisions. If an
  96. object isn't in one of the mask layers, the body will ignore it. By default,
  97. all bodies scan layer ``1``.
  98. These properties can be configured via code, or by editing them in the Inspector.
  99. Keeping track of what you're using each layer for can be difficult, so you
  100. may find it useful to assign names to the layers you're using. Names can
  101. be assigned in **Project Settings > Layer Names > 2D Physics**.
  102. .. image:: img/physics_layer_names.webp
  103. GUI example
  104. ^^^^^^^^^^^
  105. You have four node types in your game: Walls, Player, Enemy, and Coin. Both
  106. Player and Enemy should collide with Walls. The Player node should detect
  107. collisions with both Enemy and Coin, but Enemy and Coin should ignore each
  108. other.
  109. Start by naming layers 1-4 "walls", "player", "enemies", and "coins" and
  110. place each node type in its respective layer using the "Layer" property.
  111. Then set each node's "Mask" property by selecting the layers it should
  112. interact with. For example, the Player's settings would look like this:
  113. .. image:: img/player_collision_layers.webp
  114. .. image:: img/player_collision_mask.webp
  115. .. _doc_physics_introduction_collision_layer_code_example:
  116. Code example
  117. ^^^^^^^^^^^^
  118. In function calls, layers are specified as a bitmask. Where a function enables
  119. all layers by default, the layer mask will be given as ``0xffffffff``. Your code
  120. can use binary, hexadecimal, or decimal notation for layer masks, depending
  121. on your preference.
  122. The code equivalent of the above example where layers 1, 3 and 4 were enabled
  123. would be as follows:
  124. ::
  125. # Example: Setting mask value for enabling layers 1, 3 and 4
  126. # Binary - set the bit corresponding to the layers you want to enable (1, 3, and 4) to 1, set all other bits to 0.
  127. # Note: Layer 32 is the first bit, layer 1 is the last. The mask for layers 4, 3 and 1 is therefore:
  128. 0b00000000_00000000_00000000_00001101
  129. # (This can be shortened to 0b1101)
  130. # Hexadecimal equivalent (1101 binary converted to hexadecimal).
  131. 0x000d
  132. # (This value can be shortened to 0xd.)
  133. # Decimal - Add the results of 2 to the power of (layer to be enabled - 1).
  134. # (2^(1-1)) + (2^(3-1)) + (2^(4-1)) = 1 + 4 + 8 = 13
  135. #
  136. # We can use the `<<` operator to shift the bit to the left by the layer number we want to enable.
  137. # This is a faster way to multiply by powers of 2 than `pow()`.
  138. # Additionally, we use the `|` (binary OR) operator to combine the results of each layer.
  139. # This ensures we don't add the same layer multiple times, which would behave incorrectly.
  140. (1 << 1 - 1) | (1 << 3 - 1) | (1 << 4 - 1)
  141. # The above can alternatively be written as:
  142. # pow(2, 1 - 1) + pow(2, 3 - 1) + pow(2, 4 - 1)
  143. You can also set bits independently by calling ``set_collision_layer_value(layer_number, value)``
  144. or ``set_collision_mask_value(layer_number, value)`` on any given :ref:`CollisionObject2D <class_CollisionObject2D>` as follows:
  145. ::
  146. # Example: Setting mask value to enable layers 1, 3, and 4.
  147. var collider: CollisionObject2D = $CollisionObject2D # Any given collider.
  148. collider.set_collision_mask_value(1, true)
  149. collider.set_collision_mask_value(3, true)
  150. collider.set_collision_mask_value(4, true)
  151. Export annotations can be used to export bitmasks in the editor with a user-friendly GUI::
  152. @export_flags_2d_physics var layers_2d_physics
  153. Additional export annotations are available for render and navigation layers, in both 2D and 3D. See :ref:`doc_gdscript_exports_exporting_bit_flags`.
  154. Area2D
  155. ------
  156. Area nodes provide **detection** and **influence**. They can detect when
  157. objects overlap and emit signals when bodies enter or exit. Areas can also
  158. be used to override physics properties, such as gravity or damping, in a
  159. defined area.
  160. There are three main uses for :ref:`Area2D <class_Area2D>`:
  161. - Overriding physics parameters (such as gravity) in a given region.
  162. - Detecting when other bodies enter or exit a region or what bodies are currently in a region.
  163. - Checking other areas for overlap.
  164. By default, areas also receive mouse and touchscreen input.
  165. StaticBody2D
  166. ------------
  167. A static body is one that is not moved by the physics engine. It participates
  168. in collision detection, but does not move in response to the collision. However,
  169. it can impart motion or rotation to a colliding body **as if** it were moving,
  170. using its ``constant_linear_velocity`` and ``constant_angular_velocity`` properties.
  171. ``StaticBody2D`` nodes are most often used for objects that are part of the environment
  172. or that do not need to have any dynamic behavior.
  173. Example uses for ``StaticBody2D``:
  174. - Platforms (including moving platforms)
  175. - Conveyor belts
  176. - Walls and other obstacles
  177. RigidBody2D
  178. -----------
  179. This is the node that implements simulated 2D physics. You do not control a
  180. :ref:`RigidBody2D <class_RigidBody2D>` directly. Instead, you apply forces
  181. to it and the physics engine calculates the resulting movement, including
  182. collisions with other bodies, and collision responses, such as bouncing,
  183. rotating, etc.
  184. You can modify a rigid body's behavior via properties such as "Mass",
  185. "Friction", or "Bounce", which can be set in the Inspector.
  186. The body's behavior is also affected by the world's properties, as set in
  187. **Project Settings > Physics**, or by entering an :ref:`Area2D <class_Area2D>`
  188. that is overriding the global physics properties.
  189. When a rigid body is at rest and hasn't moved for a while, it goes to sleep.
  190. A sleeping body acts like a static body, and its forces are not calculated by
  191. the physics engine. The body will wake up when forces are applied, either by
  192. a collision or via code.
  193. Using RigidBody2D
  194. ~~~~~~~~~~~~~~~~~
  195. One of the benefits of using a rigid body is that a lot of behavior can be had
  196. "for free" without writing any code. For example, if you were making an
  197. "Angry Birds"-style game with falling blocks, you would only need to create
  198. RigidBody2Ds and adjust their properties. Stacking, falling, and bouncing would
  199. automatically be calculated by the physics engine.
  200. However, if you do wish to have some control over the body, you should take
  201. care - altering the ``position``, ``linear_velocity``, or other physics properties
  202. of a rigid body can result in unexpected behavior. If you need to alter any
  203. of the physics-related properties, you should use the :ref:`_integrate_forces() <class_RigidBody2D_private_method__integrate_forces>`
  204. callback instead of ``_physics_process()``. In this callback, you have access
  205. to the body's :ref:`PhysicsDirectBodyState2D <class_PhysicsDirectBodyState2D>`,
  206. which allows for safely changing properties and synchronizing them with
  207. the physics engine.
  208. For example, here is the code for an "Asteroids" style spaceship:
  209. .. tabs::
  210. .. code-tab:: gdscript GDScript
  211. extends RigidBody2D
  212. var thrust = Vector2(0, -250)
  213. var torque = 20000
  214. func _integrate_forces(state):
  215. if Input.is_action_pressed("ui_up"):
  216. state.apply_force(thrust.rotated(rotation))
  217. else:
  218. state.apply_force(Vector2())
  219. var rotation_direction = 0
  220. if Input.is_action_pressed("ui_right"):
  221. rotation_direction += 1
  222. if Input.is_action_pressed("ui_left"):
  223. rotation_direction -= 1
  224. state.apply_torque(rotation_direction * torque)
  225. .. code-tab:: csharp
  226. using Godot;
  227. public partial class Spaceship : RigidBody2D
  228. {
  229. private Vector2 _thrust = new Vector2(0, -250);
  230. private float _torque = 20000;
  231. public override void _IntegrateForces(PhysicsDirectBodyState2D state)
  232. {
  233. if (Input.IsActionPressed("ui_up"))
  234. state.ApplyForce(_thrust.Rotated(Rotation));
  235. else
  236. state.ApplyForce(new Vector2());
  237. var rotationDir = 0;
  238. if (Input.IsActionPressed("ui_right"))
  239. rotationDir += 1;
  240. if (Input.IsActionPressed("ui_left"))
  241. rotationDir -= 1;
  242. state.ApplyTorque(rotationDir * _torque);
  243. }
  244. }
  245. Note that we are not setting the ``linear_velocity`` or ``angular_velocity``
  246. properties directly, but rather applying forces (``thrust`` and ``torque``) to
  247. the body and letting the physics engine calculate the resulting movement.
  248. .. note:: When a rigid body goes to sleep, the ``_integrate_forces()``
  249. function will not be called. To override this behavior, you will
  250. need to keep the body awake by creating a collision, applying a
  251. force to it, or by disabling the :ref:`can_sleep <class_RigidBody2D_property_can_sleep>`
  252. property. Be aware that this can have a negative effect on performance.
  253. Contact reporting
  254. ~~~~~~~~~~~~~~~~~
  255. By default, rigid bodies do not keep track of contacts, because this can
  256. require a huge amount of memory if many bodies are in the scene. To enable
  257. contact reporting, set the :ref:`max_contacts_reported <class_RigidBody2D_property_max_contacts_reported>`
  258. property to a non-zero value. The contacts can then be obtained via
  259. :ref:`PhysicsDirectBodyState2D.get_contact_count() <class_PhysicsDirectBodyState2D_method_get_contact_count>`
  260. and related functions.
  261. Contact monitoring via signals can be enabled via the :ref:`contact_monitor <class_RigidBody2D_property_contact_monitor>`
  262. property. See :ref:`RigidBody2D <class_RigidBody2D>` for the list of available
  263. signals.
  264. CharacterBody2D
  265. ---------------
  266. :ref:`CharacterBody2D <class_CharacterBody2D>` bodies detect collisions with
  267. other bodies, but are not affected by physics properties like gravity or friction.
  268. Instead, they must be controlled by the user via code. The physics engine will
  269. not move a character body.
  270. When moving a character body, you should not set its ``position`` directly.
  271. Instead, you use the ``move_and_collide()`` or ``move_and_slide()`` methods.
  272. These methods move the body along a given vector, and it will instantly stop
  273. if a collision is detected with another body. After the body has collided,
  274. any collision response must be coded manually.
  275. Character collision response
  276. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  277. After a collision, you may want the body to bounce, to slide along a wall,
  278. or to alter the properties of the object it hit. The way you handle collision
  279. response depends on which method you used to move the CharacterBody2D.
  280. :ref:`move_and_collide <class_PhysicsBody2D_method_move_and_collide>`
  281. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  282. When using ``move_and_collide()``, the function returns a
  283. :ref:`KinematicCollision2D <class_KinematicCollision2D>` object, which contains
  284. information about the collision and the colliding body. You can use this
  285. information to determine the response.
  286. For example, if you want to find the point in space where the collision
  287. occurred:
  288. .. tabs::
  289. .. code-tab:: gdscript GDScript
  290. extends PhysicsBody2D
  291. var velocity = Vector2(250, 250)
  292. func _physics_process(delta):
  293. var collision_info = move_and_collide(velocity * delta)
  294. if collision_info:
  295. var collision_point = collision_info.get_position()
  296. .. code-tab:: csharp
  297. using Godot;
  298. public partial class Body : PhysicsBody2D
  299. {
  300. private Vector2 _velocity = new Vector2(250, 250);
  301. public override void _PhysicsProcess(double delta)
  302. {
  303. var collisionInfo = MoveAndCollide(_velocity * (float)delta);
  304. if (collisionInfo != null)
  305. {
  306. var collisionPoint = collisionInfo.GetPosition();
  307. }
  308. }
  309. }
  310. Or to bounce off of the colliding object:
  311. .. tabs::
  312. .. code-tab:: gdscript GDScript
  313. extends PhysicsBody2D
  314. var velocity = Vector2(250, 250)
  315. func _physics_process(delta):
  316. var collision_info = move_and_collide(velocity * delta)
  317. if collision_info:
  318. velocity = velocity.bounce(collision_info.get_normal())
  319. .. code-tab:: csharp
  320. using Godot;
  321. public partial class Body : PhysicsBody2D
  322. {
  323. private Vector2 _velocity = new Vector2(250, 250);
  324. public override void _PhysicsProcess(double delta)
  325. {
  326. var collisionInfo = MoveAndCollide(_velocity * (float)delta);
  327. if (collisionInfo != null)
  328. _velocity = _velocity.Bounce(collisionInfo.GetNormal());
  329. }
  330. }
  331. :ref:`move_and_slide <class_CharacterBody2D_method_move_and_slide>`
  332. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  333. Sliding is a common collision response; imagine a player moving along walls
  334. in a top-down game or running up and down slopes in a platformer. While it's
  335. possible to code this response yourself after using ``move_and_collide()``,
  336. ``move_and_slide()`` provides a convenient way to implement sliding movement
  337. without writing much code.
  338. .. warning:: ``move_and_slide()`` automatically includes the timestep in its
  339. calculation, so you should **not** multiply the velocity vector
  340. by ``delta``. This does **not** apply to ``gravity`` as it is an
  341. acceleration and is time dependent, and needs to be scaled by
  342. ``delta``.
  343. For example, use the following code to make a character that can walk along
  344. the ground (including slopes) and jump when standing on the ground:
  345. .. tabs::
  346. .. code-tab:: gdscript GDScript
  347. extends CharacterBody2D
  348. var run_speed = 350
  349. var jump_speed = -1000
  350. var gravity = 2500
  351. func get_input():
  352. velocity.x = 0
  353. var right = Input.is_action_pressed('ui_right')
  354. var left = Input.is_action_pressed('ui_left')
  355. var jump = Input.is_action_just_pressed('ui_select')
  356. if is_on_floor() and jump:
  357. velocity.y = jump_speed
  358. if right:
  359. velocity.x += run_speed
  360. if left:
  361. velocity.x -= run_speed
  362. func _physics_process(delta):
  363. velocity.y += gravity * delta
  364. get_input()
  365. move_and_slide()
  366. .. code-tab:: csharp
  367. using Godot;
  368. public partial class Body : CharacterBody2D
  369. {
  370. private float _runSpeed = 350;
  371. private float _jumpSpeed = -1000;
  372. private float _gravity = 2500;
  373. private void GetInput()
  374. {
  375. var velocity = Velocity;
  376. velocity.X = 0;
  377. var right = Input.IsActionPressed("ui_right");
  378. var left = Input.IsActionPressed("ui_left");
  379. var jump = Input.IsActionPressed("ui_select");
  380. if (IsOnFloor() && jump)
  381. velocity.Y = _jumpSpeed;
  382. if (right)
  383. velocity.X += _runSpeed;
  384. if (left)
  385. velocity.X -= _runSpeed;
  386. Velocity = velocity;
  387. }
  388. public override void _PhysicsProcess(double delta)
  389. {
  390. var velocity = Velocity;
  391. velocity.Y += _gravity * (float)delta;
  392. Velocity = velocity;
  393. GetInput();
  394. MoveAndSlide();
  395. }
  396. }
  397. See :ref:`doc_kinematic_character_2d` for more details on using ``move_and_slide()``,
  398. including a demo project with detailed code.