I created a racetrack with Path3D and want some fences and stugg at the sides. I sawe a video about a script with CSGPolygon#D but Is it also possible another way?
Someone who can help me with some other kind of tutorial?
CSGPolygon3D is a great option for path-following geometry without scripts. With a script one could create meshes along the path by sampling points on the Path3D’s curve.
I only can not find some tutorial of placing objects besides the road. I dont have to place it everywhere but every few meters.
Now I saw this tutorial (https://www.youtube.com/watch?v=4nOEVPjVmjc)but that is not working for version 4.3 or 4.4 if Im right. Anyone know if there are more tutorials like this? Or example games.
@tool
extends Path3D
@export_range(0, 100) var item_count = 1:
set (value):
item_count = value
spawn_item()
get:
return item_count
func spawn_item():
var offsets = []
var points = curve.get_baked_points()
var upvectors = curve.get_baked_up_vectors()
for child in $Spawn.get_children():
child.free()
for i in range(item_count):
offsets.append(float(1)/float(item_count+1))
for offset_idx in range(offsets.size()):
var idx = clamp(int(points.size()*(offsets[offset_idx])), 0.0, points.size()-1)
var point = points[idx]
var upVector = upvectors [idx]
var item_ = Node3D.new()
item_.name = "item_"
$Spawn.add_child(item_)
item_.translate(point)
var fence = preload("res://fence.tscn").instantiate()
fence.name = "fence"
item_.add_child(fence)
fence.translate(Vector3(0.05,0.0,0.0))
if idx+1 > points.size()-1:
item_.look_at(points[0], upVector)
else:
item_.look_at(points[idx+1], upVector)
item_.set_owner(get_tree().get_edited_scene_root())
fence.set_owner(get_tree().get_edited_scene_root())
Thanks for your input. After your change it still did not work.
I restarted the script and now have this what is working. Now every few meters there is a fence and are visible. I go to expand with more code but you helped me a lot.
@tool
extends Path3D
@export var fence_scene = preload("res://fence.tscn")
@export var spacing = 3.0
func _ready():
# Zorg ervoor dat de node "VisibleItems" bestaat
if !$VisibleItems2:
var visible_items = Node3D.new()
visible_items.name = "VisibleItems2"
add_child(visible_items)
spawn_fences()
func spawn_fences():
# Verwijder bestaande hekken van "VisibleItems"
for child in $VisibleItems2.get_children():
child.queue_free()
var points = curve.get_baked_points()
var up_vectors = curve.get_baked_up_vectors()
var distance = 0.0
for i in range(points.size()):
if distance >= spacing:
var fence_instance = fence_scene.instantiate()
fence_instance.translate(points[i])
$VisibleItems2.add_child(fence_instance)
fence_instance.look_at(points[(i + 1) % points.size()], up_vectors[i])
distance = 0.0
distance += points[i].distance_to(points[(i + 1) % points.size()])
Now have this script with a test path, only the fences are not next to the line. How can I let them follow exactly next to the line?
@tool
extends Path3D
@export var fence_scene = preload("res://fence.tscn")
@export var spacing = 3.0
func _ready():
# Zorg ervoor dat de node "VisibleItems" bestaat
if !$VisibleItems2:
var visible_items = Node3D.new()
visible_items.name = "VisibleItems2"
add_child(visible_items)
spawn_fences()
func spawn_fences():
# Verwijder bestaande hekken van "VisibleItems"
for child in $VisibleItems2.get_children():
child.queue_free()
var points = curve.get_baked_points()
var up_vectors = curve.get_baked_up_vectors()
var distance = 0.0
var last_index = 0
for i in range(points.size()):
distance += points[last_index].distance_to(points[i])
if distance >= spacing:
var fence_instance = fence_scene.instantiate()
fence_instance.translate(points[i])
$VisibleItems2.add_child(fence_instance)
var next_index = (i + 1) % points.size()
fence_instance.look_at(points[next_index], up_vectors[i])
fence_instance.rotate_object_local(Vector3(0, 1, 0), curve.get_baked_points()[i].angle_to(Vector3.RIGHT))
distance = 0.0
last_index = i