How to make a 3D physical trail

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Kallistotele

I want a Trail3D to detect collisions, the trail is rendered on both sides and it’s very similar to the trail from tron’s lightcycles. I tried to instanciate Areas behind the player while it’s moving, but it’s not precise and having a lot of them causes lag.

You could probably use something like an ArrayMesh to draw the trails and use the create_trimesh_collision() function and update the vertex position every frame to create that effect

Kurotsuki | 2021-03-09 12:09

The node I’m using is a ImmediateGeometry node, to emit the trail it uses begin(Mesh.PRIMITIVE_TRIANGLE_STRIP). I created a var trail = Mesh.PRIMITIVE_TRIANGLE_STRIP and I tried to call createtrimeshcollision() but for some reason the variable is a int type…
How can I store the mesh into the variable? Or should I try something else?
EDIT: Ok, Mesh.PRIMITIVE_TRIANGLE_STRIP is an enum, so I guess there’s no way to make it work from this type of node

func _render_geometry(source: Array) -> void:
"""
Base function for rendering the generated geometry to the screen.
Renders the trail, and the wireframe if set in parameters.
"""
var points_count = source.size()
if points_count < 2:
	return

# The following section is a hack to make orientation "view" work.
# but it may cause an artifact at the end of the trail.
# You can use transparency in the gradient to hide it for now.
var _d :Vector3 = source[0].transform.origin - source[1].transform.origin
var _t :Transform = source[0].transform
_t.origin = _t.origin + _d
var point = Point.new(_t, source[0].age)
var to_be_rendered = [point]+source
points_count += 1

var half_width :float = base_width/2.0
var wire_points = []
var u := 0.0

clear()
begin(trail, null)
trail.create_trimesh_collision()

This is not the entire script of course

Kallistotele | 2021-03-11 11:45

I figured it out, I made my own script and it works fine.
I’ll show the code for everyone who has the same project, the material culling must be disabled to render the trail and keep in mind that get_child(1) refers to the collision box.

extends MeshInstance

var target

var surfTool = SurfaceTool.new()
var material = SpatialMaterial.new()
var m = Mesh.new()
var p
var l = 0.1
var current_vertex = 0
var prev_point1 = Vector3.ZERO
var prev_point2 = Vector3.ZERO
var wr

var is_target = false
	
func set_target(t : KinematicBody):
target = t
p = target.global_transform.origin
prev_point1 = Vector3(p.x,p.y+l,p.z)
prev_point2 = Vector3(p.x,p.y-l,p.z)
wr = weakref(target)
is_target = true
	
func set_color(c: Color):
material.albedo_color = c
material.emission = c

func _ready():
surfTool.set_material(material)
material.vertex_color_use_as_albedo = true
material.CULL_DISABLED

func _process(delta):
if is_target:
	surfTool.begin(Mesh.PRIMITIVE_TRIANGLES)
	if wr.get_ref():
		p = target.global_transform.origin
	surfTool.add_vertex(prev_point1)
	surfTool.add_vertex(prev_point2)
	
	surfTool.add_vertex(Vector3(p.x,p.y+l,p.z))
	prev_point1 = Vector3(p.x,p.y+l,p.z)
	
	surfTool.add_vertex(Vector3(p.x,p.y-l,p.z))
	prev_point2 = Vector3(p.x,p.y-l,p.z)

	surfTool.add_index(0)
	surfTool.add_index(1)
	surfTool.add_index(2)
		
	surfTool.add_index(1)
	surfTool.add_index(2)
	surfTool.add_index(3)

	surfTool.commit(m)
	set_mesh(m)
	get_parent().get_child(1).shape = mesh.create_trimesh_shape()

Kallistotele | 2021-03-15 08:31