- Added KINEMATIC_BLENDING_AND_RECOVERY.md to outline features for smooth transitions between kinematic and ragdoll states, including visual and physical blending, and ragdoll recovery. - Introduced KINEMATIC_TO_RAGDOLL.md detailing the objectives, scope, and core architecture for transitioning the stickman from kinematic to ragdoll mode. - Created KINEMATIC_TO_RAGDOLL_SPEC.md as an implementation specification, verifying codebase facts and correcting the initial plan based on Godot 4.4 source. - Enhanced StickmanRig with state management for animated and ragdoll modes, including momentum preservation and ragdoll construction. - Updated physics_test_harness to support toggling between kinematic and ragdoll states with user input.
206 lines
11 KiB
Markdown
206 lines
11 KiB
Markdown
# Ragdoll ↔ Kinematic Blending & Recovery
|
||
|
||
## 1. Overview
|
||
|
||
Extend the existing kinematic-to-ragdoll system with two major features:
|
||
|
||
- **Blended Transition:** A smooth, visually appealing fade between the kinematic puppet and the ragdoll, eliminating the abrupt "pop" when switching modes.
|
||
- **Ragdoll Recovery:** The ability for the stickman to autonomously stand back up after falling, transitioning from ragdoll back to animated mode with a "get up" animation.
|
||
|
||
These features are essential for a director-driven sandbox where characters can fall, recover, and continue performing actions.
|
||
|
||
---
|
||
|
||
## 2. Feature 1: Ragdoll ↔ Kinematic Blending (Soft Transition)
|
||
|
||
### 2.1. Objective
|
||
|
||
Replace the instant mode switch with a gradual transition that blends the visual appearance and physical behavior over a configurable duration (e.g., 0.5–1.0 seconds). This avoids jarring pops and creates a more polished, film‑like effect.
|
||
|
||
### 2.2. Approach
|
||
|
||
#### 2.2.1. Visual Blending (Opacity Crossfade)
|
||
|
||
- During the transition, both the kinematic `Body/*` nodes and the ragdoll `RigidBody2D` bodies are visible.
|
||
- The kinematic nodes start at full opacity and fade out; the ragdoll bodies start at zero opacity and fade in.
|
||
- Use a `Tween` or `_process` lerp to drive the `modulate.a` of all relevant nodes over the transition duration.
|
||
|
||
#### 2.2.2. Physical Blending (Joint Stiffness Ramp)
|
||
|
||
- When entering ragdoll, start with the `PinJoint2D` stiffness (`softness`/`bias`) at a high value (near‑rigid).
|
||
- Gradually reduce stiffness over the transition period so the limbs become floppy.
|
||
- Conversely, when exiting ragdoll, ramp stiffness from floppy to rigid before freezing the pose.
|
||
|
||
#### 2.2.3. Implementation Outline
|
||
|
||
- `StickmanRig` gains a `transition_duration` property (export, default 0.6s).
|
||
- `_enter_ragdoll()` spawns the ragdoll bodies with `modulate.a = 0.0` and joints at high stiffness.
|
||
- A `_transition_process(delta)` runs during the blend, updating opacities and joint properties.
|
||
- Upon completion, the kinematic nodes are hidden (or vice versa) and the system settles into the target state.
|
||
|
||
### 2.3. Acceptance Criteria
|
||
|
||
- No visible pop when switching modes.
|
||
- The transition duration is configurable (tunable per director preference).
|
||
- Both visual and physical blending are synchronized.
|
||
|
||
---
|
||
|
||
## 3. Feature 2: Ragdoll Recovery (Getting Back Up)
|
||
|
||
### 3.1. Objective
|
||
|
||
Allow the ragdoll to automatically stand up after it has come to rest. This involves detecting rest, capturing the ragdoll’s final pose, applying that pose to the kinematic skeleton, playing a "stand up" animation, and transitioning back to animated mode.
|
||
|
||
### 3.2. Core Components
|
||
|
||
#### 3.2.1. Rest Detection
|
||
|
||
- Monitor the ragdoll Torso body’s linear and angular velocities.
|
||
- When both remain below a small threshold (e.g., `0.1 m/s` and `0.1 rad/s`) for a continuous **timeout** (set by the director), trigger recovery.
|
||
- The timeout must be configurable per character (or globally).
|
||
|
||
#### 3.2.2. Pose Capture
|
||
|
||
- After rest is detected, read the global positions and rotations of all 10 `RigidBody2D` bodies.
|
||
- Convert these into local transforms relative to the `StickmanRig` root (or the `Skeleton2D` root).
|
||
- This captured pose becomes the target for the kinematic bones.
|
||
|
||
#### 3.2.3. Kinematic Snap
|
||
|
||
- Temporarily disable IK (`SkeletonModificationStack2D.enabled = false`).
|
||
- Set each `Bone2D` node’s global position and rotation to match the captured ragdoll pose.
|
||
- This ensures the skeleton matches the ragdoll’s final resting posture.
|
||
|
||
#### 3.2.4. Stand-Up Animation
|
||
|
||
- Play a "stand up" animation (e.g., `stand_up`) that transitions the skeleton from the captured pose to a neutral standing pose.
|
||
- The animation should be authored/generated to work from any reasonable rest pose.
|
||
- Once the animation finishes, re‑enable IK and set the rig back to `ANIMATED` mode.
|
||
|
||
### 3.3. Implementation Outline
|
||
|
||
- Add a new state `RECOVERING` to `RigState`.
|
||
- In `_physics_process`, when in `RAGDOLL` mode, track the Torso’s velocity and a rest timer.
|
||
- When rest timer exceeds `rest_timeout`, call `_start_recovery()`.
|
||
- `_start_recovery()`:
|
||
1. Capture ragdoll pose.
|
||
2. Delete ragdoll bodies (or hide them).
|
||
3. Snap kinematic skeleton to captured pose.
|
||
4. Start the `AnimationPlayer` with the `stand_up` animation.
|
||
5. On animation end, re‑enable IK, show `Body/*`, transition to `ANIMATED`.
|
||
- The recovery process should be interruptible (e.g., if the director toggles back to ragdoll during recovery).
|
||
|
||
### 3.4. Acceptance Criteria
|
||
|
||
- Ragdoll automatically stands up after resting for the configured timeout.
|
||
- The stand‑up motion is smooth and visually convincing.
|
||
- The character resumes animated behavior after recovery.
|
||
|
||
---
|
||
|
||
## 4. Animation Generation for Recovery
|
||
|
||
### 4.1. Current State
|
||
|
||
You have a `create_walk.gd` editor script that generates `walk_left` and `walk_right` animations by keyframing IK target positions.
|
||
|
||
### 4.2. Proposed Enhancement: `create_animations.gd`
|
||
|
||
Refactor the animation generation into a unified script that can generate:
|
||
|
||
- **Walk cycles** (already done)
|
||
- **Stand‑up animation** (from a "down" pose to standing)
|
||
- **Idle / breathing** (optional)
|
||
|
||
#### 4.2.1. Architecture
|
||
|
||
- The script should define a set of **pose templates** (e.g., `POSE_DOWN`, `POSE_STANDING`).
|
||
- Each template maps IK target names to positions (relative to the rig root).
|
||
- The stand‑up animation is a blend between the captured pose (first frame) and the standing pose (last frame), with intermediate frames interpolated using a curve.
|
||
|
||
#### 4.2.2. Integration
|
||
|
||
- The recovery logic will reference a pre‑generated `stand_up` animation stored in the `AnimationPlayer`.
|
||
- The same animation library (`""`) holds all animations.
|
||
- The generator script can be run once at authoring time to create the default animations.
|
||
|
||
#### 4.2.3. Future‑Proofing
|
||
|
||
- The generator could also accept parameters (e.g., `animation_name`, `profile`, `duration`) to make it reusable.
|
||
|
||
### 4.3. Acceptance Criteria
|
||
|
||
- A single script (`create_animations.gd`) generates `walk_left`, `walk_right`, and `stand_up`.
|
||
- The `stand_up` animation works from any reasonable rest pose (i.e., it starts from the current skeleton pose, not a fixed start).
|
||
|
||
---
|
||
|
||
## 5. Director‑Controlled Rest Timeout
|
||
|
||
### 5.1. Requirement
|
||
|
||
The director (user) should be able to adjust how long the ragdoll stays on the ground before attempting recovery. This is crucial for storytelling—some scenes need a quick recovery, others need a long pause.
|
||
|
||
### 5.2. Implementation
|
||
|
||
- `StickmanRig` gains an `@export var rest_timeout: float = 2.0` (seconds).
|
||
- The `PhysicsTestHarness` UI (and ultimately the director UI) will provide a slider or spinbox to modify this value on the selected rig.
|
||
- The value is read during `_physics_process` to determine when to start recovery.
|
||
|
||
### 5.3. Acceptance Criteria
|
||
|
||
- The rest timeout is editable in the inspector (or via a UI control).
|
||
- Changes take effect immediately (no need to reload the rig).
|
||
|
||
---
|
||
|
||
## 6. Integration Timeline (Suggested Order)
|
||
|
||
| Step | Task | Notes |
|
||
| ---- | ---------------------------------------------------------------------- | --------------------------------------------------- |
|
||
| 1 | Add `transition_duration` and `rest_timeout` exports to `StickmanRig`. | Low risk, sets foundation. |
|
||
| 2 | Implement rest detection timer in `_physics_process`. | Test by printing when rest is detected. |
|
||
| 3 | Implement pose capture and kinematic snap. | Manual trigger for testing. |
|
||
| 4 | Create `create_animations.gd` with a `stand_up` placeholder. | Even a simple interpolation is fine for first pass. |
|
||
| 5 | Integrate recovery flow (snap → play animation → re‑enable IK). | End‑to‑end test. |
|
||
| 6 | Implement visual blending (opacity crossfade). | Polish. |
|
||
| 7 | Implement physical blending (joint stiffness ramp). | Advanced polish. |
|
||
| 8 | Add UI control for `rest_timeout` in the harness. | Director‑facing. |
|
||
|
||
---
|
||
|
||
## 7. Risks & Mitigations
|
||
|
||
| Risk | Mitigation |
|
||
| -------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||
| Recovery animation looks unnatural because the starting pose varies. | Use a generic "push‑up" style animation that starts from a prone position; blend the first frame from the captured pose to the animation’s first keyframe. |
|
||
| Kinematic snap may cause jitter if the ragdoll pose is unstable. | Add a small stabilization delay (0.1s) after rest detection before capturing. |
|
||
| Blending physics (joint stiffness) may cause limbs to twitch. | Use a smooth interpolation curve (ease‑in‑out) rather than linear. |
|
||
| Multiple rigs in the scene may compete for recovery timers. | Each `StickmanRig` manages its own state independently. |
|
||
|
||
---
|
||
|
||
## 8. Summary of New/Modified Files
|
||
|
||
| File | Action |
|
||
| ---------------------------------- | --------------------------------------------------------------------------- |
|
||
| `scripts/stickman_rig.gd` | Add transition logic, rest detection, pose capture, recovery state machine. |
|
||
| `scripts/create_animations.gd` | New file: unified animation generator for walk and stand‑up. |
|
||
| `scenes/physics_test_harness.tscn` | Add UI controls (slider/spinbox) for `rest_timeout`. |
|
||
| `scripts/physics_test_harness.gd` | Connect UI to the rig’s `rest_timeout` property. |
|
||
|
||
---
|
||
|
||
## 9. Acceptance Criteria (Full Feature Set)
|
||
|
||
- Switching between animated and ragdoll modes is visually smooth (crossfade).
|
||
- The ragdoll automatically stands up after resting for the director‑defined duration.
|
||
- The stand‑up animation is generated procedurally and plays seamlessly.
|
||
- The director can adjust the rest timeout at runtime.
|
||
- The system is robust and does not produce orphaned nodes or crashes.
|
||
|
||
---
|
||
|
||
_End of Plan_
|