Traffic Jam!




Devlog: Visual Waypoint System for My Crazy Taxi Clone in Godot
The Problem
Working on my Crazy Taxi clone in Godot, I needed a way to see the paths my AI traffic would follow. I had a basic setup with a parent node holding Marker3D waypoints, but I couldn’t see how they connected in the editor. This made designing routes and spotting issues a pain. I wanted a clear, editor-only view using @tool
to make path creation and debugging easier.
Attempt 1: No Line3D
I hunted for a Line3D
node, thinking it’d be perfect for drawing 3D paths. Turns out, Godot doesn’t have one, so I had to rethink my approach.
Attempt 2: Editor Plugin
I tried building a custom editor plugin to draw lines in the 3D viewport:
func _forward_3d_draw_over_viewport(overlay):
for node in EditorInterface.get_selection().get_selected_nodes():
if node.has_method("get_waypoints"):
_draw_waypoint_lines(overlay, node)
It worked, sorta, but it was a hassle to set up and only showed lines when I selected the waypoint system.
Solution: Path3D
Then it hit me—Godot’s Path3D
with Curve3D
was exactly what I needed. It’s built-in, simple, and shows paths right in the editor:
@tool
extends Node3D
@export var update_path: bool = false : set = _update_path_from_waypoints
func _build_path():
var curve = Curve3D.new()
for waypoint in waypoints:
curve.add_point(to_local(waypoint.global_position))
if loop_path:
curve.add_point(to_local(waypoints[0].global_position))
path_node.curve = curve
Better Visualization
To make the paths pop, I added a CSGPolygon3D
for a thick, cyan tube along the path:
@export var show_path_mesh: bool = true
@export var path_thickness: float = 0.1
func _update_path_mesh():
path_mesh = CSGPolygon3D.new()
path_mesh.mode = CSGPolygon3D.MODE_PATH
path_mesh.path_node = path_node.get_path()
var polygon = PackedVector2Array()
for i in 8:
var angle = i * 2.0 * PI / 8
polygon.append(Vector2(cos(angle), sin(angle)) * path_thickness)
path_mesh.polygon = polygon
How It Changed My Workflow
This setup made designing levels so much better. I can drop Marker3D waypoints around the map, toggle update_path
to see the full path instantly, move waypoints to tweak the route, and spot problems like weird turns right away. The AI Traffic is programming to turn using linear interpolation so the fact that the paths above are straight lines do not matter. They will do tight turns, but that seems more arcadey. Besides, the traffic is not the main feature, it's only meant to be an obstacle in the game.
AI Traffic Integration
The AI traffic use this system to navigate. They can find the closest waypoint:
func get_closest_index(position: Vector3) -> int:
var closest_index := -1
var closest_dist := INF
for i in waypoints.size():
var dist = position.distance_to(waypoints[i].global_position)
if dist < closest_dist:
closest_dist = dist
closest_index = i
return closest_index
If a taxi gets knocked off course, it finds the nearest waypoint, jumps back on the path, and keeps going without starting over.
This Path3D
system made building AI paths for my Crazy Taxi clone way easier, using Godot’s own tools to keep things clean and manageable.
Files
Get Uber Munch
Uber Munch
Pickup, Drive, Deliver! Those Customers Need Their Food!
Status | In development |
Author | lukasaurus |
Genre | Racing |
Tags | delivery, Driving |
More posts
- Building the City28 days ago
Leave a comment
Log in with itch.io to leave a comment.