Roblox released their new Text-to-Speech API.
I thought it would be helpful for the community to be able to experience the API in-game.
When you type in chat, the Text-to-Speech API converts what you said into an audio you can hear back.
Roblox released their new Text-to-Speech API.
I thought it would be helpful for the community to be able to experience the API in-game.
When you type in chat, the Text-to-Speech API converts what you said into an audio you can hear back.
Could this be used to make NPC have text that is then audio ?
Also in the test place, why do only some words work and also those that do work, do not have audio all the time?
Like I did these words, and sometime Hi would work, and other times it would not.
Also when I play it in studio I get the error on every time I type.
The new Roblox’s TextToSpeech API looks perfect for me!
I just implemented into chat using TextChatService from scratch, but this one might be easier than method i use! don’t insult me for using the module or AudioTextToSpeech
Hey there!
I just heard about this feature and decided to dive in. While exploring I came across your code and it really helped me out… thank you!
local TextService = game:GetService("TextService")
local Players = game:GetService("Players")
local DEFAULT_VOICE = "British male"
local VOICES = {
["British male"] = "1",
["British female"] = "2",
["US male #1"] = "3",
["US female #1"] = "4",
["US male #2"] = "5",
["US female #2"] = "6",
["Australian male"] = "7",
["Australian female"] = "8",
["Retro voice #1"] = "9",
["Retro voice #2"] = "10",
}
local CHAT_RANGE = 74
local playerVoice = {}
local function stopExisting(head: Instance)
for _, obj in ipairs(head:GetChildren()) do
if obj:IsA("AudioTextToSpeech") and obj.Name == "ChatTTS" then
obj:Destroy()
end
if obj:IsA("AudioEmitter") and obj.Name == "ChatTTSEmitter" then
obj:Destroy()
end
if obj:IsA("Wire") and obj.Name == "ChatTTSWire" then
obj:Destroy()
end
end
end
local function playChatTTS(player: Player, message: string)
local character = player.Character
if not character then return end
local head = character:FindFirstChild("Head")
if not head then return end
stopExisting(head)
local voiceId = playerVoice[player.UserId] or VOICES[DEFAULT_VOICE] or "1"
local tts = Instance.new("AudioTextToSpeech")
tts.Name = "ChatTTS"
tts.Parent = head
tts.VoiceId = voiceId
tts.Volume = 3
local emitter = Instance.new("AudioEmitter")
emitter.Name = "ChatTTSEmitter"
emitter.Parent = head
local ok, err = pcall(function()
emitter:SetDistanceAttenuation({
[0] = 1,
[CHAT_RANGE * 0.5] = 0.6,
[CHAT_RANGE] = 0,
})
end)
if not ok then
warn("SetDistanceAttenuation failed:", err)
end
local wire = Instance.new("Wire")
wire.Name = "ChatTTSWire"
wire.Parent = head
wire.SourceInstance = tts
wire.TargetInstance = emitter
local success, filterResult = pcall(function()
return TextService:FilterStringAsync(message, player.UserId)
end)
if success and filterResult then
tts.Text = message
tts:Play()
else
tts:Destroy()
emitter:Destroy()
wire:Destroy()
return
end
tts.Ended:Once(function()
if wire.Parent then wire:Destroy() end
if emitter.Parent then emitter:Destroy() end
if tts.Parent then tts:Destroy() end
end)
end
Players.PlayerAdded:Connect(function(player)
player.Chatted:Connect(function(message)
if not message or message == "" then return end
if message:sub(1,7):lower() == "!voice " then
local param = message:sub(8):gsub("^%s*(.-)%s*$", "%1") -- trim
if param ~= "" then
local id = VOICES[param]
if not id and tonumber(param) then
id = tostring(tonumber(param))
end
if id then
playerVoice[player.UserId] = id
player:SendNotification({
Title = "Voice Changed",
Text = "Your TTS voice is now: " .. param,
Duration = 3
})
else
player:SendNotification({
Title = "Voice Error",
Text = "Invalid voice name or ID.",
Duration = 3
})
end
end
return
end
playChatTTS(player, message)
end)
end)
I made some improvements:
!voice
command that lets you change your voice per id or nameWhat I couldnt figure out yet (since it got late ) is how to add reverb from the
SoundService
. I changed it to “Cave" but didnt notice any difference… maybe its something with the emitter or the wire; ’m not entirely sure. Im gonna look into that tomorrow!!!
I tried my best to build on what you shared and made it for my teast a little “better”. Hope this helps others too!!!