テキスト読み上げは、テキスト文字列を人工的な声で音声に変換する支援技術の一形態です。これにより、視覚、運動、または認知の障害を持つプレイヤーのためにあなたの経験のアクセス性が向上するだけでなく、すべての可能な物語シナリオのためにオーディオを事前に録音する必要がなく、動的に音声を生成することができます。
ジンジャーブレッドハウス - スタート .rbxlファイルを出発点として、ジンジャーブレッドハウス - テキスト読み上げを参照にし、このチュートリアルは、基本的およびコンテキストに応じたTTSオーディオを経験に追加する方法を示し、以下のガイダンスを含みます。
- UIインタラクションやチュートリアルのように変わらない一般的なゲームプレイシナリオに対してTTSをトリガーする方法。
- プレイヤーの行動、環境の状態、または柔軟な目標に応じて適応するようにTTSを設定する方法。
プロセスで行き詰まった場合は、ジンジャーブレッドハウス - テキスト読み上げを参照して進捗を比較することができます。
オーディオオブジェクト
TTSオーディオを作成するには、このチュートリアル全体で扱うオーディオオブジェクトを理解することが重要です。TTS用のオーディオオブジェクトには5つの主要なタイプがあります。
- AudioTextToSpeechオブジェクトは、テキスト文字列を音声に変換します。
- AudioEmitterオブジェクトは、音声を3D環境に発信する 仮想スピーカー です。
- AudioListenerオブジェクトは、3D環境から音声を拾う 仮想マイク です。
- AudioDeviceOutputオブジェクトは、スピーカーやヘッドフォンのような 物理ハードウェアデバイス です。
- Wires は、オーディオストリームを別のオブジェクトに運びます。
これらすべてのオーディオオブジェクトは、プレイヤーの行動に応じてTTS音声を出すために連携します。この仕組みを理解するために、プレイヤーがラップトップで経験をプレイしている際にヘッドセットを装着している例を見てみましょう。
- プレイヤーが非プレイアブルキャラクター(NPC)近くのパートに触れると、AudioTextToSpeechがテキストを読み込み、音声に変換します。
- AudioEmitterは、NPCから3D環境にTTSオーディオのストリームを発信します。
- キャラクターの子であるAudioListenerオブジェクトは、3D環境内でその音を聞き取り、ヘッドセットにフィードバックします。
- AudioDeviceOutputオブジェクトは、AudioListenerからプレイヤーの物理スピーカー、またはこの場合はヘッドフォンに音を運びます。
次のセクションでは、これらのオブジェクトについてさらに詳しく掘り下げ、基本的およびコンテキストに応じたオーディオを再生する方法を学びます。これらのオブジェクトと今後の技術をレビューすることで、経験からプレイヤーに音をキャプチャし、フィードバックする方法をより正確に予測できるようになります。
基本TTS
基本TTSは、プレイヤーや環境のコンテキストに関わらず、人工的な声がテキスト文字列を読み上げる最も一般的な形式です。これは、プレイヤーがTTSオーディオをトリガーするたびに、言葉や人工的な声の読み上げ方がプレイヤーの状態、行動、または環境の状態に関係なく一貫していることを意味します。
この形式のTTSは、プレイヤーがUIメニュー、チュートリアル、またはベンダーの提供や敵の吠え声のようなルーチンNPCインタラクションに関与するなど、ほとんどのゲームプレイシナリオで役立ちます。Robloxは、これらのインタラクションのいずれかに対して試すことができる以下の種類の声を提供しています:
| VoiceID | 声の説明 | オーディオ例 |
|---|---|---|
| 1 | イギリスの男性 | |
| 2 | イギリスの女性 | |
| 3 | アメリカ合衆国の男性 #1 | |
| 4 | アメリカ合衆国の女性 #1 | |
| 5 | アメリカ合衆国の男性 #2 | |
| 6 | アメリカ合衆国の女性 #2 | |
| 7 | オーストラリアの男性 | |
| 8 | オーストラリアの女性 | |
| 9 | レトロな声 #1 | |
| 10 | レトロな声 #2 | |
| 11 | ナレーターの声 | |
| 101 | スペイン語の男性 | |
| 102 | スペイン語の女性 | |
| 201 | ドイツ語の男性 | |
| 202 | ドイツ語の女性 | |
| 301 | イタリア語の男性 | |
| 302 | イタリア語の女性 | |
| 401 | フランス語の男性 | |
| 402 | フランス語の女性 |
サンプルの ジンジャーブレッドハウス - テキスト読み上げ プレースファイルで基本的な3D TTSオーディオを再現するには:
- プレイヤーキャラクターに接続されたデフォルトリスナーを有効にします。
- Explorerウィンドウで、SoundServiceを選択します。
- Propertiesウィンドウで、DefaultListenerLocationをCharacterに設定します。経験を実行すると、エンジンは自動的に:
- 各プレイヤーキャラクターのHumanoid.RootPartの下にAudioListenerを作成し、経験内の音源の位置や音のスケールに応じてリアルワールドのスピーカーから音が移動するのを聞けるようにします。
- SoundServiceの下にAudioDeviceOutputを作成します。
- Explorerウィンドウで、Workspace ⟩ DialogueVolumeに移動し、次に:
- AudioTextToSpeechオブジェクトを挿入して、雪だるまの周りのボリューム用のオーディオ音声生成器を作成します。
- AudioEmitterオブジェクトを挿入して、DialogueVolumeからポジショナルストリームを発信します。
- オーディオ音声生成器からオーディオエミッタにストリームを運ぶためにWireオブジェクトを挿入します。
- AudioTextToSpeechオブジェクトを選択し、Propertiesウィンドウで:
- Textを「最後のガムドロップをすべて集めて私の家を開けて!」に設定します。
- VoiceIdを2に設定して、人工の声をイギリスの女性の声にエミュレートします。
- Volumeを3に設定して、他の音声ソースを超えてTTS音声が聞こえるように高い音量で再生します。
- Wireを選択し、Propertiesウィンドウで:
- SourceInstanceを新しいAudioTextToSpeechに設定して、ワイヤがこの特定のオーディオ音声生成器から音を運ぶことを指定します。
- TargetInstanceを新しいAudioEmitterに設定して、ワイヤがボリューム内のこの特定のオーディオエミッタに音を運ぶことを指定します。
- Explorerウィンドウに戻り、StarterPlayer ⟩ StarterCharacterScriptsに移動し、次にLocalScriptを挿入し、名前をPlayBasicTTSAudioWhenInVolumeに変更し、次のコードをローカルスクリプトに貼り付けます:
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)
このスクリプトは、WorkspaceとPlayersサービスを取得して、それらの子供や機能を参照できるようにすることから始まります。経験に最初にロードされる、または再スポーンする各プレイヤーキャラクターのために、スクリプトは次を待ちます:
- 名前が DialogueVolume のワークスペース内のボリュームオブジェクト。
何かがボリュームに衝突すると、Touchedイベントハンドラ関数はModelである最初の親を取得します。これは、衝突したBasePartがキャラクターモデルの子孫である場合、キャラクターであるはずです。もしそうであれば、関数は次のようにします:
- デバウンスをtrueに設定します。
- TTS音声を再生し、その終了を待ちます。
- デバウンスをfalseに戻します。
デバウンスを false から true に、再び基本TTSオーディオが再生された後に false に設定することは、プレイヤーが継続的にボリュームに衝突する際にオーディオが繰り返しトリガーされるのを防ぐデバウンスパターンです。このデバウンスパターンの詳細については、デバウンス - 衝突を検出するを参照してください。
経験をプレイテストして、プレイヤーキャラクターが雪だるまの周りのボリュームに触れたときに指導キャラクターのダイアログを聞きます。
Text、VoiceID、Pitch、およびSpeedプロパティを新しい値に変更することで、さらにこの音声を実験できます。生成されたスピーチは、シナリオごとに新しいオーディオファイルを録音・アップロードする必要なく、完全に異なります。
コンテキストに応じたTTS
コンテキストに応じたTTSは、プレイヤー、環境の状態、またはゲームプレイのステータスに関連してテキスト文字列を読み上げる、より高度な形式のテキスト読み上げです。これは、プレイヤーがTTSオーディオをトリガーするたびに、言葉や人工的な声の読み方が適応することを意味します。
この形式のTTSは、方向性オーディオキュー、目標の状態、またはユニークなNPCインタラクションのように、常に変わるゲームプレイシナリオに役立ちます。したがって、コンテキストに応じたTTSは正確であるために変化が必要であるため、プレイヤーが環境をナビゲートし、ゲームプレイ目標を達成する際に、それらの状態を追跡できるようにゲームプレイ要素を設定する必要があります。
このタスクを達成する方法はいくつかありますが、サンプルではカスタム属性を使用してプレイヤーが集めなければならない各ガムドロップの色と位置を追跡します。属性の詳細については、プロパティと属性を参照してください。



サンプルの ジンジャーブレッドハウス - テキスト読み上げ プレースファイルでコンテキストに応じた3D TTSオーディオを再現するには:
Explorerウィンドウで、Workspace ⟩ GumDropsに移動します。
黄色のガムドロップを追跡するために3つのカスタム属性を設定します。
- 黄色のガムドロップを選択し、PropertiesウィンドウでAttributesセクションに移動し、プラスアイコンをクリックします。ポップアップダイアログが表示されます。
- NameフィールドにColorDescriptionを入力します。
- Typeのドロップダウンメニューで、stringを選択します。
- Saveボタンをクリックします。
- 新しいColorDescription属性をyellowに設定します。
- このプロセスを使用して、以下の値を持つ2つの属性をさらに作成します。
名前 タイプ 値 HintOrder number 0 LocationDescription string 滝のそば 緑色のガムドロップを追跡するために3つのカスタム属性を設定します。
- Explorerウィンドウで、緑色のガムドロップを選択します。
- Propertiesウィンドウで、以下の値を持つ3つの属性を作成します。
名前 タイプ 値 ColorDescription string green HintOrder number 1 LocationDescription string ledgeの上 赤色のガムドロップを追跡するために3つのカスタム属性を設定します。
- Explorerウィンドウで、赤色のガムドロップを選択します。
- Propertiesウィンドウで、以下の値を持つ3つの属性を作成します。
名前 タイプ 値 ColorDescription string red HintOrder number 2 LocationDescription string フェンスの後ろ Explorerウィンドウで、Workspace ⟩ HintVolumeに移動し、次に:
- AudioTextToSpeechオブジェクトを挿入して、トナカイの周りのボリューム用のオーディオ音声生成器を作成します。
- AudioEmitterオブジェクトを挿入して、HintVolumeからポジショナルストリームを発信します。
- オーディオ音声生成器からオーディオエミッタにストリームを運ぶためにWireオブジェクトを挿入します。
Wireを選択し、Propertiesウィンドウで:
- SourceInstanceを新しいAudioTextToSpeechに設定して、ワイヤがこの特定のオーディオ音声生成器から音を運ぶことを指定します。
- TargetInstanceを新しいAudioEmitterに設定して、ワイヤがボリューム内のこの特定のオーディオエミッタに音を運ぶことを指定します。
Explorerウィンドウに戻り、StarterPlayer ⟩ StarterCharacterScriptsに移動し、次にLocalScriptを挿入し、名前をPlayContextTTSAudioWhenInVolumeに変更し、次のコードをローカルスクリプトに貼り付けます:
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 "ガムドロップはもう残っていません。家の中をチェックしてください。"
end
local nextGumdrop = remainingGumdrops[1]
local colorDescription = nextGumdrop:GetAttribute("ColorDescription")
local locationDescription = nextGumdrop:GetAttribute("LocationDescription")
local message = #remainingGumdrops > 1
and #remainingGumdrops .. " 個のガムドロップが残っています。" .. colorDescription .. "のものを" .. locationDescription .. "見つけてください。"
or "1個のガムドロップが残っています。それは" .. colorDescription .. "で" .. 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("プレイヤーがボリュームに触れました。")
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)
このスクリプトは、WorkspaceとPlayersサービスを取得して、それらの子供や機能を参照できるようにすることから始まります。経験に最初にロードされる、または再スポーンする各プレイヤーキャラクターのために、スクリプトは次を待ちます:
- 名前が HintVolume のワークスペース内のボリュームオブジェクト。
スクリプトの getRemainingGumdrops() 関数は、Gumdrops フォルダ内のガムドロップ Part オブジェクトのリストを返し、プレイヤーが収集したパートをフィルタリングします。残りのガムドロップは、それぞれのガムドロップの HintOrder 属性に基づいて特定の順序でソートされます。
スクリプトの getReindeerHint(remainingGumdrops) 関数は、そのリストを取得し、プレイヤーが集める必要がある次のガムドロップの色と位置を説明する文字列メッセージを返します。ただし、プレイヤーが環境内のすべてのガムドロップを収集した場合、文字列メッセージは、環境内のすべてのガムドロップを収集した後に次に行くべき場所を示します。
何かがボリュームに衝突すると、Touchedイベントハンドラ関数はModelである最初の親を取得します。これは、衝突したBasePartがキャラクターモデルの子孫である場合、キャラクターであるはずです。もしそうであれば、関数は次のようにします:
- デバウンスをtrueに設定します。
- 残っているガムドロップのリストと、プレイヤーが見つける必要のある次のガムドロップを説明する文字列メッセージを取得します。
- 文字列をAudioTextToSpeechオブジェクトを使ってオーディオに変換し、オーディオを再生し、その終了を待ちます。
- デバウンスをfalseに戻します。
デバウンスを false から true に、再びコンテキストに応じたTTSオーディオが再生された後に false に設定することは、プレイヤーが継続的にボリュームに衝突する際にオーディオが繰り返しトリガーされるのを防ぐデバウンスパターンです。このデバウンスパターンの詳細については、デバウンス - 衝突を検出するを参照してください。
経験をプレイテストして、プレイヤーキャラクターがトナカイの周りのボリュームに触れたときにコンテキストに応じたヒントを聞きます。TTSオーディオは、プレイヤーキャラクターが環境内で既に見つけたガムドロップの数と色に応じて変わります。