extends SceneTree ## Dev tool: how abruptly does the model change posture when you start running? ## ## godot --headless --path . -s res://debug/transition_check.gd -- [skin_glb] ## ## Accelerates from a standstill the way the movement code does, then stops, and ## logs the clip in play plus the body's forward lean each frame. Reports the ## worst single-frame change in lean and how long the lean took to arrive. ## ## Written for "idle to running snaps the character leaning forward". The lean ## is procedural (ShooterPoseModifier), so it does NOT come from the clip ## crossfade and is not visible in an animation-blend graph — it was driven by a ## normalised input direction that steps 0 -> 1 the instant a key goes down, ## planting a full run posture in ~0.1 s while the Idle->Run crossfade still had ## 0.4 s to run. const ACCEL := 18.0 # m/s^2, roughly the controller's ground acceleration const TOP := 9.0 # m/s const DT := 1.0 / 60.0 var _t := 0.0 var _frames := 0 var _model: SkinnedPlayerModel = null var _speed := 0.0 var _prev_lean := 0.0 var _worst_step := 0.0 var _clip_changes: Array = [] var _last_clip := "" var _t_10 := -1.0 var _t_90 := -1.0 var _peak := 0.0 func _initialize() -> void: var args := OS.get_cmdline_user_args() var path: String = args[0] if args.size() > 0 \ else "res://assets/characters/skins/taila.glb" var scene := Node3D.new() root.add_child(scene) current_scene = scene _model = SkinnedPlayerModel.new() _model.model_path = path scene.add_child(_model) func _process(_delta: float) -> bool: _frames += 1 if _frames < 8: return false if not _model.loaded: return false # Accelerate for 1.5 s, then coast at top speed to 2.5 s. _t += DT _speed = minf(TOP, _speed + ACCEL * DT) if _t < 2.5 else 0.0 _model.update_state("ground", _speed, false) _model.set_locomotion(0.0, 1.0 if _speed > 0.01 else 0.0, 0.0) var lean: float = _model.get_lean_debug() if _last_clip != _model.current_clip_debug(): _last_clip = _model.current_clip_debug() _clip_changes.append("%.2fs %s @ %.1f m/s" % [_t, _last_clip, _speed]) if _t < 2.5: _peak = maxf(_peak, lean) if _t_10 < 0.0 and lean > 0.1: _t_10 = _t if _t_90 < 0.0 and lean > 0.9: _t_90 = _t _worst_step = maxf(_worst_step, absf(lean - _prev_lean)) _prev_lean = lean if _t > 3.5: print("\n=== idle -> run transition ===") print(" clip changes: " + ", ".join(_clip_changes)) print(" lean reached 10%% at %.2fs, 90%% at %.2fs (peak %.2f)" % [_t_10, _t_90, _peak]) print(" worst single-frame lean change: %.4f (%.2f per second at 60fps)" % [_worst_step, _worst_step * 60.0]) print(" a snap looks like ~0.10s to 90%%; a blended move is ~0.6s or more\n") return true return false