语音转文本(STT)是一种技术,可以自动将语音声音生成文本。通过 STT,您可以创建更具沉浸感的世界,让玩家与 NPC 交谈,动态生成文本而无需预先录制特定音频,提高对运动或视觉受限玩家的可访问性,并通过语音快捷方式为玩家提供免提控制,例如打开他们的库存或施放法术。
使用 姜饼屋 - 开始 .rbxl 文件作为起点,本教程将向您展示如何将动态生成的文本添加到您的游戏中,包括如何实现 STT 以便玩家可以与您 3D 世界中的物体进行交互的指导。
音频对象
要创建 STT 音频,了解您将在本教程中使用的音频对象非常重要。STT 有三种类型的音频对象:
- AudioDeviceInput 对象是现实世界中的物理硬件设备,例如笔记本电脑、手机或耳机中的麦克风。
- AudioSpeechToText 对象将语音声音转换为文本字符串。
- Wires 将音频流从一个对象传输到另一个对象。
所有这些音频对象共同工作,以响应玩家的操作生成 STT 文本。例如,如果玩家在使用笔记本电脑玩游戏时佩戴耳机:
- AudioDeviceInput 捕获玩家的语音,作为他们麦克风中说出的声音和音频流。
- Wire 将音频流从 AudioDeviceInput 传输到 AudioSpeechToText。
- AudioSpeechToText 将玩家的语音转换为文本。
- 游戏读取此文本并执行一个动作,例如在屏幕上显示所说的文本或在玩家的命令下打开一扇门。
启用麦克风使用
在将 STT 添加到游戏之前,您必须首先启用麦克风使用并发布游戏。
- 在 Studio 中打开 姜饼屋 - 开始 文件。
- 创建一个本地副本。
- 发布您本地的游戏副本。
- 返回 Studio,转到 文件 ⟩ 体验设置 ⟩ 通信。
- 打开 启用麦克风。
- 保存您的更改。
添加简单的语音捕获
要将简单的语音捕获添加到您本地的 姜饼屋 - 开始 文件中:
启用最新的语音 API。
- 在 资源管理器 窗口中,选择 VoiceChatService。
- 在 属性 窗口中,将 UseAudioApi 设置为 Enabled。
创建基本的音频对象,以便捕获所说的单词。
- 在 资源管理器 窗口中,转到 Workspace > DialogueVolume。
- 删除 DialogueVolume 文件夹中的所有对象。
- 将以下对象插入到 DialogueVolume 文件夹中:
- 一个 AudioDeviceInput 用于捕获语音。
- 一个 AudioSpeechToText 用于将语音转换为文本。
- 一个 Wire 用于将音频设备输入的流传输到 STT 实例。
- 在 AudioSpeechToText 对象的 属性 窗口中,将 Enabled 状态设置为开启。
- 在 Wire 对象的 属性 窗口中:
- 将 SourceInstance 设置为您的新 AudioDeviceInput,以指定您希望电线从此特定音频实例传输音频。
- 将 TargetInstance 设置为您的新 AudioSpeechToText,以指定您希望电线将音频传输到此特定音频实例。
在运行时将音频设备输入的 Player 属性设置为本地玩家。这告诉 Roblox 从哪个用户的麦克风捕获音频。
- 在 资源管理器 窗口中,转到 StarterPlayer > StarterCharacterScripts。
- 插入一个 LocalScript 并将其命名为 ListenForMagicWord。
- 将以下代码粘贴到新的本地脚本中:
local audioDeviceInput = workspace:WaitForChild('DialogueVolume'):WaitForChild('AudioDeviceInput')-- 将麦克风绑定到本地玩家audioDeviceInput.Player = game.Players.LocalPlayer
测试您的语音捕获
在您添加简单的语音捕获后,您可以进行游戏测试,以确保您的 STT 实现正常工作。对着麦克风说话应该会将 AudioSpeechToText 属性填充为您语音的文本版本。
要测试您的语音捕获:
- 在 测试 > 客户端和服务器 下,选择 团队测试。
- 点击 开始 启动测试服务器。
- 在新的测试服务器中,取消静音您的麦克风并说几句话。
- 在 资源管理器 窗口中,转到 Workspace > DialogueVolume > AudioSpeechToText。
- 在 AudioSpeechToText 的 属性 窗口中,确认您对麦克风说的单词已作为 Text 属性的值出现。
将 STT 与游戏玩法结合使用
要将 STT 连接到游戏玩法,并在玩家对着麦克风说“打开芝麻”时打开姜饼屋的门:
创建一个远程事件以连接客户端和服务器。
- 将其命名为 OpenDoor。
添加一个新脚本以动画化打开姜饼屋的门。
- 在 ServerScriptService 下插入一个服务器端的 Script。
- 将其命名为 DoorService。
- 将以下代码粘贴到新脚本中:
-- 获取 ReplicatedStorage 服务以便在服务器和客户端之间共享存储-- 获取 TweenService 以便使用补间动画系统local ReplicatedStorage = game:GetService("ReplicatedStorage")local TweenService = game:GetService("TweenService")-- 允许客户端请求服务器打开门local remoteEvent = ReplicatedStorage:WaitForChild("OpenDoor")-- 动画化门向下移动并打开的函数local function openDoor()local doorPart = workspace:WaitForChild("Door")local tweenInfo = TweenInfo.new(2, Enum.EasingStyle.Linear)local tween = TweenService:Create(doorPart, tweenInfo, {Position = doorPart.Position + Vector3.new(0, -15, 0)})tween:Play()end-- 将函数连接到事件remoteEvent.OnServerEvent:Connect(openDoor)将门与语音转文本连接,以便在玩家对着麦克风说话时发生动作。
- 转到 StarterPlayer > StarterCharacterScripts。
- 打开您之前创建的 ListenForMagicWord 脚本。
- 添加以下行:
-- 获取 ReplicatedStorage 服务以便在服务器和客户端之间共享存储local ReplicatedStorage = game:GetService("ReplicatedStorage")-- 获取客户端将触发到服务器的 RemoveEventlocal remoteEvent = ReplicatedStorage:WaitForChild("OpenDoor")-- 在场景图中查找 STT 节点-- 节点的 Text 属性在识别语音时更新local speechToText = workspace:WaitForChild('DialogueVolume'):WaitForChild('AudioSpeechToText')-- 如果 STT 捕获到玩家说“打开芝麻”,则告诉服务器打开门的函数speechToText:GetPropertyChangedSignal('Text'):Connect(function()local text = speechToText.Textif text == '' thenreturnendprint(text)if (text.find(text, 'open sesame') ~= nil) thenremoteEvent:FireServer()endspeechToText.Text = ''end)测试您的 STT 实现。
- 在 测试 > 客户端和服务器 下,选择 团队测试。
- 点击 开始 启动测试服务器。
- 在新的测试服务器中,走到门前,取消静音您的麦克风,并说“打开芝麻”。门应该打开并允许您进入姜饼屋。