Tekst na mowę to forma technologii wspomagającej, która przekształca ciągi tekstowe w dźwięki mowy za pomocą sztucznego głosu. Oprócz poprawy dostępności twoich gier dla graczy z niepełnosprawnościami wzrokowymi, ruchowymi lub poznawczymi, TTS pozwala na dynamiczne generowanie mowy, dzięki czemu nie musisz nagrywać audio dla wszystkich możliwych scenariuszy narracyjnych.
Używając pliku Gingerbread House - Start .rbxl jako punktu wyjścia oraz Gingerbread House - Tekst na mowę jako odniesienia, ten samouczek pokazuje, jak dodać zarówno podstawowy, jak i kontekstowy dźwięk TTS do swoich gier, w tym wskazówki dotyczące:
- Uruchamiania TTS dla typowych scenariuszy rozgrywki, które nigdy się nie zmienią, takich jak interakcje z interfejsem użytkownika i samouczki.
- Konfigurowania TTS, aby dostosowywał się do działań gracza, statusu środowiska lub elastycznych celów.
Jeśli w którymkolwiek momencie utkniesz w procesie, możesz użyć Gingerbread House - Tekst na mowę jako odniesienia, aby porównać swoje postępy.
Obiekty audio
Aby stworzyć dźwięk TTS, ważne jest, aby zrozumieć obiekty audio, z którymi będziesz pracować w tym samouczku. Istnieje pięć głównych typów obiektów audio dla TTS:
- Obiekt AudioTextToSpeech przekształca ciągi tekstowe w dźwięki mowy.
- Obiekt AudioEmitter to wirtualny głośnik, który emituje dźwięk w środowisku 3D.
- Obiekt AudioListener to wirtualny mikrofon, który odbiera dźwięk z środowiska 3D.
- Obiekt AudioDeviceOutput to fizyczne urządzenie sprzętowe w rzeczywistym świecie, takie jak głośnik lub słuchawki.
- Wires przenoszą strumienie audio z jednego obiektu do drugiego.
Wszystkie te obiekty audio współpracują ze sobą, aby emitować dźwięk TTS w odpowiedzi na działania gracza. Przyjrzyjmy się, jak to działa w praktyce dla dźwięku 3D, używając przykładu gracza noszącego słuchawki podczas grania w grę na swoim laptopie:
- Obiekt AudioTextToSpeech ładuje i przekształca tekst w audio, gdy gracz dotyka części w pobliżu postaci niegrywalnej (NPC).
- Obiekt AudioEmitter emituje strumień dźwięku TTS z NPC do środowiska 3D.
- Dziecko postaci obiektu AudioListener słucha tego dźwięku w środowisku 3D i przekazuje go z powrotem do ich słuchawek.
- Obiekt AudioDeviceOutput przenosi dźwięk z AudioListener do fizycznego głośnika gracza, lub w tym przypadku, ich słuchawek.
Następujące sekcje zagłębiają się w te obiekty, gdy uczysz się, jak odtwarzać zarówno podstawowy, jak i kontekstowy dźwięk. Przeglądając te obiekty z nadchodzącymi technikami, możesz dokładniej przewidzieć, jak uchwycić i przekazać dźwięk z gry do gracza.
Podstawowy TTS
Podstawowy TTS to najczęstsza forma tekstu na mowę, w której sztuczny głos odczytuje ciąg tekstowy niezależnie od kontekstu gracza lub środowiska. Oznacza to, że za każdym razem, gdy gracz uruchamia dźwięk TTS, słowa i sposób, w jaki sztuczny głos je odczytuje, pozostają spójne, niezależnie od stanu gracza, jego działań lub statusu środowiska.
Ta forma TTS jest przydatna w większości scenariuszy rozgrywki, takich jak interakcje graczy z menu interfejsu użytkownika, samouczki lub rutynowe interakcje z NPC, takie jak oferty sprzedawców lub krzyki wrogów. Roblox dostarcza następujące typy głosów, z którymi możesz eksperymentować w dowolnych z tych interakcji:
| VoiceID | Opis głosu | Przykład audio |
|---|---|---|
| 1 | Brytyjski mężczyzna | |
| 2 | Brytyjska kobieta | |
| 3 | Mężczyzna z USA #1 | |
| 4 | Kobieta z USA #1 | |
| 5 | Mężczyzna z USA #2 | |
| 6 | Kobieta z USA #2 | |
| 7 | Australijski mężczyzna | |
| 8 | Australijska kobieta | |
| 9 | Retro głos #1 | |
| 10 | Retro głos #2 | |
| 11 | Głos narratora | |
| 101 | Hiszpański mężczyzna | |
| 102 | Hiszpańska kobieta | |
| 201 | Niemiecki mężczyzna | |
| 202 | Niemiecka kobieta | |
| 301 | Włoski mężczyzna | |
| 302 | Włoska kobieta | |
| 401 | Francuski mężczyzna | |
| 402 | Francuska kobieta |
Aby odtworzyć podstawowy dźwięk TTS 3D w przykładowym pliku Gingerbread House - Tekst na mowę:
- Włącz domyślny słuchacz, który jest przypisany do postaci gracza.
- W oknie Eksplorator wybierz SoundService.
- W oknie Właściwości ustaw DefaultListenerLocation na Character. Gdy uruchomisz grę, silnik automatycznie:
- Tworzy AudioListener pod Humanoid.RootPart każdej postaci gracza, abyś mógł słyszeć dźwięki przesuwające się w twoich rzeczywistych głośnikach w zależności od pozycji i skali źródeł dźwięku w grze.
- Tworzy AudioDeviceOutput pod SoundService.
- W oknie Eksplorator przejdź do Workspace ⟩ DialogueVolume, a następnie:
- Wstaw obiekt AudioTextToSpeech, aby stworzyć generator mowy audio dla objętości wokół bałwana.
- Wstaw obiekt AudioEmitter, aby emitować strumień pozycyjny z DialogueVolume.
- Wstaw obiekt Wire, aby przenieść strumień z generatora mowy audio do emitera audio.
- Wybierz obiekt AudioTextToSpeech, a następnie w oknie Właściwości:
- Ustaw Text na "Zbierz każdy ostatni gumpdrop, aby otworzyć mój dom!"
- Ustaw VoiceId na 2, aby ustawić sztuczny głos na emulację brytyjskiej kobiety.
- Ustaw Volume na 3, aby odtwarzać dźwięk na wysokim poziomie, abyś mógł usłyszeć dźwięk TTS ponad innymi źródłami dźwięku w grze.
- Wybierz Wire, a następnie w oknie Właściwości:
- Ustaw SourceInstance na nowy AudioTextToSpeech, aby określić, że chcesz, aby przewód przenosił dźwięk z tego konkretnego generatora mowy audio.
- Ustaw TargetInstance na nowy AudioEmitter, aby określić, że chcesz, aby przewód przenosił dźwięk do tego konkretnego emitera audio w obrębie objętości.
- Wróć do okna Eksplorator, przejdź do StarterPlayer ⟩ StarterCharacterScripts, a następnie wstaw LocalScript, zmień jego nazwę na PlayBasicTTSAudioWhenInVolume i wklej następujący kod do lokalnego skryptu:
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)Ten skrypt zaczyna od uzyskania usług Workspace i Players, aby mógł odwołać się do ich dzieci i funkcjonalności. Dla każdej postaci gracza, która ładuje się lub odradza w grze, skrypt czeka na:
- Obiekt objętości w przestrzeni roboczej o nazwie DialogueVolume.
Gdy cokolwiek koliduje z objętością, funkcja obsługi zdarzenia Touched uzyskuje pierwszego przodka, który jest Model, co powinno być postacią, jeśli BasePart, który kolidował z objętością, jest potomkiem modelu postaci. Jeśli tak jest, funkcja następnie:
- Ustawia debounce na true.
- Odtwarza i czeka na zakończenie dźwięku TTS.
- Ustawia debounce z powrotem na false.
Ustawienie debounce z false na true, a następnie z powrotem na false po zakończeniu odtwarzania podstawowego dźwięku TTS jest wzorcem debounce, który zapobiega wielokrotnemu uruchamianiu dźwięku, gdy gracze ciągle kolidują z objętością. Aby uzyskać więcej informacji na temat tego wzorca debounce, zobacz Debounce - Wykrywanie kolizji.
Przetestuj grę, aby usłyszeć dialog instruktażowy postaci, gdy twoja postać gracza dotknie objętości wokół bałwana.
Możesz dalej eksperymentować z tym dźwiękiem, modyfikując właściwości Text, VoiceID, Pitch i Speed na nowe wartości. Generowana mowa staje się całkowicie inna bez potrzeby nagrywania i przesyłania nowego pliku audio dla każdego scenariusza.
TTS z uwzględnieniem kontekstu
TTS z uwzględnieniem kontekstu to bardziej zaawansowana forma tekstu na mowę, w której sztuczny głos odczytuje ciąg tekstowy w odniesieniu do gracza, stanu ich środowiska lub statusu rozgrywki. Oznacza to, że za każdym razem, gdy gracz uruchamia dźwięk TTS, słowa i sposób, w jaki sztuczny głos je odczytuje, dostosowują się odpowiednio.
Ta forma TTS jest przydatna w scenariuszach rozgrywki, które są ciągle zmieniające się, takich jak kierunkowe wskazówki dźwiękowe, status celów lub unikalne interakcje z NPC. W związku z tym, ponieważ TTS z uwzględnieniem kontekstu musi się przekształcać, aby być dokładnym, musisz skonfigurować elementy rozgrywki, aby móc śledzić ich status, gdy gracze poruszają się po środowisku i realizują cele rozgrywki.
Chociaż istnieje wiele sposobów na osiągnięcie tego zadania, przykład używa niestandardowych atrybutów do śledzenia koloru i lokalizacji każdego gumpdropa, który gracz musi zebrać, aby wejść do domku z piernika. Aby uzyskać więcej informacji na temat atrybutów, zobacz Właściwości i atrybuty.



Aby odtworzyć dźwięk TTS 3D z uwzględnieniem kontekstu w przykładowym pliku Gingerbread House - Tekst na mowę:
W oknie Eksplorator przejdź do Workspace ⟩ GumDrops.
Skonfiguruj trzy niestandardowe atrybuty, aby śledzić żółty gumpdrop.
- Wybierz żółty gumpdrop, a następnie w oknie Właściwości przejdź do sekcji Atrybuty, a następnie kliknij ikonę plusa. Pojawi się okno dialogowe.
- W polu Nazwa wpisz ColorDescription.
- W menu rozwijanym Typ wybierz string.
- Kliknij przycisk Zapisz.
- Ustaw nowy atrybut ColorDescription na żółty.
- Używając tego procesu, stwórz dwa dodatkowe atrybuty, używając następujących wartości.
Nazwa Typ Wartość HintOrder number 0 LocationDescription string przy wodospadzie Skonfiguruj trzy niestandardowe atrybuty, aby śledzić zielony gumpdrop.
- W oknie Eksplorator wybierz zielony gumpdrop.
- W oknie Właściwości stwórz trzy atrybuty, używając następujących wartości.
Nazwa Typ Wartość ColorDescription string zielony HintOrder number 1 LocationDescription string na krawędzi Skonfiguruj trzy niestandardowe atrybuty, aby śledzić czerwony gumpdrop.
- W oknie Eksplorator wybierz czerwony gumpdrop.
- W oknie Właściwości stwórz trzy atrybuty, używając następujących wartości.
Nazwa Typ Wartość ColorDescription string czerwony HintOrder number 2 LocationDescription string za płotem W oknie Eksplorator przejdź do Workspace ⟩ HintVolume, a następnie:
- Wstaw obiekt AudioTextToSpeech, aby stworzyć generator mowy audio dla objętości wokół renifera.
- Wstaw obiekt AudioEmitter, aby emitować strumień pozycyjny z HintVolume.
- Wstaw obiekt Wire, aby przenieść strumień z generatora mowy audio do emitera audio.
Wybierz Wire, a następnie w oknie Właściwości:
- Ustaw SourceInstance na nowy AudioTextToSpeech, aby określić, że chcesz, aby przewód przenosił dźwięk z tego konkretnego generatora mowy audio.
- Ustaw TargetInstance na nowy AudioEmitter, aby określić, że chcesz, aby przewód przenosił dźwięk do tego konkretnego emitera audio w obrębie objętości.
Wróć do okna Eksplorator, przejdź do StarterPlayer ⟩ StarterCharacterScripts, a następnie wstaw LocalScript, zmień jego nazwę na PlayContextTTSAudioWhenInVolume i wklej następujący kod do lokalnego skryptu:
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 "Nie ma już gumpdropów. Sprawdź w środku domu."
end
local nextGumdrop = remainingGumdrops[1]
local colorDescription = nextGumdrop:GetAttribute("ColorDescription")
local locationDescription = nextGumdrop:GetAttribute("LocationDescription")
local message = #remainingGumdrops > 1
and "Zostało " .. #remainingGumdrops .. " gumpdropów. Szukaj " .. colorDescription .. " w " .. locationDescription .. "."
or "Został jeden gumpdrop. Jest " .. colorDescription .. " i znajduje się " .. 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("Gracz dotknął objętości.")
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)Ten skrypt zaczyna od uzyskania usług Workspace i Players, aby mógł odwołać się do ich dzieci i funkcjonalności. Dla każdej postaci gracza, która ładuje się lub odradza w grze, skrypt czeka na:
- Obiekt objętości w przestrzeni roboczej o nazwie HintVolume.
Funkcja getRemainingGumdrops() skryptu zwraca listę obiektów gumpdrop Part w folderze Gumdrops i filtruje wszelkie części, które gracz zebrał. Pozostałe gumpdropy są sortowane w określonej kolejności zgodnie z atrybutem HintOrder każdego gumpdropa.
Funkcja getReindeerHint(remainingGumdrops) skryptu przyjmuje tę listę z getRemainingGumdrops() i zwraca komunikat tekstowy, który opisuje, gdzie gracz może znaleźć pozostałe gumpdropy, w tym zarówno opis koloru, jak i lokalizacji następnego gumpdropa, który gracz musi zebrać. Jednak jeśli gracz zebrał wszystkie gumpdropy w środowisku, komunikat tekstowy opisuje, gdzie udać się dalej po zebraniu wszystkich gumpdropów w środowisku.
Gdy cokolwiek koliduje z objętością, funkcja obsługi zdarzenia Touched uzyskuje pierwszego przodka, który jest Model, co powinno być postacią, jeśli BasePart, który kolidował z objętością, jest potomkiem modelu postaci. Jeśli tak jest, funkcja następnie:
- Ustawia debounce na true.
- Uzyskuje listę pozostałych gumpdropów i komunikat tekstowy opisujący następnego gumpdropa, którego gracz musi znaleźć.
- Przekształca tekst w audio za pomocą obiektu AudioTextToSpeech, odtwarza dźwięk i czeka na zakończenie dźwięku.
- Ustawia debounce z powrotem na false.
Ustawienie debounce z false na true, a następnie z powrotem na false po zakończeniu odtwarzania dźwięku TTS z uwzględnieniem kontekstu jest wzorcem debounce, który zapobiega wielokrotnemu uruchamianiu dźwięku, gdy gracze ciągle kolidują z objętością. Aby uzyskać więcej informacji na temat tego wzorca debounce, zobacz Debounce - Wykrywanie kolizji.
Przetestuj grę, aby usłyszeć kontekstowe wskazówki, gdy twoja postać gracza dotknie objętości wokół renifera. Dźwięk TTS zmienia się w zależności od liczby i koloru gumpdropów, które postać gracza już znalazła w środowisku.