Parte: 3 — Física y matemáticas de juegos aplicadas · Fuente: Documentación oficial de Godot 4 (Physical bones / Ragdolls) · Ian Millington, Game Physics Engine Development ⏱️ Duración estimada: 60 min · Nivel: Intermedio
Convertir un personaje animado en un ragdoll físico usando PhysicalBone3D sobre un Skeleton3D. Aprenderás a activar y desactivar la simulación con physical_bones_start_simulation(), a mezclar animación esquelética con física y a hacer un blend creíble hacia la muerte cuando el personaje recibe el golpe final.
Al finalizar, el alumno podrá:
Skeleton3D con PhysicalBone3D sustituye la pose animada por simulación física.physical_bones_start_simulation() / physical_bones_stop_simulation().| # | Tema | Por qué importa |
|---|---|---|
| 1 | Skeleton3D y huesos | El esqueleto es la base sobre la que se monta la física |
| 2 | PhysicalBone3D | Cada hueso físico es un cuerpo rígido con junta |
| 3 | Formas de colisión por hueso | Definen el volumen del brazo, pierna, torso |
| 4 | Iniciar/detener simulación | Alternar entre pose animada y ragdoll |
| 5 | Simular solo algunos huesos | Golpe localizado sin soltar todo el cuerpo |
| 6 | Blend animación→física | Evita el "salto" brusco al morir |
| 7 | Capas de colisión del ragdoll | Que los huesos no choquen entre sí de forma absurda |
| 8 | Rendimiento | Muchos ragdolls simultáneos cuestan CPU |
PhysicalBone3D tiene una junta (pin, cono, bisagra) que limita su rango respecto al padre.start_simulation deja el resto animado.Necesitas Godot 4.2+ y un personaje con Skeleton3D (los modelos de Mixamo importados en formato glTF funcionan bien). En el inspector del Skeleton3D, el menú "Create physical skeleton" genera automáticamente un PhysicalBone3D por hueso con formas de cápsula y juntas; luego ajustas tamaños y límites. Activa Debug → Visible Collision Shapes para ver las cápsulas. Asegúrate de tener un suelo con colisión. Consulta la guía oficial: https://docs.godotengine.org/en/stable/tutorials/physics/ragdoll_system.html.
Tras usar "Create physical skeleton", tu escena tiene PhysicalBone3D colgando de cada hueso. Revisa que las cápsulas cubran bien brazos, piernas y torso, y asigna capas de colisión al conjunto para que golpeen el suelo pero no se atasquen entre sí.
extends CharacterBody3D
@onready var esqueleto: Skeleton3D = $Modelo/Skeleton3D
@onready var animador: AnimationPlayer = $AnimationPlayer
var vivo := true
func recibir_golpe(danio: int) -> void:
if not vivo:
return
if danio >= 100:
morir()
func morir() -> void:
vivo = false
animador.stop() # dejo de imponer la pose animada
esqueleto.physical_bones_start_simulation() # la física toma el control
# Los huesos caen desde la pose actual: el arranque parece natural.
Observable: mientras el personaje está vivo se anima normalmente; al recibir 100 de daño, el cuerpo se desploma de forma física desde la última pose.
Un ragdoll que solo cae por gravedad es soso. Aplica un impulso al hueso del torso en la dirección del disparo para que el cuerpo salga despedido.
func morir_con_impulso(direccion: Vector3, fuerza: float) -> void:
vivo = false
animador.stop()
esqueleto.physical_bones_start_simulation()
# Busco el hueso físico del torso y le aplico el impulso del golpe.
var torso := esqueleto.get_node("Physical Bone Spine") as PhysicalBone3D
if torso:
torso.apply_central_impulse(direccion.normalized() * fuerza)
Observable: al morir, el cuerpo sale despedido en la dirección del golpe con la intensidad de fuerza, en vez de derrumbarse en el sitio.
func revivir() -> void:
esqueleto.physical_bones_stop_simulation() # la animación recupera el mando
animador.play("idle")
vivo = true
Observable: al llamar revivir(), el personaje deja de ser ragdoll y vuelve a la animación de reposo.
start_simulation) para un golpe que sacude una extremidad sin soltar todo el cuerpo.Timer antes de desaparecer el cadáver tras el ragdoll.BoneAttachment3D y comprueba que cae con el ragdoll.Implementa un enemigo que camina con animación y, al llegar su vida a cero por un disparo, transiciona a ragdoll con un impulso proporcional al arma usada y en la dirección del proyectil. Tras 4 segundos, el cadáver se desvanece.
Criterio de aceptación: la transición de animación a ragdoll no muestra un salto brusco de pose, el cuerpo reacciona con impulso en la dirección correcta del disparo, no atraviesa el suelo y desaparece a los 4 segundos.
| Síntoma | Causa y arreglo |
|---|---|
| El ragdoll tiembla o vibra | Cápsulas de huesos que se solapan y colisionan entre sí. Ajusta capas/máscaras o tamaños. |
| El cuerpo se estira o "explota" | Juntas con límites incoherentes o masas muy dispares. Revisa límites y equilibra masas. |
| Salto brusco al morir | Se inicia el ragdoll desde una pose distinta a la animada. Detén la animación en el mismo frame. |
| Los huesos atraviesan el suelo | Máscara de colisión del ragdoll no incluye el suelo. Corrige capas del PhysicalBone3D. |
| Vuelve a la pose "T" al morir | La animación sigue imponiendo la pose. Llama animador.stop() antes de simular. |
¿Necesito crear cada PhysicalBone3D a mano? No: el botón "Create physical skeleton" del inspector genera todos; solo ajustas formas y límites.
¿Puedo mezclar animación y física a la vez? Sí, simulando solo algunos huesos (impacto localizado) mientras el resto sigue la animación.
¿Por qué mi personaje no cae aunque llamo start_simulation? Probablemente la animación sigue reproduciéndose y sobrescribe la pose; deténla primero.
¿Cuántos ragdolls puedo tener? Depende del hardware; cada uno son ~15 cuerpos con juntas. Limita los activos y "congela" los cadáveres quietos.
Clase 076 - Juntas y restricciones (joints): bisagras y resortes