draw line in 3D

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By swipis
:warning: Old Version Published before Godot 3 was released.

Hello, how to draw simple line from point A to point B in 3D, I need to draw simple line from player to collision point. Need some tips how to “draw” in 3D space.
Thank you!

:bust_in_silhouette: Reply From: volzhs

There is a demo drawing line in 3d.
Download demos and see in demos/3d/navmesh.
You can see a line when moving character if var draw_path = true.

thanks, I will look at that demo

swipis | 2016-04-08 10:06

:bust_in_silhouette: Reply From: tproper

Here is what I’m using now. You AutoLoad the script then can call it by:

ScriptName.Draw_Line3D(id, vector_a, vector_b, color, thickness)

Code:

extends Node2D

class Line:
	
	var id
	var color
	var thickness
	var a = Vector2()
	var b = Vector2()

var Lines
var Camera_Node

func _ready():
	
	Camera_Node = get_viewport().get_camera()
	
	Lines = []
	set_process(true)

func _draw():
	
	for line in Lines:
		
		draw_line(line.a, line.b, line.color, line.thickness)

func _process(delta):
	
	update()

func Draw_Line3D(id, vector_a, vector_b, color, thickness):
	
	for line in Lines:
		if line.id == id:
			line.color = color
			line.a = Camera_Node.unproject_position(vector_a)
			line.b = Camera_Node.unproject_position(vector_b)
			line.thickness = thickness
			return
	
	var new_line = Line.new()
	new_line.id = id
	new_line.color = color
	new_line.a = Camera_Node.unproject_position(vector_a)
	new_line.b = Camera_Node.unproject_position(vector_b)
	new_line.thickness = thickness
	
	Lines.append(new_line)

Remove_Line(id):
    	
    	var i = 0
    	var found = false
    	for line in Lines:
    		
    		if line.id == id:
    			found = true
    			break
    		i += 1
    	
    	if found:
    		
    		Lines.remove(i)

This script is very nice but you might want to unproject the positions insde the draw function so that lines stay at their original world position when the camera moves.

Benjamin Navarro | 2020-06-02 15:51

Nice I’ve updated your code so it update with camera movement, the only problem is if the lines go behind the camera they get inverted and show up going away from the camera. I’m only using it for debug purposes so I don’t necessarily mind that it happens
Code:


extends Node2D
class Line:
var id
var color
var thickness
var a3d = Vector3()
var b3d = Vector3()
var a = Vector2()
var b = Vector2()
var Lines
var Camera_Node
func _ready():
Camera_Node = get_viewport().get_camera()
Lines =
set_process(true)

func _draw():
for line in Lines:
line.a = Camera_Node.unproject_position(line.a3d)
line.b = Camera_Node.unproject_position(line.b3d)
draw_line(line.a, line.b, line.color, line.thickness)
func _process(delta):
update()

func Draw_Line3D(id, vector_a, vector_b, color, thickness):
for line in Lines:
if line.id == id:
line.color = color
line.a3d = vector_a
line.b3d = vector_b
line.a = Camera_Node.unproject_position(vector_a)
line.b = Camera_Node.unproject_position(vector_b)
line.thickness = thickness
return
var new_line = Line.new()
new_line.id = id
new_line.color = color
new_line.a = Camera_Node.unproject_position(vector_a)
new_line.b = Camera_Node.unproject_position(vector_b)
new_line.thickness = thickness
Lines.append(new_line)
func Remove_Line(id):
var i = 0
var found = false
for line in Lines:
if line.id == id:
found = true
break
i += 1
if found:
Lines.remove(i)

Chevon | 2021-10-25 04:03

:bust_in_silhouette: Reply From: stronk

If someone was searching for 3D line that allows you to have texture on it then you can try this: GitHub - jegor377/Line3D: Line3D in godot.

:bust_in_silhouette: Reply From: miivers

This is how I am drawing lines. This draws a line for each pair of Vector3 in the list points. Change Mesh.PrimitiveType.Lines to Mesh.PrimitiveType.LineStrip for a continues line between each point.

using Godot;
using System.Collections.Generic;

namespace Utility
{
    class LineDrawer3d : ImmediateGeometry
    {
        List<Vector3> points = new List<Vector3>();


        public void addLine(Vector3 p1, Vector3 p2)
        {
            points.Add(p1);
            points.Add(p2);
        }


        public override void _Process(float delta)
        {
            base._Process(delta);

            Clear();

            Begin(Mesh.PrimitiveType.Lines);

            for (int i = 0; i < points.Count; ++i)
            {
                AddVertex(points[i]);
            }

            End();
        }
    }
}