Line3D
August 15, 2024

The Line3D plugin offers means to draw lines in 3D. Lines are drawn either for a single iteration frame or last on screen for the specified amount of seconds.

Please note, this is meant for debugging purposes. The performance is not suitable to build final release product graphics.

By default, the release build of this plugin makes all functions empty. This means that those functions can be called but will do nothing in the exported project. This can be useful to keep debugging code in place while making sure none of it will appear in the release builds. Note that custom builds of the extension pack can still change this behavior if so desired.

Why

Often we want to quickly visualize vectors while debugging. In 3D this is obviously no different. While Godot do offer means to programmatically create such lines, the way it's done requires a bit of code. This plugin is meant to simplify the task of drawing debugging lines.

Usage

This plugin contains a single class, Line3D and its usage is extremely simple. The Line3D is provided as a singleton, meaning that its functions can be directly used.

To draw a line there is the add_line() function, which requires two arguments plus and optional one. The first two arguments are the global positions of the end points of the line (segment). Perhaps this function should have been named add_line_segment(), but this is a bit too pedantic, so yeah! That said, the optional argument is used to specify the color in which the line will be drawn. It defaults to white.

Now suppose you have two positions stored in Vector3 variables (p1 and p2) and you want to draw a red line connecting those two points. Simply call:

Line3D.add_line(p1, p2, Color.RED)

This will draw a line that will last for a single frame. In other words, on the next update the line will disappear! This is done because the idea is to show lines for things that do change frequently, like direction vectors, ray casts and so on. With that in mind, if you want the line connecting those two points to remain more time on screen you either keep calling add_line() or call add_timed_line() function.

The add_timed_line() requires three arguments plus the optional color. The extra required argument is the time, in seconds, in which the line should remain on screen. So, let's add a green line that will disappear after 2.5 seconds:

Line3D.add_timed_line(p1, p2, 2.5 Color.GREEN)

Note that those two functions require "end points". This means that from a point and a direction, it's necessary to calculate the second end point. OK, it's a rather trivial calculation to be done. Yet I decided to add functions that take a point and a direction vector instead of two end points. Note that the vector is expected to have its length correctly set. So, supposing we have a point p0 and a direction vector dir, let's add two lines, one that lasts for a single frame and another that lasts 2.5 seconds:

# In here assuming that dir is a unit vector. The end goal is to draw a line of size 1.5
Line3D.add_from_vector(p0, dir * 1.5, Color.YELLOW)

# Same line length, but this will disappear after 2.8 seconds
Line3D.add_timed_from_vector(p0, dir * 1.5, 2.8, Color.BLUE)

It's possible to disable the functionality of this plugin (basically its internal processing) while still being able to access it. When it's disabled, calling add_line() or add_timed_line() will do nothing! This means it's not necessary to delete debug code that draws extra stuff on screen, just disable its processing. Alternatively you can access its enabled property. Re-enabling is also very easy:

# Disable Line3D
Line3D.disable()
# And enable it back
Line3D.enable()
# Or using its property
Line3D.enabled = true

It's possible to test if the processing is enabled or not by calling is_enabled():

if Line3D.is_enabled():
   # Do something if line is enabled
else
   # Do something else if not enabled

Depending on the situation it might be desired to remove all lines, specially the timed ones. This can be done by calling clear_lines():

Line3D.clear_lines()

Other

Note that I have mentioned that this plugin uses internal processing. If you are not new to Godot, you know that it offers _process() and _physics_process() to perform processing. If you are new, I have written about it here . Nevertheless, this plugin allows you to choose which processing will be used to deal with the lines. To do that, open Project Settings -> Keh Extension Pack -> Debug Line 3D. There is a single boolean in there, named Use Physics Process. If it's checked it will "tell" the plugin to use the physics iterations to update the lines. By default lines will be processed using the "idle frame" (in other words this option is not checked).

As I have mentioned in the introduction of this plugin, by default the release build makes the Line3D empty. Calling Line3D.enable() will not change any behavior of this class simply because it doesn't contain any code. Yet, if you decide to use a custom build of the extension pack where this debugging class is not empty in release builds, you still can disable its functionality through code, which might be useful to find potential errors that appear only in release builds.