mcpField
R
roblox-audio

roblox-audio

github.com/nonlooped开发24310 次安装1 周前更新
代码仓库

关于 roblox-audio

roblox-audio 技能为 Roblox 开发者提供音频系统的参考和实现指南,重点介绍模块化音频图、旧版 Sound 系统及两者的选择、脚本和性能实践。

主要功能

  1. 01音频图对象与连接方式
  2. 022D 和 3D 音频配置
  3. 03音效与声学模拟
  4. 04AudioPlayer 播放控制
  5. 05客户端与服务器音频实践
  6. 06性能和资源权限说明

适用场景

  1. 01为新体验搭建音频图
  2. 02实现带距离衰减的 3D 音频
  3. 03制作文本转语音或语音转文本
  4. 04优化音频预加载与效果开销

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/nonlooped/roblox-suite --skill roblox-audio

安装后在 Claude Code 中输入/roblox-audio确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
audio-effects.md
audio-graph-vs-sound.md
scripts/
AudioBus.lua

详细介绍

roblox-audio

官方来源:

Roblox 建议优先使用音频对象,而不是 Sound、SoundGroup 和 SoundEffect。新开发内容应使用音频图;如果音频图没有优势,旧代码可以继续使用 Sound。

交叉参考:

两种系统

现代音频图(新开发内容推荐使用)

采用模块化实例,模拟现实世界的音频设备。每个对象都会生成、接收、修改或传输音频流。使用 Wire 实例将它们连接起来(SourceInstance → TargetInstance)。

对象作用现实世界中的对应物
AudioPlayer从音频资源 ID 生成音频流音频文件播放器
AudioEmitter向 3D 环境中发射音频流(父级位置 = 发射点)世界中的扬声器
AudioListener接收环境中的音频流(父级 = 摄像机或角色)世界中的麦克风
AudioDeviceOutput将音频流播放到玩家的实体扬声器/耳机玩家硬件输出设备
AudioDeviceInput从玩家的实体麦克风采集音频玩家硬件麦克风
AudioTextToSpeech使用人造语音将文本转换为音频TTS 引擎
AudioSpeechToText将语音音频转换为文本转录引擎
Wire将音频流从 SourceInstance 传输到 TargetInstance音频线缆

效果(全部属于“修改”类别):AudioEqualizer、AudioCompressor、AudioReverb、AudioChorus、AudioDistortion、AudioEcho、AudioFlanger、AudioPitchShifter、AudioTremolo、AudioFader、AudioAnalyzer。请参阅 references/audio-effects.md。

旧版 Sound 系统(仍可使用,但不推荐)

将 Sound 设为 BasePart 或 Attachment 的子级,即可从该位置发出声音,并使用内置的多普勒效应和距离衰减(RollOffMode、RollOffMaxDistance、RollOffMinDistance、EmitterSize)。“全局”Sound(未设为零件或附件的子级)会以恒定音量在各处播放。SoundGroup 控制组音量和效果;SoundEffect 子类(如 EqualizerSoundEffect、ReverbSoundEffect 等)会应用组级效果。SoundService 提供全局属性(AmbientReverb、DistanceFactor、DopplerScale、RespectFilteringEnabled),这些属性会影响 Sound 播放。

SoundService.AmbientReverb 和多普勒/距离属性仅影响旧版 Sound,不会影响音频图。音频图有自己的效果对象和每个发射器的 DistanceAttenuation 曲线。

决策树:该使用哪种系统?

  • 全新体验、从零开始构建音频 → 音频图。它支持 TTS、STT、声学模拟和路由。
  • 无需路由或效果的简单 2D 音效或音乐 → Sound 足够好,也更简单。不要只为了迁移而重写能正常工作的旧代码。
  • 使用自定义衰减曲线的 3D 定位音频 → 音频图(AudioEmitter.DistanceAttenuation)。
  • 多个音源经过同一个效果(例如,所有枪声都经过同一个压缩器) → 音频图(一个效果,接入多个播放器)。
  • 文本转语音或语音转文本 → 音频图(只有音频图支持 AudioTextToSpeech / AudioSpeechToText)。
  • 语音聊天 / 空间语音 → VoiceChatService(与体验内音频分开;启用 UseAudioApi 后,底层会使用 AudioDeviceInput)。
  • 声学模拟(遮挡、衍射、混响) → 音频图,启用 SoundService.AcousticSimulationEnabled = true,并在发射器 / 监听器上启用各自的 AcousticSimulationEnabled。
  • 快速原型 / 一次性 UI 点击音效 → 使用 Sound 即可。

请参阅 references/audio-graph-vs-sound.md,了解并排的属性对照表和迁移说明。

2D 音频(非定向)

各处音量相同。需要:AudioPlayer → Wire → AudioDeviceOutput,并且都以 SoundService 为父级。

--!strict
local SoundService = game:GetService("SoundService")

local player = Instance.new("AudioPlayer")
player.AssetId = "rbxassetid://YOUR_AUDIO_ID"
player.Looping = true
player.Volume = 1
player.Parent = SoundService

local output = Instance.new("AudioDeviceOutput")
output.Parent = SoundService

local wire = Instance.new("Wire")
wire.SourceInstance = player
wire.TargetInstance = output
wire.Parent = SoundService

player:Play()

3D 音频(定位音频)

音量会随监听器与发射器之间的距离而变化。需要六个对象:AudioPlayer → Wire → AudioEmitter(以 3D 部件为父级),以及 AudioListener → Wire → AudioDeviceOutput(位于 SoundService 下)。将 SoundService.ListenerLocation 设为 Character 或 Camera(设置后,运行时引擎会在 SoundService 下自动创建 AudioDeviceOutput)。

--!strict
local SoundService = game:GetService("SoundService")
SoundService.ListenerLocation = Enum.ListenerLocation.Camera -- or Character

-- On the 3D part that should emit audio:
local part = workspace:WaitForChild("NoisyPart")
local player = Instance.new("AudioPlayer")
player.AssetId = "rbxassetid://YOUR_AUDIO_ID"
player.Looping = true
player.Parent = part

local emitter = Instance.new("AudioEmitter")
-- Custom curve: DistanceAttenuation is a NumberSequence (x = distance studs, y = volume 0..1).
-- This curve is only used when DistanceAttenuationMode == Custom (the default).
emitter.DistanceAttenuation = NumberSequence.new({
    NumberSequenceKeypoint.new(0, 1),    -- full volume at 0 studs
    NumberSequenceKeypoint.new(50, 0.5), -- half volume at 50 studs
    NumberSequenceKeypoint.new(70, 0),   -- silent at 70 studs
})
-- Preset alternative (no custom curve needed):
-- emitter.DistanceAttenuationMode = Enum.DistanceAttenuationMode.Inverse
-- emitter.DistanceAttenuationBounds = NumberRange.new(4, 10000) -- [min,max] for the preset rolloff
emitter.Parent = part

local wire = Instance.new("Wire")
wire.SourceInstance = player
wire.TargetInstance = emitter
wire.Parent = part

player:Play()

发射器的父级位置决定音频从何处发出。AudioEmitter 会忽略自身朝向;旋转父级部件 / 附件来调整发射方向。

距离模型:AudioEmitter.DistanceAttenuationMode 用于选择衰减公式(默认为 Custom;使用你的 DistanceAttenuation 曲线;其他预设使用默认值为 [4, 10000] 的 DistanceAttenuationBounds,并忽略自定义曲线)。即使当前启用的是预设,GetDistanceAttenuation() 也始终返回自定义曲线。不要假设它反映了实际可听到的衰减,除非 Mode == Custom。只有在 Mode == Custom 时,SetDistanceAttenuation(curve) 才会影响播放。使用 SetAngleAttenuation({[angle]=volume}) 设置角度衰减(0–180° → 0–1);可用于定向音源(例如,化身语音向前方传播)。

**声学模拟(遮挡 / 衍射 / 混响):**启用 SoundService.AcousticSimulationEnabled,并在发射器和监听器上都启用 AcousticSimulationEnabled。当前参考文档不再提供各实例单独的 OcclusionEnabled、DiffractionEnabled 和 ReverbEnabled 开关;请勿生成对这些开关的调用。使用 emitter:GetAudibilityFor(listener) 或 listener:GetAudibilityFor(emitter) 获取结合了距离和角度衰减的值(0–1)。

监听器位置

SoundService.ListenerLocation(一个 ListenerLocation 枚举)用于控制自动创建 AudioListener 的位置:

  • Default:在带语音聊天的体验中,位于摄像机处。
  • None:不自动创建监听器;通过脚本创建。
  • Character:以本地玩家的角色(Humanoid.RootPart)为父级。
  • Camera:以 workspace.CurrentCamera 为父级。

设为 Character 或 Camera 时,运行时引擎会在 SoundService 下自动创建 AudioDeviceOutput。AudioListener 会根据距离和发射器的 DistanceAttenuation 曲线接收来自 AudioEmitter 的音频。

从脚本触发音频

local audio = script.Parent :: AudioPlayer
someEvent:Connect(function()
    audio:Play()
end)

AudioPlayer:Play(atTime?)、:Stop(atTime?)。提供 atTime 时,操作会根据 SoundService:GetMixerTime() 进行调度,实现采样精确、与帧率无关的计时(节奏游戏/节拍同步)。:Cancel(actionId) 可取消计划在未来执行的 Play/Stop(取消成功时返回 true)。:Pause()、:SeekTime(...)、:GetWaveform(timeRange)(采样音量但不播放;适用于波形可视化,与实时 AudioAnalyzer 相比)。AudioPlayer.TimeVolume 可进行补间。有关音量和效果参数的补间,请参阅 references/audio-effects.md。

预加载音频

在需要使用主要音频资源之前(例如加载画面、回合开始时)预先加载,以避免低端设备首次播放时出现卡顿:

--!strict
local ContentProvider = game:GetService("ContentProvider")
local audioPlayer = workspace:WaitForChild("MusicPlayer") :: AudioPlayer
ContentProvider:PreloadAsync({ audioPlayer })

对于旧版 Sound 系统,以相同方式预加载 Sound 实例。

性能限制

  • 并发声部(同时播放的音频流)数量有限制;上限因设备而异。移动设备的上限远低于桌面设备。
  • 效果会占用 CPU,每条经过效果处理的活动音频流都会产生开销。混响和声学模拟的开销最大。
  • 声学模拟(SoundService.AcousticSimulationEnabled)会增加每个发声器的遮挡/绕射/混响开销;在低端客户端上或不需要时请将其禁用。
  • 移动设备节流: 引擎可能会在内存较少的客户端上丢弃或降低音频效果的质量(例如,旧款手机上会丢弃翻页动画;部分音频效果也会受到相同影响)。请在低画质设置下进行测试。
  • AudioAnalyzer 仅用于检查;不要在不必要时将其串接到可听音频路径中。

使用 MicroProfiler 分析音频(音频会显示在工作线程下),并查看 Developer Console 的 Memory 选项卡。

脚本上下文(客户端与服务端)

  • 播放 AudioPlayer、Sound 和效果是在客户端执行的。每个客户端都会播放自己的音频。服务端不会为客户端混音。
  • 复制: 如果 AudioPlayer 实例位于可复制的位置,其状态(播放/暂停/停止)会从服务端复制到客户端,但每个客户端的音量和效果都是本地的。对于一次性音效,建议采用客户端权威的触发方式:服务端通过 RemoteEvent 发送“事件已发生”的信号,由每个受影响的客户端在本地播放声音。这样可以避免复制每次触发的时间信息,并遵循各客户端的画质设置(与 VFX 的做法相同;请参阅 roblox-vfx skill)。
  • 需要在所有客户端间同步的音乐/环境音可以由服务端驱动(AudioPlayer 位于 ReplicatedStorage 或 SoundService 中,由服务端调用 :Play()),但请注意,每个客户端仍会在本地渲染,且可能出现不同步。
  • AudioDeviceInput(麦克风)仅限客户端使用。它会采集本地玩家的麦克风输入。可搭配 VoiceChatService 实现空间语音。访问控制:SetUserIdAccessList(userIds) + AccessType(Allow = 仅列表中的用户能听到输入,Deny = 除列表中的用户外所有人都能听到;默认值为 Deny),GetUserIdAccessList() 会返回允许/拒绝列表。
  • 切勿信任客户端的音频状态来判断游戏逻辑。 客户端声称“我播放了装填音效”并不具有任何权威性;请在服务端验证游戏效果(请参阅 roblox-networking)。

音频资源权限

  • 2022 年音频隐私变更前上传的音频资源可能是私有的或用途受限。上传到你自己的体验中的资源可供该体验使用。
  • Creator Store 提供可免费使用的音频资源库。这些资源可在任何体验中通过资源 ID 安全引用。
  • 其他创作者上传的音频在其标记为公开使用之前,可能无法用于你的体验。如果引用第三方音频资源 ID 后无法播放,通常是权限问题。
  • 如需使用新音频,请通过 Creator Dashboard 的资源管理器或 Open Cloud Assets API 上传(以编程方式上传请参阅 roblox-open-cloud skill)。

文本转语音(TTS)

AudioTextToSpeech 可将文本(每次请求不超过 300 个字符)转换为合成人声。可用的 VoiceId 值为:1–11(英语变体)、101–102(西班牙语)、201–202(德语)、301–302(意大利语)、401–402(法语)、501–502(中文普通话)、601–602(印地语)、701–702(日语)、801–802(阿拉伯语)、901–902(韩语)和 1001–1002(葡萄牙语);在各语言对应的语音配对中,奇数 ID 为男性,偶数 ID 为女性。连接方式与 AudioPlayer 类似:对于 2D 音频,使用 AudioTextToSpeech → Wire → AudioDeviceOutput;对于 3D 音频,使用 AudioTextToSpeech → Wire → AudioEmitter(并连接 listener→output)。在 AudioTextToSpeech 上设置 Text、VoiceId 和 Volume。:WaitForSpeechReady() 会一直等待,直到 AssetFetchStatus 为 Success(或 Failure)。所有文本都必须符合 Roblox 社区标准和使用条款。

音频分析: AudioAnalyzer 窗口由 AudioWindowSize 控制。Small(延迟最低、低频率分辨率)、Medium(均衡)、Large(分辨率最高、延迟较高)。

适用场景:无障碍功能(朗读 UI 文本)、无需录制音频的 NPC 配音、动态公告。

语音转文本(STT)

AudioSpeechToText 可将 AudioDeviceInput 捕获的语音转换为文本。需要将 VoiceChatService.UseAudioApi 设为 Enabled。连接方式:AudioDeviceInput → Wire → AudioSpeechToText。运行时设置 audioDeviceInput.Player = Players.LocalPlayer,即可将目标设为本地玩家的麦克风。Roblox 会自动检测说话者所用的语言(支持 17 种:阿拉伯语、简体中文/繁体中文、英语、法语、德语、印度尼西亚语、意大利语、日语、韩语、波兰语、葡萄牙语、西班牙语、俄语、土耳其语、泰语、越南语)。

若要使用 STT 而不向其他玩家广播语音,请禁用 VoiceChatService.EnableDefaultVoice。AudioSpeechToText 的所有音频都必须符合社区标准和使用条款。

最佳实践

  • 预加载重要音频(音乐、常见音效),并在加载期间完成。一次性 UI 音效可以延迟加载。
  • 循环播放环境音/音乐时,使用 Looping = true(音频图)或 Looped = true(旧版)。若要循环播放有限的 N 次,可使用 DidLoop 事件(旧版 Sound),或在音频图中统计播放次数。
  • 淡入/淡出时,可通过补间调整 AudioPlayer.Volume(音频图)或 Sound.Volume(旧版)。AudioFader 是音频图原生的方式,可一次控制多个流的音量。
  • **音乐与音效:**将音乐和音效分别路由到不同的 AudioFader 或 SoundGroup,以便单独静音音乐并应用闪避(音效通过 AudioCompressor 侧链降低音乐音量)。
  • **3D 与 2D:**如果声音有世界位置,请使用 3D(AudioEmitter);如果用于 UI/全局播放,请使用 2D(直接连接 AudioDeviceOutput)。
  • **无障碍功能:**为重要文本提供 TTS,为 VO 提供字幕选项,并且绝不要将音频作为游戏关键资讯的唯一提示方式。
  • **移动设备:**在低画质下进行测试。引擎可能会舍弃特效;请确保不使用这些特效时,体验仍然可用。
  • **并发播放:**频繁播放一次性音效时,应复用 AudioPlayer/Sound 实例,而不是每次播放都创建并销毁实例。

常见错误

  • 在新项目中使用 Sound/SoundGroup/SoundEffect,而音频图才是推荐方案。
  • 将 AudioEmitter 设为 SoundService 的子级(3D 音频必须将其设为 3D 零件/附件的子级)。
  • 忘记添加 Wire(音频无法从播放器传到输出设备/发射器)。
  • 误以为 SoundService.AmbientReverb 会影响音频图(它只影响旧版 Sound)。
  • 将 DistanceAttenuation 设为单个数值,而不是 NumberSequence(它是曲线,不是标量)。
  • 将客户端音频状态用于游戏逻辑(如重新加载音效、命中音效),而不是通过服务器验证。
  • 未预加载,导致移动设备上首次播放时卡顿。
  • 将第三方音频的资产 ID 写死;这些音频可能受到权限限制。

脚本

  • scripts/AudioBus.lua:一个简易的音乐/音效总线辅助工具,使用 AudioFader 控制组音量,并在音效播放时降低音乐音量。可根据你的混音需求进行调整。

如何进行

  1. 选择系统:新项目或复杂工作使用 graph,简单项目或旧项目使用 Sound。
  2. 布置总线(音乐、SFX、VO),并通过 AudioFader 或 SoundGroup 进行路由。
  3. 在需要发声的部件上放置 3D 发声器;为每个发声器设置 DistanceAttenuation。
  4. 在能提升效果的地方添加音效(洞穴中的混响、水下的闷音、闪避)。
  5. 预加载,然后从事件触发(动画标记、UI、游戏玩法)。
  6. 在目标设备中性能最低的设备上,分析并发语音数和效果开销。
  7. 确认任何第三方音频资源的使用权限。

参考索引

声学 API 参考:https://create.roblox.com/docs/reference/engine/classes/AudioEmitter 和 https://create.roblox.com/docs/reference/engine/classes/AudioListener。

评论

支持 Markdown