custom_performance_monitors.rst 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. .. _doc_custom_performance_monitors:
  2. Custom performance monitors
  3. ===========================
  4. Introduction
  5. ------------
  6. As explained in the :ref:`doc_debugger_panel` documentation, Godot features a
  7. **Debugger > Monitor** bottom panel that allows tracking various values with
  8. graphs showing their evolution over time. The data for those graphs is sourced
  9. from the engine's :ref:`class_Performance` singleton.
  10. Since Godot 4.0, you can declare custom values to be displayed in this Monitor
  11. tab. Example use cases for custom performance monitors include:
  12. - Displaying performance metrics that are specific to your project. For
  13. instance, in a voxel game, you could create a performance monitor to track the
  14. number of chunks that are loaded every second.
  15. - Displaying in-game metrics that are not strictly related to performance, but
  16. are still useful to graph for debugging purposes. For instance, you could
  17. track the number of enemies present in the game to make sure your spawning
  18. mechanic works as intended.
  19. Creating a custom performance monitor
  20. -------------------------------------
  21. In this example, we'll create a custom performance monitor to track how many
  22. enemies are present in the currently running project.
  23. The main scene features a :ref:`class_Timer` node with the following script attached:
  24. ::
  25. extends Timer
  26. func _ready():
  27. # The slash delimiter is used to determine the category of the monitor.
  28. # If there is no slash in the monitor name, a generic "Custom" category
  29. # will be used instead.
  30. Performance.add_custom_monitor("game/enemies", get_enemy_count)
  31. timeout.connect(_on_timeout)
  32. # Spawn 20 enemies per second.
  33. wait_time = 0.05
  34. start()
  35. func _on_timeout():
  36. var enemy = preload("res://enemy.tscn").instantiate()
  37. get_parent().add_child(enemy)
  38. # This function is called every time the performance monitor is queried
  39. # (this occurs once per second in the editor, more if called manually).
  40. # The function must return a number greater than or equal to 0 (int or float).
  41. func get_enemy_count():
  42. return get_tree().get_nodes_in_group("enemies").size()
  43. The second parameter of
  44. ref:`Performance.add_custom_monitor<class_Performance_method_add_custom_monitor>`
  45. is a :ref:`class_Callable`.
  46. ``enemy.tscn`` is a scene with a Node2D root node and Timer child node. The
  47. Node2D has the following script attached:
  48. ::
  49. extends Node2D
  50. func _ready():
  51. add_to_group("enemies")
  52. $Timer.timeout.connect(_on_timer_timeout)
  53. # Despawn enemies 2.5 seconds after they spawn.
  54. $Timer.wait_time = 2.5
  55. $Timer.start()
  56. func _on_timer_timeout():
  57. queue_free()
  58. In this example, since we spawn 20 enemies per second, and each enemy despawns
  59. 2.5 seconds after they spawn, we expect the number of enemies present in the
  60. scene to stabilize to 50. We can make sure about this by looking at the graph.
  61. To visualize the graph created from this custom performance monitor, run the
  62. project, switch to the editor while the project is running and open **Debugger >
  63. Monitors** at the bottom of the editor window. Scroll down to the newly
  64. available **Game** section and check **Enemies**. You should see a graph
  65. appearing as follows:
  66. .. :figure: img/custom_performance_monitors_graph_example.webp
  67. :align: center
  68. :alt: Example editor graph from a custom performance monitor
  69. Example editor graph from a custom performance monitor
  70. .. note::
  71. The performance monitor handling code doesn't have to live in the same
  72. script as the nodes themselves. You may choose to move the performance
  73. monitor registration and getter function to an :ref:`autoload
  74. <doc_singletons_autoload>` instead.
  75. Querying a performance monitor in a project
  76. -------------------------------------------
  77. If you wish to display the value of the performance monitor in the running
  78. project's window (rather than the editor), use
  79. ``Performance.get_custom_monitor("category/name")`` to fetch the value of the
  80. custom monitor. You can display the value using a :ref:`class_Label`,
  81. :ref:`class_RichTextLabel`, :ref:`doc_custom_drawing_in_2d`, :ref:`doc_3d_text`,
  82. etc.
  83. This method can be used in exported projects as well (debug and release mode),
  84. which allows you to create visualizations outside the editor.