Godot Version
4.3
Question
Hello Godoteers! It seems that 4.3 has broken some Path3D spawning logic that was working for me in 4.2 and after playing around with it for a few hours I am lost on what the problem could be and thus am stuck. Did something change with spawning along a Path3D in 4.3 and I missed it? Any help would be greatly appreciated!
Problem
In my project I have a Path3D that spawns 10 instantiated scene (zombies and a roadblock) along the PathFollow3D (see code below). This was working correctly in 4.2 but when I upgraded to 4.3 (and made no other changes to this code!) all 10 instantiated scenes spawn on top of each other instead of being equally distributed along the Path.
4.2
see how the roadblocks and “zombies” are spawned along the path around the track
4.3
see how the roadblocks and “zombies” are spawned all on top of each other
Debug Method
I made two copies of a 4.2 version of my project (same spawning code as my latest version) and opened it in 4.2 and the spawning works correctly (instantiated scenes equally distributed along Path3D) and I upgraded the other copy to 4.3. This clearly shows that with no other changes made something changed in the 4.3 to break the spawning.
I recreated the Path3D and PathFollow3D in 4.3 but the problem still persists.
This leads me to believe that 4.3 doesn’t like something in my code.
Any ideas on what could be wrong and how I fix it?
Scene Tree
main_world.gd
extends Node3D
var zombie_road_block_scene = preload("res://assets/zombie_road_block.tscn")
func _on_zombie_spawner_area_3d_vehicle_entered_zombie_spawner():
print("_on_zombie_spawner_area_3d_vehicle_entered_zombie_spawner called")
# Remove existing roadblocks from the world
for child in get_children():
if child.has_node("roadblock"):
child.get_node("roadblock").queue_free()
# Spawn road blocks
var progress_step = 1.0 / 10.0 # Divide the range of progress ratios into 10 equal parts
var current_progress = 0.0 # Start at the beginning of the path
for i in range(10): # Spawn 10 road blocks
var zombie_road_block = zombie_road_block_scene.instantiate()
var road_block_spawn_location = get_node_or_null("ZombieSpawnPath/ZombieSpawnLocation")
## Find roadblock spawn location debug
#if road_block_spawn_location:
#print("Spawn location found: ", road_block_spawn_location.global_transform.origin)
#else:
#print("Spawn location not found!")
# Create a new transform based on the road_block_spawn_location and remove the offset
var spawn_transform = Transform3D(road_block_spawn_location.global_transform.basis, Vector3.ZERO)
spawn_transform.origin = road_block_spawn_location.global_transform.origin - Vector3(0, 0, 5) # Subtract the -5 Z-axis offset
# Assign a progress ratio from one of the 10 equal parts with some randomness
road_block_spawn_location.progress_ratio = current_progress + randf() * progress_step * 0.5
var path_direction = road_block_spawn_location.global_transform.basis.z
## Ray cast position debug
#Get the path direction at the current progress ratio
#var debug_raycast = debug_raycast_scene.instantiate()
#debug_raycast.global_transform.origin = spawn_transform.origin
#add_child(debug_raycast)
# Generate random offsets perpendicular to the path direction
var random_magnitude = randf_range(-1, 1) # Random magnitude for the offset
var perpendicular_direction = path_direction.cross(Vector3.UP).normalized() # Perpendicular to the path direction
var offset = perpendicular_direction * random_magnitude # Offset is now correctly perpendicular to the path
# Apply the offset to the spawn location
spawn_transform.origin += offset
# Generate a random rotation angle in degrees, excluding 330-30, 60-120, 150-210, and 240-300 degrees
var random_rotation_degrees
while true:
random_rotation_degrees = randi() % 360
if (random_rotation_degrees >= 30 and random_rotation_degrees < 60) or \
(random_rotation_degrees >= 120 and random_rotation_degrees < 150) or \
(random_rotation_degrees >= 210 and random_rotation_degrees < 240) or \
(random_rotation_degrees >= 300 and random_rotation_degrees < 330):
break
# Convert the rotation angle to radians
var random_rotation = deg_to_rad(random_rotation_degrees)
# Create a new transform for the zombie_road_block with the random rotation
var zombie_road_block_transform = Transform3D()
zombie_road_block_transform = zombie_road_block_transform.rotated(Vector3.UP, random_rotation)
zombie_road_block_transform.origin = spawn_transform.origin
# Apply the new transform to the zombie_road_block
zombie_road_block.global_transform = zombie_road_block_transform
zombie_road_block.scale = Vector3(7.3, 7.3, 7.3)
add_child(zombie_road_block)
## Set the vehicle reference for each zombie and connect signals
zombie_road_block.get_node("zombie_a").vehicle = fiesta_vehicle
zombie_road_block.get_node("zombie_b").vehicle = fiesta_vehicle
zombie_road_block.get_node("zombie_c").vehicle = fiesta_vehicle
zombie_road_block.get_node("zombie_a").sfx_zombie_run_over = sfx_zombie_run_over
zombie_road_block.get_node("zombie_b").sfx_zombie_run_over = sfx_zombie_run_over
zombie_road_block.get_node("zombie_c").sfx_zombie_run_over = sfx_zombie_run_over
for zombie in zombie_road_block.get_children():
if zombie.is_in_group("Enemies"):
zombie.vehicle = fiesta_vehicle
zombie.zombie_killed.connect(hud._on_zombie_killed)
zombie.zombie_melee_attack.connect(vehicle_parent.zombie_melee_attack)
# Move to the next part of the progress range for the next road block
current_progress += progress_step