Parte: 6 — Audio y música interactiva · Fuente: Documentación de audio de Godot 4 (AudioStreamInteractive, 4.3+) + GDC talks sobre horizontal re-sequencing ⏱️ Duración estimada: 55 min · Nivel: Intermedio
Pasar de un tema a otro —de exploración a combate, de calma a jefe— sin cortes bruscos. Es el horizontal re-sequencing: en lugar de sumar capas (vertical), cambiamos el segmento que suena. Verás dos enfoques: el crossfade (fundir un tema con otro solapándolos) y la transición en beat/compás (esperar al siguiente punto musical para saltar, que suena mucho más natural). En Godot 4.3+ el recurso AudioStreamInteractive formaliza clips y transiciones con reglas de sincronización.
Al finalizar, el alumno podrá:
volume_db.AudioStreamInteractive con clips y transiciones sincronizadas.| # | Tema | Por qué importa |
|---|---|---|
| 1 | Re-sequencing horizontal | Cambiar de segmento en vez de sumar capas |
| 2 | Crossfade | Solución simple: solapar y fundir dos temas |
| 3 | Transición en beat/compás | Saltar en un punto musical evita el corte feo |
| 4 | AudioStreamInteractive |
Recurso que gestiona clips y transiciones (4.3+) |
| 5 | Modos de transición | Inmediata, en compás, al final del clip |
| 6 | Fill/puente | Un pequeño clip de enlace suaviza el salto |
| 7 | Disparo desde gameplay | El estado del juego pide el cambio de música |
Consigue dos temas del mismo proyecto musical, idealmente al mismo tempo y en tonalidades compatibles: exploracion.ogg y combate.ogg, ambos en bucle. Para el enfoque manual con crossfade bastan dos AudioStreamPlayer. Para el enfoque con AudioStreamInteractive necesitas Godot 4.3 o superior; comprueba tu versión en Help → About. Revisa la referencia de AudioStreamInteractive y la guía de música interactiva. Coloca los OGG en audio/musica/.
Haremos primero un crossfade manual y luego una transición sincronizada con AudioStreamInteractive. Resultado audible: la música pasa de exploración a combate al "entrar en pelea" sin un corte abrupto.
Paso 1 — Crossfade manual: escena. Crea un nodo MusicaHorizontal con dos hijos AudioStreamPlayer: Exploracion y Combate, cada uno con su OGG en loop y bus Music. Ambos arrancarán a la vez, pero uno silenciado.
Paso 2 — Script del crossfade. El truco: reproducir ambos temas sincronizados desde el inicio y solo cruzar sus volúmenes. Así el combate ya está "en su sitio" temporal cuando entra:
extends Node
@onready var exploracion: AudioStreamPlayer = $Exploracion
@onready var combate: AudioStreamPlayer = $Combate
const SILENCIO := -60.0
var _en_combate := false
func _ready() -> void:
exploracion.volume_db = 0.0
combate.volume_db = SILENCIO
# Ambos suenan desde el mismo instante para que el salto sea coherente.
exploracion.play()
combate.play()
func cambiar_a_combate(activo: bool) -> void:
if activo == _en_combate:
return
_en_combate = activo
var tween := create_tween().set_parallel(true) # fundimos las dos a la vez
tween.tween_property(exploracion, "volume_db", SILENCIO if activo else 0.0, 1.0)
tween.tween_property(combate, "volume_db", 0.0 if activo else SILENCIO, 1.0)
func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed("ui_accept"):
cambiar_a_combate(not _en_combate) # alterna con Espacio
Paso 3 — Pruébalo. Corre la escena y pulsa Espacio. La música de exploración se funde con la de combate en un segundo, y al volver a pulsar regresa. Como ambos temas comparten reloj, el cambio respeta el compás automáticamente.
Paso 4 — Enfoque profesional: AudioStreamInteractive. Crea un AudioStreamPlayer llamado MusicaInteractiva. En su Stream, elige New AudioStreamInteractive. Ábrelo: en Clips, añade dos y asigna exploracion.ogg y combate.ogg. Ponles nombre explorar y pelear.
Paso 5 — Define las transiciones. En el editor del AudioStreamInteractive, abre la matriz de transiciones. Configura de explorar a pelear con From Time = Next Beat (o Next Bar para el compás) y Fade Mode = Crossfade. Haz lo mismo de pelear a explorar. Esto obliga a que el salto ocurra en un punto musical, no a mitad de nota.
Paso 6 — Dispara la transición por código. Controla el clip activo con la API del reproductor interactivo:
extends Node
@onready var musica: AudioStreamPlayer = $MusicaInteractiva
func _ready() -> void:
musica.play()
# Arrancamos en el clip de exploración por su nombre.
musica.get_stream_playback().switch_to_clip_by_name("explorar")
func entrar_en_combate() -> void:
# La transición respeta el "Next Beat/Bar" definido en el recurso.
musica.get_stream_playback().switch_to_clip_by_name("pelear")
func salir_de_combate() -> void:
musica.get_stream_playback().switch_to_clip_by_name("explorar")
Paso 7 — Compara los dos enfoques. Con el crossfade manual controlas todo pero la sincronía al compás depende de arrancar juntos. Con AudioStreamInteractive, Godot espera al siguiente beat/compás y aplica el crossfade por ti: el salto suena claramente más musical.
Resultado visible: la música cambia de exploración a combate al dispararse un evento, primero por crossfade y luego con una transición cuantizada al compás que se percibe intencional y limpia.
0.2 y a 3.0 s y describe el efecto en la sensación de urgencia.AudioStreamInteractive, prueba From Time Immediate vs Next Bar y compara la naturalidad.jefe) y define transiciones desde combate y exploración hacia él.entrar_en_combate() a la detección de un enemigo cercano en vez de a una tecla.Implementa un cambio de música entre dos estados de juego (exploración y combate) usando transición en el siguiente compás, ya sea con AudioStreamInteractive (clips + transiciones cuantizadas) o con un crossfade manual sobre temas sincronizados. El cambio debe dispararse desde un evento del juego y poder ir y volver.
Criterio de aceptación: al activar el combate la música cambia de tema sin un corte abrupto y respetando el pulso (la transición cae en un beat/compás, no a mitad de frase); al salir del combate vuelve al tema de exploración de forma igualmente limpia; y el disparo del cambio proviene de un evento de gameplay, no de reiniciar la música.
| Síntoma | Causa y arreglo |
|---|---|
| El cambio de tema suena a "corte" seco | Transicionas de forma inmediata; usa Next Beat/Next Bar o un crossfade |
| El crossfade suena aguado o desafinado | Los temas tienen distinto tempo o tonalidad; usa piezas compatibles |
AudioStreamInteractive no aparece |
Tu versión es anterior a 4.3; actualiza Godot o usa el crossfade manual |
| El combate empieza desde el principio del tema y desincroniza | Reinicias el player; mantén ambos sonando o deja que el recurso gestione la sincronía |
switch_to_clip_by_name da error |
El nombre no coincide con el del clip; revisa mayúsculas y espacios |
| La transición no espera al compás | From Time está en Immediate; cámbialo a Next Bar en la matriz |
¿Horizontal o vertical: cuál uso? Vertical (capas) para intensidad continua sobre una misma pieza; horizontal (segmentos) para cambios de sección claros como exploración→combate. Muchos juegos combinan ambos.
¿El crossfade manual es "peor" que AudioStreamInteractive?
No necesariamente; es más laborioso y menos preciso al compás, pero funciona en cualquier versión de Godot y ofrece control total. AudioStreamInteractive te ahorra la lógica de sincronización.
¿Qué es un clip de "fill"? Un fragmento musical corto (un redoble, un acorde de enlace) que se intercala durante la transición para tapar la costura entre secciones y darle continuidad.
¿Puedo transicionar al final del clip en lugar de al siguiente compás?
Sí: AudioStreamInteractive permite From Time = End of Clip, útil cuando cada segmento es una frase completa que quieres dejar terminar.
Clase 130 - Música adaptativa: capas verticales