Files
Papay-Shooter/debug/visual_capture.gd
T
2026-08-02 02:20:02 -04:00

90 lines
2.9 KiB
GDScript

extends SceneTree
## Dev tool: launch with rendering, screenshot the main menu and a level,
## then quit. Run:
## godot --path . -s res://debug/visual_capture.gd -- <output_dir> [scene_path]
## Screenshots land in <output_dir>/shot_menu.png, shot_level.png, shot_tp_run.png
## and shot_aerial.png. scene_path defaults to the test level.
var _frames := 0
var _out_dir := "."
var _scene := "res://scenes/maps/test_level/test_level.tscn"
func _initialize() -> void:
var args := OS.get_cmdline_user_args()
if args.size() > 0:
_out_dir = args[0]
if args.size() > 1:
_scene = args[1]
if not _out_dir.is_absolute_path():
_out_dir = ProjectSettings.globalize_path(_out_dir)
var mkdir_error := DirAccess.make_dir_recursive_absolute(_out_dir)
if mkdir_error != OK:
printerr("visual_capture: could not create '%s' (error %d)" % [
_out_dir, mkdir_error])
quit(mkdir_error)
return
change_scene_to_file("res://ui/main_menu/main_menu.tscn")
func _process(_delta: float) -> bool:
_frames += 1
if _frames == 60:
_shot("menu")
var nm = root.get_node_or_null("NetworkManager")
if nm and nm.has_method("start_singleplayer_match"):
nm.start_singleplayer_match(GameMode.DEATHMATCH)
change_scene_to_file(_scene)
elif _frames == 240:
_shot("level")
# Third person + run forward, to eyeball model grounding and animation
for p in root.find_children("*", "CharacterBody3D", true, false):
if p.has_method("set_third_person") and p.is_multiplayer_authority():
p.set_third_person(true)
Input.action_press("move_forward")
elif _frames == 300:
_shot("tp_run")
Input.action_release("move_forward")
elif _frames == 338:
_shot("tp_idle")
# Aerial overview of the whole map
var cam := root.get_camera_3d()
if cam:
var aerial := Camera3D.new()
current_scene.add_child(aerial)
if _scene.contains("neon_alley"):
aerial.far = 2000.0
aerial.global_position = Vector3(0, 400, 300)
else:
aerial.global_position = Vector3(0, 55, 42)
aerial.look_at(Vector3(0, 0, -5), Vector3.UP)
aerial.current = true
elif _frames == 340:
_shot("aerial")
# Fixed street-level view for deterministic style comparisons
var cam := root.get_camera_3d()
if cam:
cam.global_position = Vector3(3, 2.2, 20)
cam.look_at(Vector3(-8, 4, -18), Vector3.UP)
elif _frames == 360:
_shot("street")
# Let the loaded scene and RenderingServer resources drain before the
# process exits. Large CSG maps can still have deferred frees queued on
# the exact frame of the last screenshot.
unload_current_scene()
elif _frames == 480:
return true
return false
func _shot(tag: String) -> void:
var img := root.get_viewport().get_texture().get_image()
var path := _out_dir + "/shot_" + tag + ".png"
var save_error := img.save_png(path)
if save_error == OK:
print("visual_capture: saved ", path)
else:
printerr("visual_capture: could not save '%s' (error %d)" % [
path, save_error])