big
This commit is contained in:
+66
-22
@@ -2,30 +2,46 @@ extends SceneTree
|
||||
|
||||
## Dev tool: screenshot every animation state on the active GLB skin.
|
||||
## Run:
|
||||
## godot --path . --windowed --resolution 1280x720 -s res://debug/anim_capture.gd -- <out_dir> [skin_id]
|
||||
## godot --path . --windowed --resolution 1280x720 -s res://debug/anim_capture.gd -- <out_dir> [skin_id] [unarmed] [tag,tag,...]
|
||||
## Saves anim_<state>.png per state plus mid-action shots for reload/throw.
|
||||
|
||||
var _frames := 0
|
||||
var _out_dir := "."
|
||||
var _skin := "miku"
|
||||
var _unarmed := false
|
||||
var _player: Node = null
|
||||
var _model: Node = null
|
||||
var _cam: Camera3D = null
|
||||
|
||||
# [tag, state, speed, crouch, hold_frames]
|
||||
# [tag, state, speed, crouch, hold_frames, strafe, forward, emote_index]
|
||||
var _states := [
|
||||
["idle", "idle", 0.0, false, 50],
|
||||
["walk", "ground", 2.2, false, 50],
|
||||
["run", "ground", 6.5, false, 50],
|
||||
["sprint", "ground", 12.0, false, 50],
|
||||
["crouch", "ground", 0.0, true, 50],
|
||||
["crouchwalk", "ground", 2.0, true, 50],
|
||||
["fall", "air", 4.0, false, 50],
|
||||
["slide", "slide", 10.0, true, 50],
|
||||
["dash", "dash", 14.0, false, 30],
|
||||
["wallrun", "wall_run", 9.0, false, 50],
|
||||
["grapple", "grapple", 10.0, false, 50],
|
||||
["dance", "idle", 0.0, false, 60],
|
||||
["idle", "idle", 0.0, false, 50, 0.0, 0.0, -1],
|
||||
["walk", "ground", 0.975, false, 50, 0.0, 1.0, -1],
|
||||
["run", "ground", 5.26148, false, 50, 0.0, 1.0, -1],
|
||||
["sprint", "ground", 8.25, false, 50, 0.0, 1.0, -1],
|
||||
["sprint_game_speed", "ground", 12.0, false, 50, 0.0, 1.0, -1],
|
||||
["strafe_walk_back", "ground", 3.0, false, 50, 0.0, -1.0, -1],
|
||||
["strafe_walk_left", "ground", 3.0, false, 50, -1.0, 0.0, -1],
|
||||
["strafe_walk_right", "ground", 3.0, false, 50, 1.0, 0.0, -1],
|
||||
["run_back", "ground", 8.25, false, 50, 0.0, -1.0, -1],
|
||||
["run_left", "ground", 8.25, false, 50, -1.0, 0.0, -1],
|
||||
["run_right", "ground", 8.25, false, 50, 1.0, 0.0, -1],
|
||||
["run_left_game_speed", "ground", 11.0, false, 50, -1.0, 0.0, -1],
|
||||
["run_right_game_speed", "ground", 11.0, false, 50, 1.0, 0.0, -1],
|
||||
["crouch", "ground", 0.0, true, 50, 0.0, 0.0, -1],
|
||||
["crouchwalk", "ground", 0.75, true, 50, 0.0, 1.0, -1],
|
||||
["fall", "air", 4.0, false, 50, 0.0, 1.0, -1],
|
||||
["slide", "slide", 10.0, true, 50, 0.0, 1.0, -1],
|
||||
["dash", "dash", 14.0, false, 30, 0.0, 1.0, -1],
|
||||
["wallrun", "wall_run", 13.0, false, 50, 0.0, 1.0, -1],
|
||||
["wallcling", "wall_cling", 0.0, false, 50, 0.0, 0.0, -1],
|
||||
["wallclimb", "wall_climb", 2.0, false, 50, 0.0, 1.0, -1],
|
||||
["grapple", "grapple", 10.0, false, 50, 0.0, 1.0, -1],
|
||||
["emote_dance", "idle", 0.0, false, 60, 0.0, 0.0, 0],
|
||||
["emote_stretch", "idle", 0.0, false, 60, 0.0, 0.0, 1],
|
||||
["emote_call", "idle", 0.0, false, 60, 0.0, 0.0, 2],
|
||||
["emote_yes", "idle", 0.0, false, 60, 0.0, 0.0, 3],
|
||||
["emote_no", "idle", 0.0, false, 60, 0.0, 0.0, 4],
|
||||
]
|
||||
var _phase := 0 # index into _states, then actions after
|
||||
var _phase_frame := 0
|
||||
@@ -40,6 +56,20 @@ func _initialize() -> void:
|
||||
_out_dir = args[0]
|
||||
if args.size() > 1:
|
||||
_skin = args[1]
|
||||
if args.size() > 2:
|
||||
_unarmed = args[2].to_lower() == "unarmed"
|
||||
if args.size() > 3 and args[3] != "":
|
||||
var wanted := args[3].split(",", false)
|
||||
_states = _states.filter(func(state: Array) -> bool:
|
||||
return String(state[0]) in wanted)
|
||||
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("anim_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")
|
||||
|
||||
|
||||
@@ -75,9 +105,10 @@ func _process(_delta: float) -> bool:
|
||||
_player.global_position = Vector3(0, 1.2, 14)
|
||||
_player.rotation = Vector3.ZERO
|
||||
_model.set_owner_visible(true)
|
||||
# Give the model a weapon so armed poses read.
|
||||
# Optional unarmed pass exposes the authored arm silhouettes used by
|
||||
# idle/dance/emotes instead of covering them with weapon IK.
|
||||
if _model.has_method("set_weapon"):
|
||||
_model.set_weapon("res://weapons/ak47.gd")
|
||||
_model.set_weapon("" if _unarmed else "res://weapons/ak47.gd")
|
||||
# Camera: repositioned per shot (front + side). Model faces -Z.
|
||||
_cam = Camera3D.new()
|
||||
_cam.cull_mask &= ~(1 << 19) # don't render the FP viewmodel layer
|
||||
@@ -91,8 +122,14 @@ func _process(_delta: float) -> bool:
|
||||
# hop needs a real rendered frame in between).
|
||||
if _mode == "states":
|
||||
var s: Array = _states[_phase]
|
||||
if s[0] == "dance" and _model.has_method("set_dancing"):
|
||||
_model.set_dancing(true)
|
||||
if _model.has_method("set_locomotion"):
|
||||
_model.set_locomotion(float(s[5]), float(s[6]), 0.0)
|
||||
if s[0] == "wallrun" and _model.has_method("set_wall_side"):
|
||||
_model.set_wall_side(-1.0)
|
||||
if _model.has_method("set_wall_run_motion"):
|
||||
_model.set_wall_run_motion(Vector3(13.0, 0.0, 0.0))
|
||||
if int(s[7]) >= 0 and _model.has_method("set_dancing"):
|
||||
_model.set_dancing(true, int(s[7]))
|
||||
_model.update_state(s[1], s[2], s[3])
|
||||
_phase_frame += 1
|
||||
var hold: int = int(s[4])
|
||||
@@ -102,7 +139,7 @@ func _process(_delta: float) -> bool:
|
||||
elif _phase_frame >= hold:
|
||||
_snap("anim_" + String(s[0]) + "_s")
|
||||
_cam_to(Vector3(0.4, 0.9, -2.4))
|
||||
if s[0] == "dance" and _model.has_method("set_dancing"):
|
||||
if int(s[7]) >= 0 and _model.has_method("set_dancing"):
|
||||
_model.set_dancing(false)
|
||||
if s[0] == "idle":
|
||||
_debug_gun()
|
||||
@@ -188,7 +225,10 @@ func _process(_delta: float) -> bool:
|
||||
_model.update_state("grapple", 12.0, false)
|
||||
if _model.has_method("set_grapple_target"):
|
||||
# Anchor up and ahead of the player (player faces -Z world).
|
||||
_model.set_grapple_target(_player.global_position + Vector3(1.5, 7.0, -7.0))
|
||||
_model.set_grapple_target(
|
||||
_player.global_position + Vector3(1.5, 7.0, -7.0),
|
||||
Vector3(14.0, 2.0, -4.0),
|
||||
)
|
||||
_phase_frame += 1
|
||||
if _phase_frame == 48:
|
||||
_snap("anim_grapple_zip_f")
|
||||
@@ -222,5 +262,9 @@ func _cam_to(offset: Vector3) -> void:
|
||||
func _snap(tag: String) -> void:
|
||||
var img := root.get_viewport().get_texture().get_image()
|
||||
var path := _out_dir + "/" + tag + ".png"
|
||||
img.save_png(path)
|
||||
print("anim_capture: saved ", path)
|
||||
var save_error := img.save_png(path)
|
||||
if save_error == OK:
|
||||
print("anim_capture: saved ", path)
|
||||
else:
|
||||
printerr("anim_capture: could not save '%s' (error %d)" % [
|
||||
path, save_error])
|
||||
|
||||
Reference in New Issue
Block a user