123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- .. _doc_custom_performance_monitors:
- Custom performance monitors
- ===========================
- Introduction
- ------------
- As explained in the :ref:`doc_debugger_panel` documentation, Godot features a
- **Debugger > Monitor** bottom panel that allows tracking various values with
- graphs showing their evolution over time. The data for those graphs is sourced
- from the engine's :ref:`class_Performance` singleton.
- Since Godot 4.0, you can declare custom values to be displayed in this Monitor
- tab. Example use cases for custom performance monitors include:
- - Displaying performance metrics that are specific to your project. For
- instance, in a voxel game, you could create a performance monitor to track the
- number of chunks that are loaded every second.
- - Displaying in-game metrics that are not strictly related to performance, but
- are still useful to graph for debugging purposes. For instance, you could
- track the number of enemies present in the game to make sure your spawning
- mechanic works as intended.
- Creating a custom performance monitor
- -------------------------------------
- In this example, we'll create a custom performance monitor to track how many
- enemies are present in the currently running project.
- The main scene features a :ref:`class_Timer` node with the following script attached:
- ::
- extends Timer
- func _ready():
- # The slash delimiter is used to determine the category of the monitor.
- # If there is no slash in the monitor name, a generic "Custom" category
- # will be used instead.
- Performance.add_custom_monitor("game/enemies", get_enemy_count)
- timeout.connect(_on_timeout)
- # Spawn 20 enemies per second.
- wait_time = 0.05
- start()
- func _on_timeout():
- var enemy = preload("res://enemy.tscn").instantiate()
- get_parent().add_child(enemy)
- # This function is called every time the performance monitor is queried
- # (this occurs once per second in the editor, more if called manually).
- # The function must return a number greater than or equal to 0 (int or float).
- func get_enemy_count():
- return get_tree().get_nodes_in_group("enemies").size()
- The second parameter of
- ref:`Performance.add_custom_monitor<class_Performance_method_add_custom_monitor>`
- is a :ref:`class_Callable`.
- ``enemy.tscn`` is a scene with a Node2D root node and Timer child node. The
- Node2D has the following script attached:
- ::
- extends Node2D
- func _ready():
- add_to_group("enemies")
- $Timer.timeout.connect(_on_timer_timeout)
- # Despawn enemies 2.5 seconds after they spawn.
- $Timer.wait_time = 2.5
- $Timer.start()
- func _on_timer_timeout():
- queue_free()
- In this example, since we spawn 20 enemies per second, and each enemy despawns
- 2.5 seconds after they spawn, we expect the number of enemies present in the
- scene to stabilize to 50. We can make sure about this by looking at the graph.
- To visualize the graph created from this custom performance monitor, run the
- project, switch to the editor while the project is running and open **Debugger >
- Monitors** at the bottom of the editor window. Scroll down to the newly
- available **Game** section and check **Enemies**. You should see a graph
- appearing as follows:
- .. :figure: img/custom_performance_monitors_graph_example.webp
- :align: center
- :alt: Example editor graph from a custom performance monitor
- Example editor graph from a custom performance monitor
- .. note::
- The performance monitor handling code doesn't have to live in the same
- script as the nodes themselves. You may choose to move the performance
- monitor registration and getter function to an :ref:`autoload
- <doc_singletons_autoload>` instead.
- Querying a performance monitor in a project
- -------------------------------------------
- If you wish to display the value of the performance monitor in the running
- project's window (rather than the editor), use
- ``Performance.get_custom_monitor("category/name")`` to fetch the value of the
- custom monitor. You can display the value using a :ref:`class_Label`,
- :ref:`class_RichTextLabel`, :ref:`doc_custom_drawing_in_2d`, :ref:`doc_3d_text`,
- etc.
- This method can be used in exported projects as well (debug and release mode),
- which allows you to create visualizations outside the editor.
|