extends SceneTree ## Physics probe: boot a level headless, raycast forward from the spawn to see ## which colliders exist ahead. Usage: ## Godot --headless --path . --script tests/probe.gd -- level=queen_st_mall func _initialize() -> void: _run() func _run() -> void: var opts := {} for a in OS.get_cmdline_user_args(): var kv := a.split("=") if kv.size() == 2: opts[kv[0]] = kv[1] Game.car_path = Registry.cars().values()[0] var levels := Registry.levels() Game.level_path = levels.get(opts.get("level", ""), levels.values()[0]) Game.mode = "cruise" var game: Game = (load("res://src/game.tscn") as PackedScene).instantiate() root.add_child(game) await process_frame var sp := game.get_child(0).find_child("Spawn", true, false) print("Spawn node: ", sp, " class=", sp.get_class() if sp else "nil", " global=", (sp as Node3D).global_position if sp is Node3D else Vector3.INF) print("car right after ready: ", game.car.global_position) for i in 10: var p: Vector3 = game.car.global_position print("tick %d: y=%.3f vy=%.2f" % [i, p.y, game.car.linear_velocity.y]) await physics_frame var space := game.car.get_world_3d().direct_space_state var from := game.car.global_position + Vector3.UP * 0.5 var fwd := -game.car.global_basis.z print("spawn at ", game.car.global_position, " facing ", fwd) for dist in [5.0, 200.0]: var q := PhysicsRayQueryParameters3D.create(from, from + fwd * dist) q.exclude = [game.car.get_rid()] var hit := space.intersect_ray(q) if hit: print("ray %dm: hit %s at %.1fm" % [dist, hit.collider.get_parent().name if hit.collider.get_parent() else hit.collider.name, from.distance_to(hit.position)]) else: print("ray %dm: clear" % dist) for off in [Vector3.ZERO, Vector3(20, 0, -18)]: var down := PhysicsRayQueryParameters3D.create(from + off, from + off + Vector3.DOWN * 100.0) down.exclude = [game.car.get_rid()] var dh := space.intersect_ray(down) if dh: print("down@%s: hit %s at y=%.2f" % [off, dh.collider.get_parent().name if dh.collider.get_parent() else dh.collider.name, dh.position.y]) else: print("down@%s: NOTHING within 100m" % off) var bodies := 0 for n in game.find_children("*", "StaticBody3D", true, false): bodies += 1 print("static bodies in level: ", bodies) var car := game.car print("basis.y = ", car.global_basis.y, " basis.z = ", car.global_basis.z) for w: Node3D in car.wheels: var wf := w.global_position var q2 := PhysicsRayQueryParameters3D.create(wf, wf - car.global_basis.y * Car.REST) q2.exclude = [car.get_rid()] var h2 := space.intersect_ray(q2) print("wheel %s from y=%.2f: %s" % [w.name, wf.y, ("hit %s y=%.2f" % [h2.collider.get_parent().name, h2.position.y]) if h2 else "MISS"]) quit(0)