マガジン

Unity WebGLで音が鳴らない問題:ブラウザの自動再生制限と対策

遊びをつくる

執筆にClaudeを使用しています。

三つの透明な箱に並ぶ入力キー、球の動く仕組み、小さなゲームの舞台を赤い糸でつないだ模型。
記事のテーマをもとに制作したAI生成の写真風イメージ。

Unity製のゲームをWebGLでビルドしてブラウザで動かしたとき、BGMや効果音がまったく再生されないという経験をした方は多いはずです。ローカルのUnityエディタでは正常に鳴っていたのに、ブラウザ上だと無音になる。この現象はUnityやゲーム側のバグではなく、ブラウザの自動再生制限(Autoplay Policy) が原因です。 自動再生制限とは、ユーザーがページを操作する前にスクリプトが音声を再生しようとしても、ブラウザがそれを強制的に止める仕組みです。Chrome・Firefox・Safariのいずれも採用しており、無効化はできません。Unity WebGLのAudioSourceは内部でWeb Audio APIを使っているため、この制限をそのまま受けます。 つまり対策の本質は「Unity側の設定を変える」ことではなく、「ユーザーが何かを操作した後にAudio Contextを起動する」という設計に切り替えることです。この記事では、その仕組みの理解から具体的な実装手順まで、詰まりやすい点を交えて説明します。

この記事の目次
  1. なぜブラウザは音を止めるのか
  2. Unityバージョンによる挙動の違い
  3. JavaScriptから直接Audio Contextを再開する方法
  4. AudioSourceの設定で見落としやすい点
  5. iOSとSafariへの特別な対応
  6. 次の行動
  7. 参考資料

なぜブラウザは音を止めるのか

ブラウザが自動再生を制限するようになったのは、広告などが勝手に音を鳴らすことへのユーザー苦情が広まったためです。現在の主要ブラウザはいずれも、Audio ContextをSuspended(停止)状態で起動し、ユーザーの操作(クリック・タップ・キー入力など)が確認されてから初めてRunning(動作)状態に遷移させます。

Unity WebGLはページ読み込み後に自動でAudio Contextを生成・起動しようとします。しかしこの時点ではまだユーザーの操作がないため、ContextはSuspendedのまま残ります。結果として、その後AudioSourceでPlay()を呼んでも音が出ません。ブラウザのコンソールに The AudioContext was not allowed to start というメッセージが表示されていれば、この状態です。

一方で、「ゲーム画面をクリックしたら音が鳴り始めた」という経験をした方もいるかもしれません。それはクリックという操作をトリガーに、Audio ContextがRunning状態に遷移したケースです。Unityのバージョンによってはこの遷移を自動処理するコードが含まれていますが、確実に機能しない環境もあるため、自分で制御できるようにしておく方が安全です。

Unityバージョンによる挙動の違い

Unity 2021以降、WebGLテンプレートにはAudio Contextの再開を試みるコードが追加されています。ただし完全に解決しているわけではなく、Safari(特にiOS Safari)では依然として手動対応が必要なケースがあります。Unityのバージョンと使用するブラウザの組み合わせによって挙動が変わるため、まず自分の環境を確認することが先決です。

確認の手順は次のとおりです。

  1. WebGLビルドをローカルサーバーまたはホスティング環境で開く(file:// では動作しません)
  2. ブラウザの開発者ツール(F12)でConsoleタブを開く
  3. ページ読み込み直後に AudioContext に関する警告・エラーが出るかチェックする
  4. ゲーム画面をクリックした後に音が鳴るかどうかを確認する

クリック後に鳴るなら、Unity側のテンプレートコードがある程度機能しています。クリック後も鳴らない場合は、Audio Context自体がRunningに遷移していないか、AudioSourceの設定に別の問題がある可能性があります。

JavaScriptから直接Audio Contextを再開する方法

最も確実な対策は、HTMLテンプレートのJavaScript側でAudio Contextを明示的に再開することです。Unityが生成するWebGLビルドには index.html が含まれており、Build/ フォルダと同階層にあります。このファイルを編集するか、UnityのWebGLテンプレート機能を使ってカスタムHTMLを用意します。

ページ全体へのクリックイベントにAudio Context再開処理を仕込む基本的なパターンは次のようなものです。

javascript
document.addEventListener('click', function() {
  if (typeof AudioContext !== 'undefined') {
    var ctx = new AudioContext();
    if (ctx.state === 'suspended') {
      ctx.resume();
    }
  }
}, { once: true });

ただしこれはUnityが内部で使っているAudio Contextとは別のインスタンスです。UnityのAudio Contextを直接操作するには、Unity 2021以降であれば unityInstance オブジェクトを通じてアクセスする方法が公式ドキュメントで説明されています。実装の詳細はUnityのバージョンごとに変わるため、使用バージョンの公式ドキュメントで AudioContext または Autoplay をキーワードに確認してください。

もう一つの安全な方法は、ゲーム起動前にスタート画面を挟む設計です。「タップしてはじめる」などのボタンを表示し、そのクリックをトリガーとしてUnityのインスタンスをロードまたは音を鳴らす流れにすることで、ユーザー操作の条件を確実に満たせます。

AudioSourceの設定で見落としやすい点

Audio Contextの問題が解決した後でも音が出ない場合は、Unity側の設定を見直します。

Play On Awakeの扱い:AudioSourceコンポーネントの Play On Awake をオンにしていても、Audio ContextがSuspendedの間に再生命令が来ると音が出ません。Contextが再開されてから再び Play() を呼ぶ処理が必要です。C#側でAudio Contextの状態を待つ仕組みを作るか、スタート画面でContextを解決してからシーン遷移する設計にすると安全です。

Audio Mixer経由の音量:Audio Mixerを使っている場合、初期状態で音量が -80dB(実質無音)になっていることがあります。ブラウザ上での音が出ない問題に取り組むとき、一時的にMixerをバイパスして直接AudioSourceから再生できるか確認すると、切り分けが早くなります。

圧縮形式:WebGLビルドではOgg Vorbisが推奨されています。MP3やWAVもサポートされていますが、ブラウザやUnityのバージョンによってデコードに差が出ることがあります。音が途切れる・鳴らないという問題が圧縮形式に起因するケースも稀にあるため、Ogg形式で試してみる価値があります。

Load Type:Streaming に設定したクリップがモバイルSafariで鳴らないケースが報告されています。短いSEは Decompress On Load、BGMは Compressed In Memory を基本として試し、問題が出たら切り替える判断基準にしてください。

iOSとSafariへの特別な対応

デスクトップChromeで動いても、iPhoneのSafariでは鳴らないというケースは頻繁に起きます。iOSは自動再生制限がとくに厳しく、タッチイベントの直接的なハンドラ内でないとAudio Contextを再開できません。setTimeout でわずかに遅延させた処理や、非同期処理の中では再開が拒否されることがあります。

また、iOSではページ全体ではなくUnityのキャンバス要素(#unity-canvas)に対してタッチイベントを設定する方が確実に動作する場合があります。ターゲットとなる要素とイベントの種類(touchstart か click か)を変えて試すと、問題の切り分けができます。

iOSのWebGLサポートはUnityのバージョンと組み合わせによって対応状況が変わります。リリース時点での動作確認は、実機(iPhone実機またはXcodeのSimulator)で行うのが確実です。BrowserStackなどのクロスブラウザテストサービスも活用できます。

次の行動

まずブラウザのコンソールで AudioContext was not allowed to start のメッセージを確認し、自分のビルドが自動再生制限に引っかかっているかどうかを判断してください。引っかかっている場合は、スタート画面にボタンを一つ追加してユーザー操作を必ず挟む設計に変えるのが、もっとも確実で追加コードが少ない対策です。完成したゲームはアソバースにZIPまたはHTMLとしてそのまま投稿・公開できます。

参考資料

  • Unity 公式ドキュメント「WebGL: Audio」
  • Web Audio API 仕様(W3C)
  • MDN Web Docs「AudioContext」および「Autoplay guide for media and Web Audio APIs」