Dalle voz propia e dinámica aos teus personaxes en Godot

Imaxe do Metarcade mostrando dous personaxes

O son nos videoxogos é unha parte que a miúdo pasamos por alto cando desenvolvemos os nosos proxectos de afeccionados. Como se pode ver en calquera artigo sobre “espremer o zume” na creación de videoxogos a presencia do audio e música xoga unha parte fundamental no xeito que os xogadores perciben os nosos produtos.

O xogo que estamos a desenvolver, Metarcade, contén pequenas partes de xestión do personaxe e subida de niveis pero consiste principalmente en interactuar con diferentes personaxes para avanzar a historia. Para que os usuarios non se cansen de ler tanto texto, pareceunos fundamental facer a súa lectura máis apetecible.

Seguindo un artigo en gamedeveloper, comezamos por animar a aparición de texto palabra a palabra no canto de letra a letra. Axuda sobre todo en casos como o noso que queremos potenciar a parte cómica do texto. Pero, como poderías asumir polo título do post, a parte que fixo maior cambio foi engadir un pequeno son con cada nova palabra.

Sintetizador

Dadas as pretensións do noso xogo, engadir actuacións para cada liña de texto non é viable, como sería de esperar. Ademais que isto sería contraproducente á hora de traducir o xogo a outros idiomas. Queremos facelo principalmente en galego, pero é certo que chegará o momento que para aumentar a base de usuarios o teñamos que traducir e, con voces reais isto sería o triple de traballo.

Por outra banda, tampouco queriamos engadir o mesmo son unha e outra vez e por riba para todos os personaxes, xa que un bip continuado pode acabar taladrando os tímpanos do xogador e facendo que baixe o volume por completo.

A solución foi usar o plugin GDFXR, baseado no popular sintetizador SFXR. SFXR é unha pequena ferramenta desenvolta de xeito altruista para xerar sons de videoxogos. Hai unha versión en liña, JSFXR que te convido a probar se nunca o fixeches.

A idea deste tipo de sintetizadores é que a partir de só uns poucos parámetros se poden conseguir sons moi distintos e, como se pode experimentar nos seus axustes predefinidos, se poden axeitar a explosións, saltos, recollida de obxectos ou moitas outras accións comúns.

A maneira habitual de utilizar este sintetizador é creando os sons en formato WAV para logo engadilos ao xogo. Este sería o modo habitual de usar tamén o plugin GDFXR, pero no noso caso queríamos dar máis expresividade a cada interacción.

Sons algorítmicos

Xa que o sintetizador se pode executar dentro do propio Godot e dende o código podemos modificar os parámetros para a xeración, é posible reproducir sons únicos para cada nova palabra sen aumentar o tamaño do xogo.

Para isto comezamos definindo un son “base” para cada personaxe. A maneira foi experimentando na web JSFXR ata dar con algo que máis ou menos se axeitase ao carácter que queríamos dar a ese NPC. Unha vez demos con algo axeitado, usamos a opción de GDFXR de importar a configuración directamente dende a web.

Hai moitos parámetros que se poden modificar, e probablemente no futuro engadamos algún máis dinámico, pero é suficiente con modificar lixeiramente a frecuencia para que os sons sexan o suficientemente distintos.

Como queremos que cada novo son sexa parecida á “base”, utilizamos unha función aleatoria con distribución normal, randfn, deste xeito serán máis habituais os sons achegados ao inicial con algún que outro mais diferente.

O código quedou así:

# Usamos AudioStreamPlayer como base
extends AudioStreamPlayer

# Necesitamos incluír os scripts do addon
const SFXRConfig = preload("res://addons/gdfxr/SFXRConfig.gd")
const SFXRGenerator = preload("res://addons/gdfxr/SFXRGenerator.gd")

var sfxr_config = SFXRConfig.new()
var sfxr_gen = SFXRGenerator.new()
var orig_base_freq = sfxr_config.p_base_freq

# Cada vez que se cambia de NPC actualizamos o son base
func update_sound_base(path: String):
  sfxr_config.load(path)
  orig_base_freq = sfxr_config.p_base_freq

func play_new_sound():
  sfxr_config.p_base_freq = randfn(orig_base_freq, 0.1)
  # os parámetros son para 8 bit, 22050Hz
  stream = sfxr_gen.generate_audio_stream(sfxr_config, 0, 1)
  play()

A chamada a generate_audio_stream queda un pouco críptica, xa que os enum están definidos no script SFXGenerator e non se exportan. A razón de usar estes é porque é un pouco máis rápido.

Exportar a Android

Con isto xa sería suficiente para reproducir os sons no PC, pero por desgraza hai unha serie de problemas ao intentar usar este código en dispositivos móbiles, sendo o problema máis grande a diferenza de velocidade, pero non o único.

O arquivo usado para gardar os datos é un “.sfxr”. Contén por unha parte os parámetros para xerar o son e por outra o arquivo xa xerado en WAV. Á hora de exportar o proxecto a Android, Godot fai unha conversión do arquivo WAV, seguramente para comprimilo, pero decide prescindir dos parámetros por completo. Por isto é necesario modificar os parámetros de improtación para “preservar o arquivo como é”.

Na imaxe superior vemos que hai tres arquivos sfxr marcados cunha “x”, que significa que non se modificarán ao exportalos. O outro, que si ten unha icona de audio decidín mantelo coa importación por defecto, xa que ese é o que se utiliza cando se preme unha opción de diálogo e ao escoitarse menos a miúdo se pode manter estática.

Seguintes pasos

GDFRX suxire non crear os arquivos no momento, senón gardalos previamente. Isto é porque leva moito tempo, varias veces o que debera durar un frame. A pesar diso, polo menos polo momento nos decidimos mantelo como se explicou neste artigo.

No seguinte artigo explicarei como puidemos xerar o audio no momento sen afectar ao rendemento incluso en dispositivos limitados co uso de varios fíos de procesamento.

Reaccións do Fediverso

Comentarios

3 respostas a “Dalle voz propia e dinámica aos teus personaxes en Godot”

  1. Avatar de jsmtux

    @metarcade_bitacora Novo artigo sobre desenvolvemento en #godot !
    Pode ser de axuda a que estea a facer un xogo con moito texo e queira darlle un pouco de vida con uns efectos de audio divertidos.

  2. Avatar de Ribadeando

    @metarcade_bitacora Faiseme difícil, pero o fondo é clariño…

  3. […] post anterior, sobre engadir voces aos personaxes en Godot quedou inconcluso, ao deixar para máis adiante as optimizacións necesarias para executalo nun […]

Deixa una resposta a Aproveita os núcleos do teu procesador en Godot – Metarcade Bitácora Cancelar a resposta

O teu enderezo electrónico non se publicará Os campos obrigatorios están marcados con *