การเปลี่ยนข้อความเป็นเสียง เป็นรูปแบบของเทคโนโลยีช่วยเหลือที่แปลงข้อความเป็นเสียงพูดโดยใช้เสียงเทียม นอกจากจะช่วยปรับปรุงการเข้าถึงของประสบการณ์สำหรับผู้เล่นที่มีความบกพร่องทางสายตา การเคลื่อนไหว หรือการรับรู้แล้ว TTS ยังช่วยให้คุณสร้างเสียงพูดแบบไดนามิกได้ เพื่อที่คุณจะไม่ต้องบันทึกเสียงล่วงหน้าสำหรับทุกสถานการณ์เรื่องราวที่เป็นไปได้
โดยใช้ไฟล์ Gingerbread House - เริ่มต้น .rbxl เป็นจุดเริ่มต้นและ Gingerbread House - การเปลี่ยนข้อความเป็นเสียง เป็นการอ้างอิง บทเรียนนี้จะสอนวิธีการเพิ่มเสียง TTS ที่พื้นฐานและตอบสนองต่อบริบทลงไปในประสบการณ์ของคุณ รวมถึงคำแนะนำเกี่ยวกับ:
- การกระตุ้น TTS สำหรับสถานการณ์การเล่นเกมทั่วไปที่ไม่เคยเปลี่ยนแปลง เช่น การโต้ตอบ UI และการสอน
- การตั้งค่า TTS เพื่อให้มันปรับตัวเข้ากับการกระทำของผู้เล่น สถานะของสิ่งแวดล้อม หรือวัตถุประสงค์ที่ยืดหยุ่น
หากในบางจุดคุณติดขัดในกระบวนการ คุณสามารถใช้ Gingerbread House - การเปลี่ยนข้อความเป็นเสียง เป็นการอ้างอิงเพื่อเปรียบเทียบความก้าวหน้าของคุณ
วัตถุเสียง
การสร้างเสียง TTS นั้นสำคัญที่จะต้องเข้าใจวัตถุเสียงที่คุณจะทำงานด้วยตลอดบทเรียนนี้ มีวัตถุเสียงหลัก 5 ประเภทสำหรับ TTS:
- วัตถุ AudioTextToSpeech แปลงข้อความเป็นเสียงพูด
- วัตถุ AudioEmitter เป็น ลำโพงเสมือน ที่ปล่อยเสียงในสภาพแวดล้อม 3 มิติ
- วัตถุ AudioListener เป็น ไมโครโฟนเสมือน ที่รับเสียงจากสภาพแวดล้อม 3 มิติ
- วัตถุ AudioDeviceOutput เป็น อุปกรณ์ฮาร์ดแวร์ทางกายภาพ ในโลกจริง เช่น ลำโพงหรือหูฟัง
- Wires เป็นสายที่นำเสียงจากวัตถุหนึ่งไปยังอีกวัตถุหนึ่ง
วัตถุเสียงทั้งหมดเหล่านี้ทำงานร่วมกันเพื่อปล่อยเสียง TTS ตามการกระทำของผู้เล่น มาดูวิธีการทำงานนี้ในทางปฏิบัติสำหรับเสียง 3 มิติ โดยยกตัวอย่างผู้เล่นที่สวมหูฟังขณะเล่นประสบการณ์ด้วยแล็ปท็อปของพวกเขา:
- AudioTextToSpeech โหลดและแปลงข้อความเป็นเสียงเมื่อผู้เล่นสัมผัสส่วนใกล้ตัวละครที่ไม่สามารถเล่นได้ (NPC)
- AudioEmitter ปล่อยเสียง TTS จาก NPC ลงในสภาพแวดล้อม 3 มิติ
- วัตถุ AudioListener ของตัวละครฟังเสียงนั้นในสภาพแวดล้อม 3 มิติและนำกลับไปยังหูฟังของพวกเขา
- วัตถุ AudioDeviceOutput นำเสียงจาก AudioListener ไปยังลำโพงทางกายภาพของผู้เล่น หรือในกรณีนี้คือหูฟังของพวกเขา
ส่วนถัดไปจะเจาะลึกและนำเสนอวัตถุเหล่านี้เมื่อคุณเรียนรู้วิธีการเล่นเสียงพื้นฐานและตอบสนองต่อบริบท เมื่อคุณตรวจสอบวัตถุเหล่านี้พร้อมกับเทคนิคที่กำลังจะเกิดขึ้น คุณสามารถคาดการณ์ได้อย่างแม่นยำว่าจะจับเสียงและส่งเสียงจากประสบการณ์ไปยังผู้เล่นได้อย่างไร
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 | หญิงฝรั่งเศส |
เพื่อสร้างเสียง TTS 3 มิติพื้นฐานในไฟล์ตัวอย่าง Gingerbread House - การเปลี่ยนข้อความเป็นเสียง:
- เปิดใช้งานผู้ฟังเริ่มต้นที่เชื่อมต่อกับตัวละครของผู้เล่น
- ในหน้าต่าง Explorer ให้เลือก SoundService
- ในหน้าต่าง Properties ตั้งค่า DefaultListenerLocation เป็น Character เมื่อคุณเรียกใช้ประสบการณ์ เอนจินจะสร้างโดยอัตโนมัติ:
- สร้าง AudioListener ใต้ Humanoid.RootPart ของแต่ละตัวละครของผู้เล่นเพื่อให้คุณสามารถได้ยินเสียงเปลี่ยนไปตามลำโพงในโลกจริงตามตำแหน่งและขนาดของแหล่งเสียงภายในประสบการณ์
- สร้าง AudioDeviceOutput ใต้ SoundService
- ในหน้าต่าง 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 ที่ชนกับปริมาตรเป็นลูกหลานของรูปแบบตัวละคร ถ้าเป็นเช่นนั้น ฟังก์ชันนั้นจะ:
- ตั้งค่า debounce เป็น true
- เล่นและรอให้เสียง TTS จบ
- ตั้งค่า debounce กลับเป็น false
การตั้งค่า debounce จาก false เป็น true เพื่อกลับเป็น false อีกครั้งหลังจากที่เสียง TTS พื้นฐานเล่นจบ เป็นรูปแบบ debounce ที่ป้องกันไม่ให้เสียงถูกกระตุ้นซ้ำแล้วซ้ำเล่าขณะที่ผู้เล่นชนกับปริมาณนี้ต่อเนื่อง สำหรับข้อมูลเพิ่มเติมเกี่ยวกับรูปแบบ debounce นี้ ให้ดูที่ Debounce - ตรวจจับการชน.
- ทดสอบการเล่นเพื่อได้ยินการสนทนาของตัวละครสอนเมื่อพาตัวละครผู้เล่นสัมผัสกับปริมาณระหว่างตัวตุ๊กตาหิมะ
คุณสามารถทดลองเพิ่มเติมเกี่ยวกับเสียงนี้ได้โดยการปรับเปลี่ยน Text, VoiceID, Pitch, และ Speed ให้มีค่าใหม่ คำพูดที่สร้างขึ้นจะแตกต่างออกไปโดยไม่จำเป็นต้องบันทึกและอัปโหลดไฟล์เสียงใหม่สำหรับแต่ละสถานการณ์
TTS ที่ตอบสนองต่อบริบท
TTS ที่ตอบสนองต่อบริบทเป็นรูปแบบที่ก้าวหน้ามากขึ้นของการเปลี่ยนข้อความเป็นเสียงซึ่งเสียงเทียมจะอ่านข้อความตามผู้เล่น สถานะของสิ่งแวดล้อม หรือสถานะของเกม นั่นหมายความว่าเมื่อใดก็ตามที่ผู้เล่นกระตุ้นเสียง TTS คำและวิธีที่เสียงเทียมอ่านคำจะปรับตัวให้เข้ากับบริบท
รูปแบบนี้มีประโยชน์สำหรับสถานการณ์การเล่นเกมที่เปลี่ยนแปลงตลอดเวลา เช่น ข้อมูลเสียงตามทิศทาง สถานะวัตถุประสงค์ หรือการโต้ตอบกับ NPC ที่ไม่เหมือนใคร ดังนั้น เนื่องจาก TTS ที่ตอบสนองต่อบริบทต้องปรับเปลี่ยนเพื่อให้แม่นยำ คุณต้องตั้งค่าส่วนประกอบการเล่นเกมเพื่อให้คุณสามารถติดตามสถานะของพวกเขาเมื่อผู้เล่นเข้าไปในสภาพแวดล้อมและทำภารกิจในเกมให้สำเร็จ
ในขณะที่มีหลายวิธีในการทำงานนี้ ตัวอย่างจะใช้คุณลักษณะกำหนดเองเพื่อเก็บข้อมูล สี และ ตำแหน่ง ของแต่ละกัมดรอปที่ผู้เล่นต้องเก็บเพื่อเข้าสู่บ้านขนมปังขิง สำหรับข้อมูลเพิ่มเติมเกี่ยวกับคุณลักษณะ ให้ดูที่ คุณสมบัติและคุณลักษณะ.



เพื่อสร้างเสียง TTS 3 มิติที่ตอบสนองต่อบริบทในไฟล์ตัวอย่าง Gingerbread House - การเปลี่ยนข้อความเป็นเสียง:
- ในหน้าต่าง Explorer ให้เข้าไปที่ Workspace ⟩ GumDrops
- ตั้งค่าคุณลักษณะกำหนดเองสามอย่างเพื่อติดตามกัมดรอปสีเหลือง
- เลือกกัมดรอปสีเหลือง จากนั้นในหน้าต่าง Properties ไปที่ส่วน Attributes และคลิกที่ไอคอนบวก กล่องโต้ตอบป๊อปอัพจะแสดงขึ้น
- ในฟิลด์ Name ให้ป้อน ColorDescription
- ในเมนูแบบเลื่อนลง Type ให้เลือก string
- คลิกปุ่ม Save
- ตั้งค่า ColorDescription ใหม่เป็น yellow
- ใช้กระบวนการนี้เพื่อสร้างคุณลักษณะอีก 2 อย่างด้วยค่าต่อไปนี้
| Name | Type | Value |
|---|---|---|
| HintOrder | number | 0 |
| LocationDescription | string | by the waterfall |
- ตั้งค่าคุณลักษณะกำหนดเองสามอย่างเพื่อติดตามกัมดรอปสีเขียว
- ในหน้าต่าง Explorer ให้เลือกกัมดรอปสีเขียว
- ในหน้าต่าง Properties ให้สร้างคุณลักษณะสามอย่างด้วยค่าต่อไปนี้
| Name | Type | Value |
|---|---|---|
| ColorDescription | string | green |
| HintOrder | number | 1 |
| LocationDescription | string | on the ledge |
- ตั้งค่าคุณลักษณะกำหนดเองสามอย่างเพื่อติดตามกัมดรอปสีแดง
- ในหน้าต่าง Explorer ให้เลือกกัมดรอปสีแดง
- ในหน้าต่าง Properties ให้สร้างคุณลักษณะสามอย่างด้วยค่าต่อไปนี้
| Name | Type | Value |
|---|---|---|
| ColorDescription | string | red |
| HintOrder | number | 2 |
| LocationDescription | string | behind the fence |
- ในหน้าต่าง 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 "ไม่มี gomdrops เหลืออยู่ ตรวจสอบข้างในบ้าน."
end
local nextGumdrop = remainingGumdrops[1]
local colorDescription = nextGumdrop:GetAttribute("ColorDescription")
local locationDescription = nextGumdrop:GetAttribute("LocationDescription")
local message = #remainingGumdrops > 1
and "ยังมี gomdrops " .. #remainingGumdrops .. " ชิ้นเหลืออยู่ มองหาสี " .. colorDescription .. " ที่ " .. locationDescription .. "."
or "มี gomdrop หนึ่งชิ้นเหลืออยู่ มันคือ " .. 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() ของสคริปต์คืนค่ารายการของวัตถุ gumdrop Part ภายในโฟลเดอร์ Gumdrops และกรองออกแต่ละส่วนที่ผู้เล่นได้เก็บมาอย่างแล้ว มันจะจัดเรียงกัมดรอปที่เหลือตามลำดับเฉพาะตามที่อยู่ของคุณลักษณะ HintOrder ของแต่ละกัมดรอป
ฟังก์ชัน getReindeerHint(remainingGumdrops) ของสคริปต์นั้นจะรับรายการที่ไปจาก getRemainingGumdrops() และจะคืนค่าเป็นข้อความสตริงที่อธิบายว่าผู้เล่นสามารถหากัมดรอปที่เหลืออยู่ในที่ใด รวมถึงคำอธิบายสีและที่ตั้งของกัมดรอปใบถัดไปที่ผู้เล่นต้องเก็บ อย่างไรก็ตาม ถ้าผู้เล่นได้เก็บกัมดรอปทั้งหมดในสภาพแวดล้อมแล้ว ข้อความจะกล่าวถึงที่ไปต่อไปหลังจากที่พวกเขาได้เก็บกัมดรอปทั้งหมดในสภาพแวดล้อมแล้ว
เมื่อมีบางอย่างชนกับปริมาณ ฟังก์ชันตัวจัดการเหตุการณ์ Touched จะดึงตัวพ่อแม่ตัวแรกที่เป็น Model ซึ่งควรจะแสดงถึงตัวละครหาก BasePart ที่ชนกับปริมาณเป็นลูกหลานของรูปแบบตัวละคร ถ้าเป็นเช่นนั้น ฟังก์ชันนั้นจะ:
- ตั้งค่า debounce เป็น true
- ดึงรายการของกัมดรอปที่เหลืออยู่และข้อความสตริงที่อธิบายถึงกัมดรอปที่ลูกค้าต้องหาต่อไป
- แปลงสตริงเป็นเสียงโดยใช้วัตถุ AudioTextToSpeech เล่นเสียงและรอให้เสียงจบ
- ตั้งค่า debounce กลับเป็น false
การตั้งค่า debounce จาก false เป็น true เพื่อกลับเป็น false อีกครั้งหลังจากที่เสียง TTS ที่ตอบสนองต่อบริบทเล่นจบ เป็นรูปแบบ debounce ที่ป้องกันไม่ให้เสียงถูกกระตุ้นซ้ำแล้วซ้ำเล่าขณะที่ผู้เล่นชนกับปริมาณนี้ต่อเนื่อง สำหรับข้อมูลเพิ่มเติมเกี่ยวกับรูปแบบ debounce นี้ ให้ดูที่ Debounce - ตรวจจับการชน.
- ทดสอบประสบการณ์เพื่อได้ยินคำใบ้ตามบริบทเมื่อผู้เล่นสัมผัสปริมาณเสียงรอบๆ เอลฟ์ เสียง TTS จะเปลี่ยนไปตามจำนวนและสีของกัมดรอปที่ตัวละครผู้เล่นได้พบในสภาพแวดล้อมแล้ว