roblox-audio について
roblox-audio は、Roblox 開発者向けのオーディオ実装リファレンススキルです。モジュラーなオーディオグラフと従来の Sound システムの使い分けに加え、スクリプトやパフォーマンスの指針を解説します。
主な機能
- 01オーディオグラフのオブジェクトと接続
- 022D・3D オーディオの設定
- 03エフェクトと音響シミュレーション
- 04AudioPlayer の再生制御
- 05クライアント・サーバーでの音声運用
- 06パフォーマンスとアセット権限
活用シーン
- 01新しいエクスペリエンス向けのオーディオグラフ構築
- 02距離減衰を使った 3D オーディオの実装
- 03テキスト読み上げや音声認識機能の作成
- 04音声の事前読み込みとエフェクト負荷の調整
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ nonlooped/ roblox-suite --skill roblox-audioインストール後、Claude Code で/roblox-audioを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/audio-effects.mdaudio-graph-vs-sound.mdscripts/AudioBus.lua詳細
roblox-audio
公式ソース:
- https://create.roblox.com/docs/en-us/audio/objects(オーディオグラフの概要)
- https://create.roblox.com/docs/en-us/audio/effects(オーディオエフェクト)
- https://create.roblox.com/docs/en-us/reference/engine/classes/Sound(レガシーな
Sound) - https://create.roblox.com/docs/en-us/reference/engine/classes/SoundService
- エンジンクラス:
AudioPlayer、AudioEmitter、AudioListener、AudioDeviceOutput、AudioDeviceInput、AudioTextToSpeech、AudioSpeechToText、Wire、AudioEqualizer、AudioCompressor、AudioReverb、AudioChorus、AudioDistortion、AudioEcho、AudioFlanger、AudioPitchShifter、AudioTremolo、AudioFader、AudioAnalyzer - 完全なリファレンス:https://create.roblox.com/docs/en-us/reference/engine
Roblox では、Sound、SoundGroup、SoundEffect よりもオーディオオブジェクトを推奨しています。新しい開発ではグラフを使用してください。グラフを使う利点がない場合は、レガシーコードで Sound を引き続き使用できます。
関連項目:
- サービスとスクリプトの配置場所については、roblox-core/SKILL.md を参照してください。
- アニメーションマーカー(足音、衝撃音など)からオーディオを制御する方法については、roblox-animation/SKILL.md を参照してください。
- UI によってトリガーされる効果音については、roblox-user-interfaces/SKILL.md を参照してください。
- クライアントが権限を持つ演出用オーディオと、サーバーが権限を持つゲームプレイ用オーディオについては、roblox-networking/SKILL.md を参照してください。
2 つのシステム
最新のオーディオグラフ(新規開発に推奨)
現実世界のオーディオ機器を模したモジュール式のインスタンスです。各オブジェクトはオーディオストリームを生成、受信、変更、または伝送します。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 システム(現在も動作しますが、非推奨)
BasePart または Attachment を親とする Sound は、組み込みのドップラー効果と距離による減衰(RollOffMode、RollOffMaxDistance、RollOffMinDistance、EmitterSize)を伴って、その位置から音を出します。パーツまたはアタッチメントを親としない「グローバル」な Sound は、どこでも一定の音量で再生されます。SoundGroup はグループの音量とエフェクトを制御します。SoundEffect のサブクラス(EqualizerSoundEffect、ReverbSoundEffect など)は、グループ単位でエフェクトを適用します。SoundService は、Sound の再生に影響するグローバルプロパティ(AmbientReverb、DistanceFactor、DopplerScale、RespectFilteringEnabled)を公開します。
SoundService.AmbientReverb とドップラー/距離に関するプロパティが影響するのは、レガシーな Sound のみであり、オーディオグラフには影響しません。グラフには独自のエフェクトオブジェクトと、エミッターごとの DistanceAttenuation カーブがあります。
選択ガイド:どのシステムを使うべきですか?
- 新しい体験を一から作る場合、または音声機能を一から構築する場合 → オーディオグラフを使用します。TTS、STT、音響シミュレーション、ルーティングに対応しています。
- ルーティングやエフェクトを必要としないシンプルな 2D 効果音や音楽 →
Soundで問題ありません。よりシンプルに使えます。移行のためだけに、正常に動作しているレガシーコードを書き直す必要はありません。 - カスタム減衰曲線を使った 3D の位置オーディオ → オーディオグラフを使用します(
AudioEmitter.DistanceAttenuation)。 - 複数の音源を 1 つのエフェクトに通す場合(例:すべての銃声を 1 つのコンプレッサーに通す) → オーディオグラフを使用します(1 つのエフェクトに複数のプレーヤーを接続します)。
- テキスト読み上げまたは音声認識 → オーディオグラフを使用します(
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 オーディオ(位置オーディオ)
音量はリスナーからエミッターまでの距離に応じて変化します。6 つのオブジェクトが必要です: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 の場合を除き、返される値が実際に聞こえる音の減衰を反映していると想定しないでください。SetDistanceAttenuation(curve) が再生に反映されるのは、Mode == Custom の場合のみです。角度減衰は SetAngleAttenuation({[angle]=volume})(0~180° → 0~1)で設定します。アバターの声を前方に投射する場合など、指向性音源に使用してください。
音響シミュレーション(遮蔽/回折/残響): SoundService.AcousticSimulationEnabled と、エミッターおよびリスナー双方の AcousticSimulationEnabled を有効にします。現在のリファレンスでは、インスタンスごとの個別の OcclusionEnabled、DiffractionEnabled、ReverbEnabled 切り替え項目は公開されていません。これらを呼び出すコードを生成しないでください。距離と角度の減衰を組み合わせた値(0~1)を取得するには、emitter:GetAudibilityFor(listener) または listener:GetAudibilityFor(emitter) を使用します。
リスナーの位置
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の状態(再生中/一時停止中/停止中)はサーバーからクライアントへレプリケートされますが、クライアントごとの音量やエフェクトはローカルです。単発の SFX では、クライアント主導の再生を推奨します。サーバーが RemoteEvent を通じて「このイベントが発生した」と通知し、影響を受ける各クライアントがローカルでサウンドを再生します。これにより、再生ごとのタイミングをレプリケートする必要がなくなり、各クライアントの品質設定も尊重されます(VFX と同じパターンです。roblox-vfx スキルを参照してください)。 - 全クライアントで同期させる音楽/環境音は、サーバー主導にできます(
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 スキルを参照してください)。
テキスト読み上げ(TTS)
AudioTextToSpeech は、テキスト(1 リクエストあたり 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(およびリスナーから出力へのワイヤー)です。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 で使用するすべての音声は、コミュニティ基準および利用規約に準拠する必要があります。
ベストプラクティス
- 先読み:重要なオーディオ(音楽、よく使う SFX)はロード中に先読みします。1 回限りの UI 効果音は遅延ロードできます。
- ループ:環境音や音楽は、
Looping = true(グラフ)またはLooped = true(レガシー)でループします。有限回数 N 回ループするには、DidLoopイベント(レガシーのSound)を使うか、グラフで再生回数をカウントします。 - フェードイン/フェードアウト:
AudioPlayer.Volume(グラフ)またはSound.Volume(レガシー)をトゥイーンして行います。複数のストリームの音量を一度に制御するグラフネイティブな方法はAudioFaderです。 - **音楽と SFX:**音楽と SFX は別々の
AudioFaderまたはSoundGroupにルーティングすると、音楽を個別にミュートしたり、ダッキングを適用したりできます(AudioCompressorのサイドチェーンにより、SFX の再生中に音楽の音量を下げます)。 - **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を使ってグループ音量を制御し、SFX の再生中に音楽の音量を下げる、小規模な音楽/SFX バスのヘルパーです。ミックスに合わせて調整してください。
進め方
- システムを選びます。新規または複雑な作業にはグラフ、シンプルな作業やレガシーな作業には
Soundを使用します。 - バス(音楽、効果音、ナレーション)を構成し、
AudioFaderまたはSoundGroupを経由するようにルーティングします。 - 音を鳴らすパーツに 3D エミッターを配置し、各エミッターに
DistanceAttenuationを設定します。 - 価値がある箇所にエフェクトを追加します(洞窟でのリバーブ、水中でのこもり、ダッキングなど)。
- 事前に読み込み、イベント(アニメーションマーカー、UI、ゲームプレイ)からトリガーします。
- 最低性能の対象デバイスで、同時発音数とエフェクトのコストをプロファイルします。
- サードパーティ製オーディオを使用する場合は、アセットの利用許可を確認します。
リファレンス一覧
- audio-effects.md:エフェクトのルーティング、オーディオバスのミキシング、音楽のダッキング、減衰の調整について説明します。
- audio-graph-vs-sound.md:オーディオシステムの選択や、レガシーな
Soundコードの移行について説明します。
音響 API のリファレンス:https://create.roblox.com/docs/reference/engine/classes/AudioEmitter および https://create.roblox.com/docs/reference/engine/classes/AudioListener.