Texto-para-fala é uma forma de tecnologia assistiva que converte strings de texto em sons de fala usando uma voz artificial. Além de melhorar a acessibilidade dos seus jogos para jogadores com deficiências visuais, de mobilidade ou cognitivas, o TTS permite que você gere fala dinamicamente, para que não precise pré-gravar áudio para todos os possíveis cenários narrativos.
Usando o arquivo Gingerbread House - Start .rbxl como ponto de partida e Gingerbread House - Texto-para-Fala como referência, este tutorial mostra como adicionar áudio TTS básico e contextual aos seus jogos, incluindo orientações sobre:
- Acionar TTS para cenários comuns de jogabilidade que nunca mudarão, como interações de UI e tutoriais.
- Configurar TTS para que se adapte às ações do jogador, ao status ambiental ou a objetivos flexíveis.
Se em algum momento você ficar preso no processo, pode usar Gingerbread House - Texto-para-Fala como referência para comparar seu progresso.
Objetos de Áudio
Para criar áudio TTS, é importante entender os objetos de áudio com os quais você trabalhará ao longo deste tutorial. Existem cinco tipos principais de objetos de áudio para TTS:
- O objeto AudioTextToSpeech converte strings de texto em sons de fala.
- O objeto AudioEmitter é um alto-falante virtual que emite áudio no ambiente 3D.
- O objeto AudioListener é um microfone virtual que capta áudio do ambiente 3D.
- O objeto AudioDeviceOutput é um dispositivo de hardware físico no mundo real, como um alto-falante ou fones de ouvido.
- Wires transportam streams de áudio de um objeto para outro.
Todos esses objetos de áudio trabalham juntos para emitir som TTS em resposta às ações do jogador. Vamos dar uma olhada em como isso funciona na prática para áudio 3D usando um exemplo de um jogador usando um fone de ouvido enquanto joga em seu laptop:
- O AudioTextToSpeech carrega e converte texto em áudio sempre que um jogador toca em uma parte próxima a um personagem não jogável (NPC).
- O AudioEmitter emite um stream do áudio TTS do NPC para o ambiente 3D.
- Um objeto Wire transporta o stream do AudioTextToSpeech para o AudioEmitter, de modo que o stream saia do NPC.
- O objeto filho AudioListener do personagem ouve esse som dentro do ambiente 3D e o retransmite para seu fone de ouvido.
- O objeto AudioDeviceOutput transporta o som do AudioListener para o alto-falante físico do jogador, ou neste caso, seus fones de ouvido.
As seções a seguir se aprofundam e fazem referência a esses objetos enquanto você aprende a reproduzir áudio básico e contextual. Ao revisar esses objetos com as técnicas que virão, você poderá prever com mais precisão como capturar e transmitir som do jogo para o jogador.
TTS Básico
O TTS básico é a forma mais comum de texto-para-fala em que a voz artificial lê uma string de texto independentemente do contexto do jogador ou do ambiente. Isso significa que sempre que o jogador aciona o áudio TTS, as palavras e a forma como a voz artificial lê as palavras permanecem consistentes, não importando o estado do jogador, suas ações ou o status ambiental.
Essa forma de TTS é útil na maioria dos cenários de jogabilidade, como jogadores interagindo com menus de UI, tutoriais ou interações rotineiras com NPCs, como ofertas de vendedores ou gritos de inimigos. O Roblox fornece os seguintes tipos de vozes que você pode experimentar para qualquer uma dessas interações:
| VoiceID | Descrição da Voz | Exemplo de Áudio |
|---|---|---|
| 1 | Masculino britânico | |
| 2 | Feminino britânico | |
| 3 | Masculino dos Estados Unidos #1 | |
| 4 | Feminino dos Estados Unidos #1 | |
| 5 | Masculino dos Estados Unidos #2 | |
| 6 | Feminino dos Estados Unidos #2 | |
| 7 | Masculino australiano | |
| 8 | Feminino australiano | |
| 9 | Voz retro #1 | |
| 10 | Voz retro #2 | |
| 11 | Voz de apresentador | |
| 101 | Masculino espanhol | |
| 102 | Feminino espanhol | |
| 201 | Masculino alemão | |
| 202 | Feminino alemão | |
| 301 | Masculino italiano | |
| 302 | Feminino italiano | |
| 401 | Masculino francês | |
| 402 | Feminino francês |
Para recriar o áudio TTS 3D básico no arquivo de amostra Gingerbread House - Texto-para-Fala:
- Ative um ouvinte padrão que esteja anexado ao seu personagem jogador.
- Na janela Explorer, selecione o SoundService.
- Na janela Properties, defina DefaultListenerLocation como Character. Quando você executar o jogo, o mecanismo automaticamente:
- Cria um AudioListener sob o Humanoid.RootPart de cada personagem jogador, para que você possa ouvir os sons mudarem em seus alto-falantes do mundo real de acordo com a posição e escala das fontes de som dentro do jogo.
- Cria um AudioDeviceOutput sob o SoundService.
- Na janela Explorer, navegue até Workspace ⟩ DialogueVolume, então:
- Insira um objeto AudioTextToSpeech para criar um gerador de fala de áudio para o volume ao redor do boneco de neve.
- Insira um objeto AudioEmitter para emitir um stream posicional do DialogueVolume.
- Insira um objeto Wire para transportar o stream do gerador de fala de áudio para o emissor de áudio.
- Selecione o objeto AudioTextToSpeech, então na janela Properties:
- Defina Text como "Cole cada último gumpdrop para abrir minha casa!"
- Defina VoiceId como 2 para definir a voz artificial para emular uma feminina britânica.
- Defina o Volume como 3 para tocar o áudio em um volume alto, para que você ouça o som TTS sobre outras fontes de áudio dentro do jogo.
- Selecione o Wire, então na janela Properties:
- Defina SourceInstance para seu novo AudioTextToSpeech para especificar que você deseja que o fio transporte áudio deste gerador de fala de áudio específico.
- Defina TargetInstance para seu novo AudioEmitter para especificar que você deseja que o fio transporte áudio para este emissor de áudio específico dentro do volume.
- De volta à janela Explorer, navegue até StarterPlayer ⟩ StarterCharacterScripts, então insira um LocalScript, renomeie-o para PlayBasicTTSAudioWhenInVolume, e cole o seguinte código no script local:
local Workspace = game:GetService("Workspace")
local Players = game:GetService("Players")
local humanoid = script.Parent:WaitForChild("Humanoid")
local volumeDetector = Workspace.DialogueVolume
local trigger = humanoid:WaitForChild("Animator")
local debounce = false
local localPlayer = Players.LocalPlayer
volumeDetector.Touched:Connect(function(hit)
if debounce then
return
end
local hitCharacter = hit:FindFirstAncestorWhichIsA("Model")
local hitPlayer = Players:GetPlayerFromCharacter(hitCharacter)
if hitPlayer ~= localPlayer then
return
end
debounce = true
local audioTextToSpeech = Workspace.DialogueVolume.AudioTextToSpeech
audioTextToSpeech:Play()
audioTextToSpeech.Ended:Wait()
debounce = false
end)Este script começa obtendo os serviços Workspace e Players para que possa referenciar seus filhos e funcionalidades. Para cada personagem jogador que carrega ou renasce no jogo, o script espera por:
- O objeto de volume no espaço de trabalho chamado DialogueVolume.
Quando qualquer coisa colide com o volume, a função manipuladora de eventos Touched obtém o primeiro ancestral que é um Model, que deve ser o personagem se a BasePart que colidiu com o volume for um descendente de um modelo de personagem. Se for, a função então:
- Define debounce como true.
- Toca e espera o áudio TTS terminar.
- Define debounce de volta para false.
Definir debounce de false para true e de volta para false novamente após o áudio TTS básico terminar de tocar é um padrão de debounce que impede que o áudio seja acionado repetidamente à medida que os jogadores colidem continuamente com o volume. Para mais informações sobre esse padrão de debounce, veja Debounce - Detectar colisões.
Teste o jogo para ouvir o diálogo instrucional do personagem quando seu personagem jogador tocar o volume ao redor do boneco de neve.
Você pode experimentar ainda mais com este áudio modificando as propriedades Text, VoiceID, Pitch e Speed para novos valores. A fala gerada se torna completamente diferente sem a necessidade de gravar e enviar um novo arquivo de áudio para cada cenário.
TTS Contextual
O TTS contextual é uma forma mais avançada de texto-para-fala em que a voz artificial lê uma string de texto em relação ao jogador, ao estado de seu ambiente ou ao status da jogabilidade. Isso significa que sempre que o jogador aciona o áudio TTS, as palavras e a forma como a voz artificial lê as palavras se adaptam de acordo.
Essa forma de TTS é útil para cenários de jogabilidade que estão em constante mudança, como dicas de áudio direcionais, status de objetivos ou interações únicas com NPCs. Consequentemente, como o TTS contextual precisa se transformar para ser preciso, você deve configurar elementos de jogabilidade para que possa rastrear seu status à medida que os jogadores navegam pelo ambiente e completam objetivos de jogabilidade.
Embora existam muitas maneiras de realizar essa tarefa, o exemplo usa atributos personalizados para rastrear a cor e a localização de cada gumpdrop que o jogador deve coletar para entrar na casa de gengibre. Para mais informações sobre atributos, veja Propriedades e atributos.



Para recriar o áudio TTS 3D contextual no arquivo de amostra Gingerbread House - Texto-para-Fala:
Na janela Explorer, navegue até Workspace ⟩ GumDrops.
Configure três atributos personalizados para rastrear o gumpdrop amarelo.
- Selecione o gumpdrop amarelo, então na janela Properties, navegue até a seção Attributes, e clique no ícone de mais. Um diálogo pop-up será exibido.
- No campo Name, insira ColorDescription.
- No menu suspenso Type, selecione string.
- Clique no botão Save.
- Defina o novo atributo ColorDescription como amarelo.
- Usando esse processo, crie mais dois atributos com os seguintes valores.
Nome Tipo Valor HintOrder number 0 LocationDescription string perto da cachoeira Configure três atributos personalizados para rastrear o gumpdrop verde.
- Na janela Explorer, selecione o gumpdrop verde.
- Na janela Properties, crie três atributos usando os seguintes valores.
Nome Tipo Valor ColorDescription string verde HintOrder number 1 LocationDescription string na beirada Configure três atributos personalizados para rastrear o gumpdrop vermelho.
- Na janela Explorer, selecione o gumpdrop vermelho.
- Na janela Properties, crie três atributos usando os seguintes valores.
Nome Tipo Valor ColorDescription string vermelho HintOrder number 2 LocationDescription string atrás da cerca Na janela Explorer, navegue até Workspace ⟩ HintVolume, então:
- Insira um objeto AudioTextToSpeech para criar um gerador de fala de áudio para o volume ao redor da rena.
- Insira um objeto AudioEmitter para emitir um stream posicional do HintVolume.
- Insira um objeto Wire para transportar o stream do gerador de fala de áudio para o emissor de áudio.
Selecione o Wire, então na janela Properties:
- Defina SourceInstance para seu novo AudioTextToSpeech para especificar que você deseja que o fio transporte áudio deste gerador de fala de áudio específico.
- Defina TargetInstance para seu novo AudioEmitter para especificar que você deseja que o fio transporte áudio para este emissor de áudio específico dentro do volume.
De volta à janela Explorer, navegue até StarterPlayer ⟩ StarterCharacterScripts, então insira um LocalScript, renomeie-o para PlayContextTTSAudioWhenInVolume, e cole o seguinte código no script local:
local Workspace = game:GetService("Workspace")
local Players = game:GetService("Players")
local humanoid = script.Parent:WaitForChild("Humanoid")
local volumeDetector = Workspace.HintVolume
local trigger = humanoid:WaitForChild("Animator")
local debounce = false
local localPlayer = Players.LocalPlayer
function getRemainingGumdrops(): {Part}
local gumdropsFolder = Workspace.Gumdrops
local gumdrops = gumdropsFolder:GetChildren()
local remainingGumdrops = {};
for _, gumdrop in gumdrops do
if gumdrop:GetAttribute("Active") then
remainingGumdrops[#remainingGumdrops + 1] = gumdrop
end
end
table.sort(remainingGumdrops, function(a, b)
return a:GetAttribute("HintOrder") < b:GetAttribute("HintOrder")
end)
return remainingGumdrops
end
function getReindeerHint(remainingGumdrops: {Part}): string
local remainingGumdrops = getRemainingGumdrops()
if (#remainingGumdrops == 0) then
return "Não há gumpdrops restantes. Verifique dentro da casa."
end
local nextGumdrop = remainingGumdrops[1]
local colorDescription = nextGumdrop:GetAttribute("ColorDescription")
local locationDescription = nextGumdrop:GetAttribute("LocationDescription")
local message = #remainingGumdrops > 1
and "Ainda há " .. #remainingGumdrops .. " gumpdrops restantes. Procure o " .. colorDescription .. " " .. locationDescription .. "."
or "Há um gumpdrop restante. É " .. colorDescription .. " e está " .. locationDescription .. "."
return message
end
volumeDetector.Touched:Connect(function(hit)
if debounce then
return
end
local hitCharacter = hit:FindFirstAncestorWhichIsA("Model")
local hitPlayer = Players:GetPlayerFromCharacter(hitCharacter)
if hitPlayer ~= localPlayer then
return
end
print("Jogador tocou o volume.")
debounce = true
local remainingGumdrops = getRemainingGumdrops()
local message = getReindeerHint(remainingGumdrops)
local audioTextToSpeech = Workspace.HintVolume.AudioTextToSpeech
audioTextToSpeech.Text = message
audioTextToSpeech:Play()
audioTextToSpeech.Ended:Wait()
debounce = false
end)Este script começa obtendo os serviços Workspace e Players para que possa referenciar seus filhos e funcionalidades. Para cada personagem jogador que carrega ou renasce no jogo, o script espera por:
- O objeto de volume no espaço de trabalho chamado HintVolume.
A função getRemainingGumdrops() do script retorna uma lista de objetos gumpdrop Part dentro da pasta Gumdrops e filtra qualquer parte que o jogador tenha coletado. Os gumpdrops restantes são ordenados em uma ordem específica de acordo com o atributo HintOrder de cada gumpdrop.
A função getReindeerHint(remainingGumdrops) do script pega essa lista da getRemainingGumdrops() e retorna uma mensagem de string que descreve onde o jogador pode encontrar os gumpdrops restantes, incluindo tanto a descrição da cor quanto a descrição da localização do próximo gumpdrop que o jogador precisa coletar. No entanto, se o jogador coletou todos os gumpdrops no ambiente, a mensagem de string descreve para onde ir a seguir após coletar todos os gumpdrops no ambiente.
Quando qualquer coisa colide com o volume, a função manipuladora de eventos Touched obtém o primeiro ancestral que é um Model, que deve ser o personagem se a BasePart que colidiu com o volume for um descendente de um modelo de personagem. Se for, a função então:
- Define debounce como true.
- Obtém a lista de gumpdrops restantes e a mensagem de string descrevendo o próximo gumpdrop que o jogador precisa encontrar.
- Converte a string em áudio usando o objeto AudioTextToSpeech, toca o áudio e espera o áudio terminar.
- Define debounce de volta para false.
Definir debounce de false para true e de volta para false novamente após o áudio TTS contextual terminar de tocar é um padrão de debounce que impede que o áudio seja acionado repetidamente à medida que os jogadores colidem continuamente com o volume. Para mais informações sobre esse padrão de debounce, veja Debounce - Detectar colisões.
Teste o jogo para ouvir dicas contextuais quando seu personagem jogador tocar o volume ao redor da rena. O áudio TTS muda de acordo com o número e a cor dos gumpdrops que o personagem jogador já encontrou no ambiente.