Văn bản thành giọng nói là một hình thức công nghệ hỗ trợ chuyển đổi chuỗi văn bản thành âm thanh giọng nói bằng cách sử dụng giọng nói nhân tạo. Ngoài việc cải thiện khả năng tiếp cận trò chơi của bạn cho người chơi có khuyết tật về thị giác, vận động hoặc nhận thức, TTS cho phép bạn tạo ra âm thanh giọng nói một cách động để bạn không phải ghi âm trước âm thanh cho tất cả các kịch bản kể chuyện có thể xảy ra.
Sử dụng tệp Gingerbread House - Start .rbxl làm điểm khởi đầu và Gingerbread House - Text-to-Speech làm tài liệu tham khảo, hướng dẫn này sẽ chỉ cho bạn cách thêm cả âm thanh TTS cơ bản và TTS theo ngữ cảnh vào trò chơi của bạn, bao gồm hướng dẫn về:
- Kích hoạt TTS cho các kịch bản gameplay phổ biến mà sẽ không bao giờ thay đổi, chẳng hạn như tương tác UI và hướng dẫn.
- Cấu hình TTS để nó thích ứng với hành động của người chơi, trạng thái môi trường hoặc mục tiêu linh hoạt.
Nếu bạn gặp khó khăn trong quá trình này, bạn có thể sử dụng Gingerbread House - Text-to-Speech làm tài liệu tham khảo để so sánh tiến trình của bạn.
Đối tượng Âm thanh
Để tạo âm thanh TTS, điều quan trọng là hiểu các đối tượng âm thanh mà bạn sẽ làm việc trong suốt hướng dẫn này. Có năm loại đối tượng âm thanh chính cho TTS:
- Đối tượng AudioTextToSpeech chuyển đổi chuỗi văn bản thành âm thanh giọng nói.
- Đối tượng AudioEmitter là một loa ảo phát âm thanh vào môi trường 3D.
- Đối tượng AudioListener là một micro ảo thu âm thanh từ môi trường 3D.
- Đối tượng AudioDeviceOutput là một thiết bị phần cứng vật lý trong thế giới thực, chẳng hạn như loa hoặc tai nghe.
- Wires mang các luồng âm thanh từ một đối tượng này sang đối tượng khác.
Tất cả các đối tượng âm thanh này làm việc cùng nhau để phát âm thanh TTS phản ứng với hành động của người chơi. Hãy cùng xem cách điều này hoạt động trong thực tế cho âm thanh 3D bằng một ví dụ về một người chơi đeo tai nghe trong khi chơi trò chơi với máy tính xách tay của họ:
- Đối tượng AudioTextToSpeech tải và chuyển đổi văn bản thành âm thanh bất cứ khi nào một người chơi chạm vào một phần gần một nhân vật không thể chơi (NPC).
- Đối tượng AudioEmitter phát một luồng âm thanh TTS từ NPC vào môi trường 3D.
- Một đối tượng Wire mang luồng từ AudioTextToSpeech đến AudioEmitter để luồng âm thanh phát ra từ NPC.
- Đối tượng con AudioListener của nhân vật lắng nghe âm thanh đó trong môi trường 3D và truyền lại cho tai nghe của họ.
- Đối tượng AudioDeviceOutput mang âm thanh từ AudioListener đến loa vật lý của người chơi, hoặc trong trường hợp này, tai nghe của họ.
Các phần tiếp theo sẽ đi sâu hơn và tham chiếu đến các đối tượng này khi bạn học cách phát âm thanh cơ bản và theo ngữ cảnh. Khi bạn xem xét các đối tượng này với các kỹ thuật sắp tới, bạn có thể dự đoán chính xác hơn cách để thu thập và truyền âm thanh từ trò chơi đến người chơi.
TTS Cơ bản
TTS cơ bản là hình thức phổ biến nhất của văn bản thành giọng nói trong đó giọng nói nhân tạo đọc một chuỗi văn bản mà không quan tâm đến ngữ cảnh của người chơi hoặc môi trường. Điều này có nghĩa là bất cứ khi nào người chơi kích hoạt âm thanh TTS, các từ và cách mà giọng nói nhân tạo đọc các từ vẫn nhất quán bất kể trạng thái của người chơi, hành động của họ, hoặc trạng thái môi trường.
Hình thức TTS này hữu ích trong hầu hết các kịch bản gameplay, chẳng hạn như người chơi tương tác với menu UI, hướng dẫn, hoặc các tương tác NPC thường xuyên như các đề nghị của người bán hoặc tiếng kêu của kẻ thù. Roblox cung cấp các loại giọng nói sau mà bạn có thể thử nghiệm cho bất kỳ tương tác nào trong số này:
| VoiceID | Mô tả Giọng nói | Ví dụ Âm thanh |
|---|---|---|
| 1 | Nam Anh | |
| 2 | Nữ Anh | |
| 3 | Nam Mỹ #1 | |
| 4 | Nữ Mỹ #1 | |
| 5 | Nam Mỹ #2 | |
| 6 | Nữ Mỹ #2 | |
| 7 | Nam Úc | |
| 8 | Nữ Úc | |
| 9 | Giọng retro #1 | |
| 10 | Giọng retro #2 | |
| 11 | Giọng người dẫn chương trình | |
| 101 | Nam Tây Ban Nha | |
| 102 | Nữ Tây Ban Nha | |
| 201 | Nam Đức | |
| 202 | Nữ Đức | |
| 301 | Nam Ý | |
| 302 | Nữ Ý | |
| 401 | Nam Pháp | |
| 402 | Nữ Pháp |
Để tái tạo âm thanh TTS 3D cơ bản trong tệp mẫu Gingerbread House - Text-to-Speech:
- Kích hoạt một listener mặc định được gắn vào nhân vật người chơi của bạn.
- Trong cửa sổ Explorer, chọn SoundService.
- Trong cửa sổ Properties, đặt DefaultListenerLocation thành Character. Khi bạn chạy trò chơi, động cơ tự động:
- Tạo một AudioListener dưới Humanoid.RootPart của mỗi nhân vật người chơi để bạn có thể nghe âm thanh thay đổi trong loa thực tế của bạn theo vị trí và quy mô của các nguồn âm thanh trong trò chơi.
- Tạo một AudioDeviceOutput dưới SoundService.
- Trong cửa sổ Explorer, điều hướng đến Workspace ⟩ DialogueVolume, sau đó:
- Chèn một đối tượng AudioTextToSpeech để tạo một máy phát âm thanh cho âm thanh xung quanh người tuyết.
- Chèn một đối tượng AudioEmitter để phát một luồng âm thanh từ DialogueVolume.
- Chèn một đối tượng Wire để mang luồng từ máy phát âm thanh đến máy phát âm thanh.
- Chọn đối tượng AudioTextToSpeech, sau đó trong cửa sổ Properties:
- Đặt Text thành "Thu thập từng viên kẹo cuối cùng để mở cửa nhà tôi!"
- Đặt VoiceId thành 2 để đặt giọng nói nhân tạo mô phỏng một nữ người Anh.
- Đặt Volume thành 3 để phát âm thanh ở âm lượng cao để bạn nghe thấy âm thanh TTS trên các nguồn âm thanh khác trong trò chơi.
- Chọn Wire, sau đó trong cửa sổ Properties:
- Đặt SourceInstance thành AudioTextToSpeech mới của bạn để chỉ định rằng bạn muốn dây mang âm thanh từ máy phát âm thanh cụ thể này.
- Đặt TargetInstance thành AudioEmitter mới của bạn để chỉ định rằng bạn muốn dây mang âm thanh đến máy phát âm thanh cụ thể này trong âm lượng.
- Quay lại cửa sổ Explorer, điều hướng đến StarterPlayer ⟩ StarterCharacterScripts, sau đó chèn một LocalScript, đổi tên thành PlayBasicTTSAudioWhenInVolume, và dán mã sau vào script cục bộ:
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)Script này bắt đầu bằng cách lấy các dịch vụ Workspace và Players để nó có thể tham chiếu đến các đối tượng con và chức năng của chúng. Đối với mỗi nhân vật người chơi được tải hoặc hồi sinh trở lại trò chơi, script sẽ chờ:
- Đối tượng âm lượng trong workspace có tên DialogueVolume.
Khi bất kỳ thứ gì va chạm với âm lượng, hàm xử lý sự kiện Touched sẽ lấy tổ tiên đầu tiên là một Model, mà nên là nhân vật nếu BasePart va chạm với âm lượng là một phần tử con của mô hình nhân vật. Nếu đúng, hàm sẽ:
- Đặt debounce thành true.
- Phát và chờ âm thanh TTS kết thúc.
- Đặt debounce trở lại false.
Việc đặt debounce từ false thành true rồi lại thành false sau khi âm thanh TTS cơ bản kết thúc phát là một mẫu debounce ngăn âm thanh kích hoạt lặp đi lặp lại khi người chơi liên tục va chạm với âm lượng. Để biết thêm thông tin về mẫu debounce này, xem Debounce - Phát hiện va chạm.
Chơi thử trò chơi để nghe cuộc đối thoại hướng dẫn của nhân vật khi nhân vật người chơi của bạn chạm vào âm lượng xung quanh người tuyết.
Bạn có thể thử nghiệm thêm với âm thanh này bằng cách thay đổi các thuộc tính Text, VoiceID, Pitch, và Speed thành các giá trị mới. Giọng nói được tạo ra trở nên hoàn toàn khác mà không cần ghi âm và tải lên một tệp âm thanh mới cho mỗi kịch bản.
TTS Theo ngữ cảnh
TTS theo ngữ cảnh là một hình thức nâng cao hơn của văn bản thành giọng nói trong đó giọng nói nhân tạo đọc một chuỗi văn bản liên quan đến người chơi, trạng thái môi trường của họ, hoặc trạng thái gameplay. Điều này có nghĩa là bất cứ khi nào người chơi kích hoạt âm thanh TTS, các từ và cách mà giọng nói nhân tạo đọc các từ sẽ thích ứng tương ứng.
Hình thức TTS này hữu ích cho các kịch bản gameplay đang thay đổi liên tục, chẳng hạn như các tín hiệu âm thanh định hướng, trạng thái mục tiêu, hoặc các tương tác NPC độc đáo. Do đó, vì TTS theo ngữ cảnh cần phải biến đổi để chính xác, bạn phải cấu hình các yếu tố gameplay để bạn có thể theo dõi trạng thái của chúng khi người chơi điều hướng qua môi trường và hoàn thành các mục tiêu gameplay.
Trong khi có nhiều cách để thực hiện nhiệm vụ này, mẫu sử dụng các thuộc tính tùy chỉnh để theo dõi màu sắc và vị trí của mỗi viên kẹo mà người chơi phải thu thập để vào ngôi nhà gừng. Để biết thêm thông tin về thuộc tính, xem Thuộc tính và thuộc tính.



Để tái tạo âm thanh TTS 3D theo ngữ cảnh trong tệp mẫu Gingerbread House - Text-to-Speech:
Trong cửa sổ Explorer, điều hướng đến Workspace ⟩ GumDrops.
Cấu hình ba thuộc tính tùy chỉnh để theo dõi viên kẹo màu vàng.
- Chọn viên kẹo màu vàng, sau đó trong cửa sổ Properties, điều hướng đến phần Attributes, sau đó nhấp vào biểu tượng cộng. Một hộp thoại pop-up sẽ hiển thị.
- Trong trường Name, nhập ColorDescription.
- Trong menu thả xuống Type, chọn string.
- Nhấp vào nút Save.
- Đặt thuộc tính ColorDescription mới thành yellow.
- Sử dụng quy trình này, tạo hai thuộc tính nữa với các giá trị sau.
Tên Loại Giá trị HintOrder số 0 LocationDescription string gần thác nước Cấu hình ba thuộc tính tùy chỉnh để theo dõi viên kẹo màu xanh.
- Trong cửa sổ Explorer, chọn viên kẹo màu xanh.
- Trong cửa sổ Properties, tạo ba thuộc tính với các giá trị sau.
Tên Loại Giá trị ColorDescription string green HintOrder số 1 LocationDescription string trên bờ Cấu hình ba thuộc tính tùy chỉnh để theo dõi viên kẹo màu đỏ.
- Trong cửa sổ Explorer, chọn viên kẹo màu đỏ.
- Trong cửa sổ Properties, tạo ba thuộc tính với các giá trị sau.
Tên Loại Giá trị ColorDescription string red HintOrder số 2 LocationDescription string đằng sau hàng rào Trong cửa sổ Explorer, điều hướng đến Workspace ⟩ HintVolume, sau đó:
- Chèn một đối tượng AudioTextToSpeech để tạo một máy phát âm thanh cho âm thanh xung quanh con tuần lộc.
- Chèn một đối tượng AudioEmitter để phát một luồng âm thanh từ HintVolume.
- Chèn một đối tượng Wire để mang luồng từ máy phát âm thanh đến máy phát âm thanh.
Chọn Wire, sau đó trong cửa sổ Properties:
- Đặt SourceInstance thành AudioTextToSpeech mới của bạn để chỉ định rằng bạn muốn dây mang âm thanh từ máy phát âm thanh cụ thể này.
- Đặt TargetInstance thành AudioEmitter mới của bạn để chỉ định rằng bạn muốn dây mang âm thanh đến máy phát âm thanh cụ thể này trong âm lượng.
Quay lại cửa sổ Explorer, điều hướng đến StarterPlayer ⟩ StarterCharacterScripts, sau đó chèn một LocalScript, đổi tên thành PlayContextTTSAudioWhenInVolume, và dán mã sau vào script cục bộ:
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 "Không còn viên kẹo nào. Kiểm tra bên trong nhà."
end
local nextGumdrop = remainingGumdrops[1]
local colorDescription = nextGumdrop:GetAttribute("ColorDescription")
local locationDescription = nextGumdrop:GetAttribute("LocationDescription")
local message = #remainingGumdrops > 1
and "Còn " .. #remainingGumdrops .. " viên kẹo. Tìm viên " .. colorDescription .. " ở " .. locationDescription .. "."
or "Còn một viên kẹo. Nó màu " .. colorDescription .. " và nó ở " .. 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("Người chơi đã chạm vào âm lượng.")
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)Script này bắt đầu bằng cách lấy các dịch vụ Workspace và Players để nó có thể tham chiếu đến các đối tượng con và chức năng của chúng. Đối với mỗi nhân vật người chơi được tải hoặc hồi sinh trở lại trò chơi, script sẽ chờ:
- Đối tượng âm lượng trong workspace có tên HintVolume.
Hàm getRemainingGumdrops() của script trả về một danh sách các đối tượng viên kẹo Part trong thư mục Gumdrops và lọc ra bất kỳ phần nào mà người chơi đã thu thập. Các viên kẹo còn lại được sắp xếp theo một thứ tự cụ thể dựa trên thuộc tính HintOrder của mỗi viên kẹo.
Hàm getReindeerHint(remainingGumdrops) của script lấy danh sách từ getRemainingGumdrops() và trả về một thông điệp chuỗi mô tả nơi người chơi có thể tìm thấy bất kỳ viên kẹo nào còn lại, bao gồm cả mô tả màu sắc và vị trí của viên kẹo tiếp theo mà người chơi cần thu thập. Tuy nhiên, nếu người chơi đã thu thập tất cả các viên kẹo trong môi trường, thông điệp chuỗi mô tả nơi để đi tiếp sau khi họ đã thu thập tất cả các viên kẹo trong môi trường.
Khi bất kỳ thứ gì va chạm với âm lượng, hàm xử lý sự kiện Touched sẽ lấy tổ tiên đầu tiên là một Model, mà nên là nhân vật nếu BasePart va chạm với âm lượng là một phần tử con của mô hình nhân vật. Nếu đúng, hàm sẽ:
- Đặt debounce thành true.
- Lấy danh sách các viên kẹo còn lại và thông điệp chuỗi mô tả viên kẹo tiếp theo mà người chơi cần tìm.
- Chuyển đổi chuỗi thành âm thanh bằng đối tượng AudioTextToSpeech, phát âm thanh và chờ âm thanh kết thúc.
- Đặt debounce trở lại false.
Việc đặt debounce từ false thành true rồi lại thành false sau khi âm thanh TTS theo ngữ cảnh kết thúc phát là một mẫu debounce ngăn âm thanh kích hoạt lặp đi lặp lại khi người chơi liên tục va chạm với âm lượng. Để biết thêm thông tin về mẫu debounce này, xem Debounce - Phát hiện va chạm.
Chơi thử trò chơi để nghe các gợi ý theo ngữ cảnh khi nhân vật người chơi của bạn chạm vào âm lượng xung quanh con tuần lộc. Âm thanh TTS thay đổi theo số lượng và màu sắc của các viên kẹo mà nhân vật người chơi đã tìm thấy trong môi trường.